aegis-stack 0.2.0rc2__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 (392) hide show
  1. aegis/__init__.py +5 -0
  2. aegis/__main__.py +51 -0
  3. aegis/cli/__init__.py +6 -0
  4. aegis/cli/callbacks.py +114 -0
  5. aegis/cli/interactive.py +611 -0
  6. aegis/cli/utils.py +70 -0
  7. aegis/cli/validators.py +34 -0
  8. aegis/commands/__init__.py +6 -0
  9. aegis/commands/add.py +353 -0
  10. aegis/commands/add_service.py +332 -0
  11. aegis/commands/components.py +35 -0
  12. aegis/commands/init.py +370 -0
  13. aegis/commands/remove.py +227 -0
  14. aegis/commands/services.py +52 -0
  15. aegis/commands/update.py +252 -0
  16. aegis/commands/version.py +12 -0
  17. aegis/config/__init__.py +1 -0
  18. aegis/config/shared_files.py +136 -0
  19. aegis/core/CLAUDE.md +377 -0
  20. aegis/core/__init__.py +6 -0
  21. aegis/core/component_files.py +228 -0
  22. aegis/core/component_utils.py +220 -0
  23. aegis/core/components.py +127 -0
  24. aegis/core/copier_manager.py +315 -0
  25. aegis/core/copier_updater.py +475 -0
  26. aegis/core/dependency_resolver.py +119 -0
  27. aegis/core/manual_updater.py +554 -0
  28. aegis/core/post_gen_tasks.py +547 -0
  29. aegis/core/service_resolver.py +261 -0
  30. aegis/core/services.py +157 -0
  31. aegis/core/template_generator.py +266 -0
  32. aegis/core/version_compatibility.py +259 -0
  33. aegis/templates/CLAUDE.md +591 -0
  34. aegis/templates/cookiecutter-aegis-project/cookiecutter.json +39 -0
  35. aegis/templates/cookiecutter-aegis-project/hooks/post_gen_project.py +214 -0
  36. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/.dockerignore +71 -0
  37. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/.env.example.j2 +130 -0
  38. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/.gitignore +131 -0
  39. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/Dockerfile +53 -0
  40. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/Makefile +236 -0
  41. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/README.md.j2 +196 -0
  42. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/alembic/alembic.ini.j2 +111 -0
  43. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/alembic/env.py.j2 +91 -0
  44. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/alembic/script.py.mako +25 -0
  45. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/alembic/versions/001_initial_auth.py.j2 +51 -0
  46. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/__init__.py +5 -0
  47. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/cli/__init__.py +6 -0
  48. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/cli/ai.py.j2 +700 -0
  49. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/cli/ai_rendering.py +361 -0
  50. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/cli/auth.py.j2 +253 -0
  51. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/cli/health.py.j2 +419 -0
  52. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/cli/load_test.py.j2 +656 -0
  53. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/cli/main.py.j2 +65 -0
  54. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/cli/marko_terminal_renderer.py +489 -0
  55. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/cli/tasks.py.j2 +328 -0
  56. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/cli/{% if cookiecutter.include_scheduler == /"yes/" %}tasks.py{% endif %}" +340 -0
  57. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/__init__.py +0 -0
  58. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/api/__init__.py +0 -0
  59. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/api/ai/__init__.py +8 -0
  60. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/api/ai/router.py +329 -0
  61. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/api/auth/__init__.py +1 -0
  62. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/api/auth/router.py +64 -0
  63. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/api/deps.py +58 -0
  64. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/api/health.py +163 -0
  65. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/api/models.py.j2 +280 -0
  66. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/api/routing.py.j2 +32 -0
  67. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/api/scheduler.py.j2 +121 -0
  68. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/api/worker.py.j2 +478 -0
  69. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/hooks.py +144 -0
  70. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/main.py +31 -0
  71. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/middleware/__init__.py +1 -0
  72. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/middleware/cors.py +20 -0
  73. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/shutdown/__init__.py +1 -0
  74. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/shutdown/cleanup.py +14 -0
  75. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/startup/__init__.py +1 -0
  76. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/startup/component_health.py.j2 +418 -0
  77. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/startup/database_init.py.j2 +83 -0
  78. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/__init__.py +5 -0
  79. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/controls/__init__.py +27 -0
  80. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/controls/table.py +78 -0
  81. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/controls/text.py +142 -0
  82. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/dashboard/cards/__init__.py.j2 +47 -0
  83. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/dashboard/cards/ai_card.py +287 -0
  84. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/dashboard/cards/auth_card.py +198 -0
  85. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/dashboard/cards/base_card.py +256 -0
  86. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/dashboard/cards/card_factory.py +227 -0
  87. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/dashboard/cards/card_utils.py +333 -0
  88. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/dashboard/cards/database_card.py +420 -0
  89. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/dashboard/cards/fastapi_card.py +328 -0
  90. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/dashboard/cards/flet_card.py +267 -0
  91. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/dashboard/cards/redis_card.py +322 -0
  92. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/dashboard/cards/scheduler_card.py +352 -0
  93. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/dashboard/cards/services_card.py +233 -0
  94. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/dashboard/cards/worker_card.py +684 -0
  95. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/main.py.j2 +653 -0
  96. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/theme.py +48 -0
  97. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/scheduler/__init__.py +1 -0
  98. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/scheduler/main.py.j2 +156 -0
  99. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/worker/CLAUDE.md.j2 +213 -0
  100. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/worker/__init__.py +6 -0
  101. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/worker/constants.py.j2 +30 -0
  102. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/worker/pools.py +97 -0
  103. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/worker/queues/__init__.py +1 -0
  104. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/worker/queues/load_test.py +55 -0
  105. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/worker/queues/media.py +49 -0
  106. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/worker/queues/system.py +44 -0
  107. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/worker/registry.py +139 -0
  108. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/worker/tasks/__init__.py +120 -0
  109. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/worker/tasks/load_tasks.py +507 -0
  110. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/worker/tasks/simple_system_tasks.py +33 -0
  111. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/worker/tasks/system_tasks.py +281 -0
  112. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/core/config.py.j2 +178 -0
  113. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/core/constants.py +58 -0
  114. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/core/db.py.j2 +176 -0
  115. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/core/log.py +92 -0
  116. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/core/security.py +62 -0
  117. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/entrypoints/__init__.py +1 -0
  118. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/entrypoints/webserver.py +40 -0
  119. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/entrypoints/{% if cookiecutter.include_scheduler == /"yes/" %}scheduler.py{% endif %}" +21 -0
  120. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/integrations/__init__.py +0 -0
  121. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/integrations/main.py +62 -0
  122. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/models/__init__.py +1 -0
  123. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/models/user.py +44 -0
  124. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/py.typed +0 -0
  125. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/__init__.py +1 -0
  126. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/ai/__init__.py +8 -0
  127. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/ai/config.py +130 -0
  128. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/ai/conversation.py +213 -0
  129. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/ai/health.py +96 -0
  130. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/ai/models.py +229 -0
  131. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/ai/providers.py +370 -0
  132. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/ai/service.py +388 -0
  133. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/auth/__init__.py +1 -0
  134. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/auth/auth_service.py +41 -0
  135. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/auth/health.py +164 -0
  136. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/auth/user_service.py +83 -0
  137. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/backend/middleware_inspector.py.j2 +223 -0
  138. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/backend/models.py.j2 +70 -0
  139. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/backend/route_inspector.py.j2 +155 -0
  140. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/load_test.py +679 -0
  141. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/load_test_models.py +266 -0
  142. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/scheduler/__init__.py.j2 +21 -0
  143. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/scheduler/models.py.j2 +119 -0
  144. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/scheduler/scheduled_task_manager.py.j2 +273 -0
  145. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/scheduler/task_monitor.py.j2 +189 -0
  146. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/shared/__init__.py +15 -0
  147. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/shared/models.py +26 -0
  148. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/system/__init__.py +52 -0
  149. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/system/alerts.py +94 -0
  150. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/system/backup.py.j2 +119 -0
  151. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/system/health.py.j2 +1333 -0
  152. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/system/models.py +243 -0
  153. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/system/ui.py +52 -0
  154. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/assets/aegis-manifesto-dark.png +0 -0
  155. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/assets/aegis-manifesto-square-backup.png +0 -0
  156. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/assets/aegis-manifesto.png +0 -0
  157. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/clean-validation/.dockerignore +71 -0
  158. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/clean-validation/.env.example.j2 +64 -0
  159. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/clean-validation/.gitignore +131 -0
  160. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/clean-validation/Dockerfile +53 -0
  161. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/clean-validation/Makefile +211 -0
  162. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/clean-validation/README.md.j2 +172 -0
  163. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/clean-validation/docker-compose.yml.j2 +78 -0
  164. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/clean-validation/mkdocs.yml.j2 +62 -0
  165. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/clean-validation/pyproject.toml.j2 +120 -0
  166. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/clean-validation/uv.lock +1673 -0
  167. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/docker-compose.yml.j2 +200 -0
  168. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/docs/api.md +191 -0
  169. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/docs/components/scheduler.md +0 -0
  170. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/docs/components/scheduler.md.j2 +621 -0
  171. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/docs/development.md +215 -0
  172. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/docs/health.md +240 -0
  173. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/docs/javascripts/mermaid-config.js +62 -0
  174. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/docs/stylesheets/mermaid.css +95 -0
  175. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/mkdocs.yml.j2 +62 -0
  176. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/pyproject.toml.j2 +131 -0
  177. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/scripts/entrypoint.sh +87 -0
  178. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/scripts/entrypoint.sh.j2 +93 -0
  179. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/scripts/gen_docs.py +16 -0
  180. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/api/__init__.py +1 -0
  181. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/api/test_auth_endpoints.py.j2 +307 -0
  182. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/api/test_health_endpoints.py.j2 +262 -0
  183. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/api/test_scheduler_endpoints.py.j2 +214 -0
  184. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/api/test_worker_endpoints.py.j2 +165 -0
  185. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/cli/test_ai_rendering.py +427 -0
  186. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/cli/test_conversation_memory.py +465 -0
  187. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/components/test_scheduler.py +43 -0
  188. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/conftest.py.j2 +195 -0
  189. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/services/__init__.py +1 -0
  190. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/services/ai/__init__.py +1 -0
  191. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/services/ai/conftest.py +78 -0
  192. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/services/ai/test_health.py +157 -0
  193. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/services/ai/test_models.py +164 -0
  194. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/services/ai/test_service.py +198 -0
  195. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/services/test_auth_integration.py.j2 +528 -0
  196. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/services/test_component_integration.py.j2 +387 -0
  197. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/services/test_conversation_persistence.py +342 -0
  198. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/services/test_health_logic.py.j2 +663 -0
  199. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/services/test_load_test_models.py +619 -0
  200. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/services/test_load_test_service.py +603 -0
  201. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/services/test_middleware_inspector.py.j2 +248 -0
  202. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/services/test_scheduled_task_manager.py.j2 +292 -0
  203. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/services/test_system_service.py +98 -0
  204. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/services/test_worker_health_registration.py.j2 +257 -0
  205. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/test_core.py +49 -0
  206. aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/uv.lock +1673 -0
  207. aegis/templates/copier-aegis-project/{{ project_slug }}/.copier-answers.yml.jinja +21 -0
  208. aegis/templates/copier-aegis-project/{{ project_slug }}/.dockerignore +71 -0
  209. aegis/templates/copier-aegis-project/{{ project_slug }}/.env.example.jinja +130 -0
  210. aegis/templates/copier-aegis-project/{{ project_slug }}/.gitignore +131 -0
  211. aegis/templates/copier-aegis-project/{{ project_slug }}/Dockerfile +53 -0
  212. aegis/templates/copier-aegis-project/{{ project_slug }}/Makefile.jinja +236 -0
  213. aegis/templates/copier-aegis-project/{{ project_slug }}/README.md.jinja +196 -0
  214. aegis/templates/copier-aegis-project/{{ project_slug }}/alembic/alembic.ini.jinja +111 -0
  215. aegis/templates/copier-aegis-project/{{ project_slug }}/alembic/env.py.jinja +91 -0
  216. aegis/templates/copier-aegis-project/{{ project_slug }}/alembic/script.py.mako +25 -0
  217. aegis/templates/copier-aegis-project/{{ project_slug }}/alembic/versions/001_initial_auth.py.jinja +51 -0
  218. aegis/templates/copier-aegis-project/{{ project_slug }}/app/__init__.py.jinja +5 -0
  219. aegis/templates/copier-aegis-project/{{ project_slug }}/app/cli/__init__.py.jinja +6 -0
  220. aegis/templates/copier-aegis-project/{{ project_slug }}/app/cli/ai.py.jinja +700 -0
  221. aegis/templates/copier-aegis-project/{{ project_slug }}/app/cli/ai_rendering.py +360 -0
  222. aegis/templates/copier-aegis-project/{{ project_slug }}/app/cli/auth.py.jinja +253 -0
  223. aegis/templates/copier-aegis-project/{{ project_slug }}/app/cli/health.py.jinja +419 -0
  224. aegis/templates/copier-aegis-project/{{ project_slug }}/app/cli/load_test.py.jinja +656 -0
  225. aegis/templates/copier-aegis-project/{{ project_slug }}/app/cli/main.py.jinja +65 -0
  226. aegis/templates/copier-aegis-project/{{ project_slug }}/app/cli/marko_terminal_renderer.py +489 -0
  227. aegis/templates/copier-aegis-project/{{ project_slug }}/app/cli/tasks.py.jinja +328 -0
  228. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/__init__.py +0 -0
  229. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/api/__init__.py +0 -0
  230. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/api/ai/__init__.py +8 -0
  231. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/api/ai/router.py +329 -0
  232. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/api/auth/__init__.py +1 -0
  233. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/api/auth/router.py +64 -0
  234. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/api/deps.py +58 -0
  235. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/api/health.py.jinja +163 -0
  236. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/api/models.py.jinja +280 -0
  237. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/api/routing.py.jinja +32 -0
  238. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/api/scheduler.py.jinja +121 -0
  239. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/api/worker.py.jinja +478 -0
  240. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/hooks.py +144 -0
  241. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/main.py +31 -0
  242. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/middleware/__init__.py +1 -0
  243. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/middleware/cors.py +20 -0
  244. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/shutdown/__init__.py +1 -0
  245. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/shutdown/cleanup.py +14 -0
  246. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/startup/__init__.py +1 -0
  247. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/startup/component_health.py.jinja +418 -0
  248. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/startup/database_init.py.jinja +83 -0
  249. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/__init__.py +5 -0
  250. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/controls/__init__.py +27 -0
  251. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/controls/table.py +78 -0
  252. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/controls/text.py +142 -0
  253. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/dashboard/cards/__init__.py.jinja +47 -0
  254. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/dashboard/cards/ai_card.py +287 -0
  255. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/dashboard/cards/auth_card.py +198 -0
  256. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/dashboard/cards/base_card.py +256 -0
  257. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/dashboard/cards/card_factory.py +227 -0
  258. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/dashboard/cards/card_utils.py +333 -0
  259. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/dashboard/cards/database_card.py +420 -0
  260. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/dashboard/cards/fastapi_card.py +328 -0
  261. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/dashboard/cards/flet_card.py +267 -0
  262. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/dashboard/cards/redis_card.py +322 -0
  263. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/dashboard/cards/scheduler_card.py +352 -0
  264. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/dashboard/cards/services_card.py +233 -0
  265. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/dashboard/cards/worker_card.py +684 -0
  266. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/main.py.jinja +653 -0
  267. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/theme.py +48 -0
  268. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/scheduler/__init__.py +1 -0
  269. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/scheduler/main.py.jinja +156 -0
  270. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/worker/CLAUDE.md.jinja +213 -0
  271. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/worker/__init__.py +6 -0
  272. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/worker/constants.py.jinja +30 -0
  273. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/worker/pools.py +97 -0
  274. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/worker/queues/__init__.py +1 -0
  275. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/worker/queues/load_test.py +55 -0
  276. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/worker/queues/media.py +49 -0
  277. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/worker/queues/system.py +44 -0
  278. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/worker/registry.py +139 -0
  279. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/worker/tasks/__init__.py +120 -0
  280. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/worker/tasks/load_tasks.py +507 -0
  281. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/worker/tasks/simple_system_tasks.py +33 -0
  282. aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/worker/tasks/system_tasks.py +281 -0
  283. aegis/templates/copier-aegis-project/{{ project_slug }}/app/core/config.py.jinja +178 -0
  284. aegis/templates/copier-aegis-project/{{ project_slug }}/app/core/constants.py +58 -0
  285. aegis/templates/copier-aegis-project/{{ project_slug }}/app/core/db.py.jinja +176 -0
  286. aegis/templates/copier-aegis-project/{{ project_slug }}/app/core/log.py +92 -0
  287. aegis/templates/copier-aegis-project/{{ project_slug }}/app/core/security.py +62 -0
  288. aegis/templates/copier-aegis-project/{{ project_slug }}/app/entrypoints/__init__.py +1 -0
  289. aegis/templates/copier-aegis-project/{{ project_slug }}/app/entrypoints/scheduler.py.jinja +21 -0
  290. aegis/templates/copier-aegis-project/{{ project_slug }}/app/entrypoints/webserver.py +39 -0
  291. aegis/templates/copier-aegis-project/{{ project_slug }}/app/integrations/__init__.py +0 -0
  292. aegis/templates/copier-aegis-project/{{ project_slug }}/app/integrations/main.py +61 -0
  293. aegis/templates/copier-aegis-project/{{ project_slug }}/app/models/__init__.py +1 -0
  294. aegis/templates/copier-aegis-project/{{ project_slug }}/app/models/user.py +44 -0
  295. aegis/templates/copier-aegis-project/{{ project_slug }}/app/py.typed +0 -0
  296. aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/__init__.py +1 -0
  297. aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/ai/__init__.py +8 -0
  298. aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/ai/config.py +130 -0
  299. aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/ai/conversation.py +213 -0
  300. aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/ai/health.py +96 -0
  301. aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/ai/models.py +229 -0
  302. aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/ai/providers.py.jinja +370 -0
  303. aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/ai/service.py +387 -0
  304. aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/auth/__init__.py +1 -0
  305. aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/auth/auth_service.py +40 -0
  306. aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/auth/health.py +162 -0
  307. aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/auth/user_service.py +82 -0
  308. aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/backend/middleware_inspector.py.jinja +223 -0
  309. aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/backend/models.py.jinja +70 -0
  310. aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/backend/route_inspector.py.jinja +155 -0
  311. aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/load_test.py +678 -0
  312. aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/load_test_models.py +265 -0
  313. aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/scheduler/__init__.py.jinja +21 -0
  314. aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/scheduler/models.py.jinja +119 -0
  315. aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/scheduler/scheduled_task_manager.py.jinja +273 -0
  316. aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/scheduler/task_monitor.py.jinja +189 -0
  317. aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/shared/__init__.py +15 -0
  318. aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/shared/models.py +26 -0
  319. aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/system/__init__.py +52 -0
  320. aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/system/alerts.py +94 -0
  321. aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/system/backup.py.jinja +119 -0
  322. aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/system/health.py.jinja +1333 -0
  323. aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/system/models.py +243 -0
  324. aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/system/ui.py +52 -0
  325. aegis/templates/copier-aegis-project/{{ project_slug }}/assets/.!57223!aegis-manifesto.png +0 -0
  326. aegis/templates/copier-aegis-project/{{ project_slug }}/assets/.!57224!aegis-manifesto-dark.png +0 -0
  327. aegis/templates/copier-aegis-project/{{ project_slug }}/assets/.!57225!aegis-manifesto-square-backup.png +0 -0
  328. aegis/templates/copier-aegis-project/{{ project_slug }}/assets/.!57533!aegis-manifesto.png +0 -0
  329. aegis/templates/copier-aegis-project/{{ project_slug }}/assets/.!57534!aegis-manifesto-dark.png +0 -0
  330. aegis/templates/copier-aegis-project/{{ project_slug }}/assets/.!57538!aegis-manifesto-square-backup.png +0 -0
  331. aegis/templates/copier-aegis-project/{{ project_slug }}/assets/.!57897!aegis-manifesto.png +0 -0
  332. aegis/templates/copier-aegis-project/{{ project_slug }}/assets/.!57898!aegis-manifesto-dark.png +0 -0
  333. aegis/templates/copier-aegis-project/{{ project_slug }}/assets/.!57904!aegis-manifesto-square-backup.png +0 -0
  334. aegis/templates/copier-aegis-project/{{ project_slug }}/assets/.!58315!aegis-manifesto.png +0 -0
  335. aegis/templates/copier-aegis-project/{{ project_slug }}/assets/.!58316!aegis-manifesto-dark.png +0 -0
  336. aegis/templates/copier-aegis-project/{{ project_slug }}/assets/.!58324!aegis-manifesto-square-backup.png +0 -0
  337. aegis/templates/copier-aegis-project/{{ project_slug }}/assets/.!58837!aegis-manifesto.png +0 -0
  338. aegis/templates/copier-aegis-project/{{ project_slug }}/assets/.!58838!aegis-manifesto-dark.png +0 -0
  339. aegis/templates/copier-aegis-project/{{ project_slug }}/assets/.!58849!aegis-manifesto-square-backup.png +0 -0
  340. aegis/templates/copier-aegis-project/{{ project_slug }}/assets/aegis-manifesto-dark.png +0 -0
  341. aegis/templates/copier-aegis-project/{{ project_slug }}/assets/aegis-manifesto-square-backup.png +0 -0
  342. aegis/templates/copier-aegis-project/{{ project_slug }}/assets/aegis-manifesto.png +0 -0
  343. aegis/templates/copier-aegis-project/{{ project_slug }}/clean-validation/.env.example.jinja +64 -0
  344. aegis/templates/copier-aegis-project/{{ project_slug }}/clean-validation/README.md.jinja +172 -0
  345. aegis/templates/copier-aegis-project/{{ project_slug }}/clean-validation/docker-compose.yml.jinja +78 -0
  346. aegis/templates/copier-aegis-project/{{ project_slug }}/clean-validation/mkdocs.yml.jinja +62 -0
  347. aegis/templates/copier-aegis-project/{{ project_slug }}/clean-validation/pyproject.toml.jinja +120 -0
  348. aegis/templates/copier-aegis-project/{{ project_slug }}/docker-compose.yml.jinja +200 -0
  349. aegis/templates/copier-aegis-project/{{ project_slug }}/docs/api.md.jinja +191 -0
  350. aegis/templates/copier-aegis-project/{{ project_slug }}/docs/components/scheduler.md +0 -0
  351. aegis/templates/copier-aegis-project/{{ project_slug }}/docs/components/scheduler.md.jinja +621 -0
  352. aegis/templates/copier-aegis-project/{{ project_slug }}/docs/development.md.jinja +215 -0
  353. aegis/templates/copier-aegis-project/{{ project_slug }}/docs/health.md.jinja +240 -0
  354. aegis/templates/copier-aegis-project/{{ project_slug }}/docs/javascripts/mermaid-config.js +62 -0
  355. aegis/templates/copier-aegis-project/{{ project_slug }}/docs/stylesheets/mermaid.css +95 -0
  356. aegis/templates/copier-aegis-project/{{ project_slug }}/mkdocs.yml.jinja +62 -0
  357. aegis/templates/copier-aegis-project/{{ project_slug }}/pyproject.toml.jinja +131 -0
  358. aegis/templates/copier-aegis-project/{{ project_slug }}/scripts/entrypoint.sh +87 -0
  359. aegis/templates/copier-aegis-project/{{ project_slug }}/scripts/entrypoint.sh.jinja +93 -0
  360. aegis/templates/copier-aegis-project/{{ project_slug }}/scripts/gen_docs.py +16 -0
  361. aegis/templates/copier-aegis-project/{{ project_slug }}/tests/api/__init__.py +1 -0
  362. aegis/templates/copier-aegis-project/{{ project_slug }}/tests/api/test_auth_endpoints.py.jinja +307 -0
  363. aegis/templates/copier-aegis-project/{{ project_slug }}/tests/api/test_health_endpoints.py.jinja +262 -0
  364. aegis/templates/copier-aegis-project/{{ project_slug }}/tests/api/test_scheduler_endpoints.py.jinja +214 -0
  365. aegis/templates/copier-aegis-project/{{ project_slug }}/tests/api/test_worker_endpoints.py.jinja +165 -0
  366. aegis/templates/copier-aegis-project/{{ project_slug }}/tests/cli/test_ai_rendering.py +427 -0
  367. aegis/templates/copier-aegis-project/{{ project_slug }}/tests/cli/test_conversation_memory.py +465 -0
  368. aegis/templates/copier-aegis-project/{{ project_slug }}/tests/components/test_scheduler.py +43 -0
  369. aegis/templates/copier-aegis-project/{{ project_slug }}/tests/conftest.py.jinja +195 -0
  370. aegis/templates/copier-aegis-project/{{ project_slug }}/tests/services/__init__.py +1 -0
  371. aegis/templates/copier-aegis-project/{{ project_slug }}/tests/services/ai/__init__.py +1 -0
  372. aegis/templates/copier-aegis-project/{{ project_slug }}/tests/services/ai/conftest.py +78 -0
  373. aegis/templates/copier-aegis-project/{{ project_slug }}/tests/services/ai/test_health.py +157 -0
  374. aegis/templates/copier-aegis-project/{{ project_slug }}/tests/services/ai/test_models.py +164 -0
  375. aegis/templates/copier-aegis-project/{{ project_slug }}/tests/services/ai/test_service.py +198 -0
  376. aegis/templates/copier-aegis-project/{{ project_slug }}/tests/services/test_auth_integration.py.jinja +528 -0
  377. aegis/templates/copier-aegis-project/{{ project_slug }}/tests/services/test_component_integration.py.jinja +387 -0
  378. aegis/templates/copier-aegis-project/{{ project_slug }}/tests/services/test_conversation_persistence.py +342 -0
  379. aegis/templates/copier-aegis-project/{{ project_slug }}/tests/services/test_health_logic.py.jinja +663 -0
  380. aegis/templates/copier-aegis-project/{{ project_slug }}/tests/services/test_load_test_models.py +619 -0
  381. aegis/templates/copier-aegis-project/{{ project_slug }}/tests/services/test_load_test_service.py +603 -0
  382. aegis/templates/copier-aegis-project/{{ project_slug }}/tests/services/test_middleware_inspector.py.jinja +248 -0
  383. aegis/templates/copier-aegis-project/{{ project_slug }}/tests/services/test_scheduled_task_manager.py.jinja +292 -0
  384. aegis/templates/copier-aegis-project/{{ project_slug }}/tests/services/test_system_service.py +98 -0
  385. aegis/templates/copier-aegis-project/{{ project_slug }}/tests/services/test_worker_health_registration.py.jinja +257 -0
  386. aegis/templates/copier-aegis-project/{{ project_slug }}/tests/test_core.py +49 -0
  387. aegis/templates/copier-aegis-project/{{ project_slug }}/uv.lock +1673 -0
  388. aegis_stack-0.2.0rc2.dist-info/METADATA +165 -0
  389. aegis_stack-0.2.0rc2.dist-info/RECORD +392 -0
  390. aegis_stack-0.2.0rc2.dist-info/WHEEL +4 -0
  391. aegis_stack-0.2.0rc2.dist-info/entry_points.txt +3 -0
  392. aegis_stack-0.2.0rc2.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,591 @@
1
+ # Template Development Guide
2
+
3
+ This guide covers template development patterns for Aegis Stack's Cookiecutter templates.
4
+
5
+ ## Template Architecture
6
+
7
+ ### Template Structure
8
+ ```
9
+ aegis/templates/cookiecutter-aegis-project/
10
+ ├── cookiecutter.json # Template variables
11
+ ├── hooks/
12
+ │ └── post_gen_project.py # Template processing logic
13
+ └── {{cookiecutter.project_slug}}/ # Generated project structure
14
+ ├── app/
15
+ │ ├── components/
16
+ │ │ ├── backend/ # Always included
17
+ │ │ ├── frontend/ # Always included
18
+ │ │ ├── scheduler/ # Optional component
19
+ │ │ └── worker/ # Optional component
20
+ │ ├── core/ # Framework utilities
21
+ │ ├── entrypoints/ # Execution modes
22
+ │ ├── integrations/ # App composition
23
+ │ └── services/ # Business logic (empty)
24
+ ├── tests/
25
+ ├── docker-compose.yml.j2 # Conditional services
26
+ ├── Dockerfile.j2 # Conditional entrypoints
27
+ ├── pyproject.toml.j2 # Dependencies and configuration
28
+ └── scripts/entrypoint.sh.j2 # Runtime dispatch
29
+ ```
30
+
31
+ ### Template Processing Flow
32
+ 1. **Cookiecutter generates** base project structure using `cookiecutter.json`
33
+ 2. **Post-generation hook** (`hooks/post_gen_project.py`) processes `.j2` files with Jinja2
34
+ 3. **Component selection** includes/excludes files based on user choices
35
+ 4. **Auto-formatting** runs `make fix` on generated project
36
+ 5. **Cleanup** removes unused template files and `.j2` originals
37
+
38
+ ## Cookiecutter Variables
39
+
40
+ ### Core Variables (cookiecutter.json)
41
+ ```json
42
+ {
43
+ "project_name": "My Aegis Project",
44
+ "project_slug": "{{ cookiecutter.project_name|lower|replace(' ', '-')|replace('_', '-') }}",
45
+ "project_description": "A production-ready Python application",
46
+ "author_name": "Your Name",
47
+ "author_email": "your.email@example.com",
48
+ "version": "0.1.0",
49
+ "python_version": "3.11",
50
+ "include_scheduler": "no",
51
+ "include_worker": "no",
52
+ "include_database": "no"
53
+ }
54
+ ```
55
+
56
+ ### Variable Usage in Templates
57
+ ```jinja2
58
+ # In any .j2 file
59
+ {{ cookiecutter.project_name }} # "My Aegis Project"
60
+ {{ cookiecutter.project_slug }} # "my-aegis-project"
61
+ {{ cookiecutter.project_description }} # Description text
62
+ {{ cookiecutter.author_name }} # Author info
63
+ {{ cookiecutter.include_scheduler }} # "yes" or "no"
64
+ ```
65
+
66
+ ## Jinja2 Template Patterns
67
+
68
+ ### Conditional Content
69
+ ```jinja2
70
+ {% if cookiecutter.include_scheduler == "yes" %}
71
+ # Scheduler-specific content
72
+ {% endif %}
73
+
74
+ {% if cookiecutter.include_worker == "yes" %}
75
+ # Worker-specific content
76
+ {% endif %}
77
+
78
+ {% if cookiecutter.include_database == "yes" %}
79
+ # Database-specific content
80
+ {% endif %}
81
+ ```
82
+
83
+ ### Conditional Files
84
+ File names can be conditional:
85
+ ```
86
+ {% if cookiecutter.include_scheduler == "yes" %}scheduler.py{% endif %}
87
+ ```
88
+
89
+ ### Variable Substitution in Code
90
+ ```python
91
+ # In .j2 files
92
+ CLI_NAME = "{{ cookiecutter.project_slug }}"
93
+ PROJECT_NAME = "{{ cookiecutter.project_name }}"
94
+ VERSION = "{{ cookiecutter.version }}"
95
+ ```
96
+
97
+ ### Dependencies Based on Components
98
+ ```toml
99
+ # pyproject.toml.j2
100
+ dependencies = [
101
+ "fastapi>=0.116.1",
102
+ "flet>=0.28.3",
103
+ {% if cookiecutter.include_scheduler == "yes" %}
104
+ "apscheduler>=3.10.0",
105
+ {% endif %}
106
+ {% if cookiecutter.include_worker == "yes" %}
107
+ "arq>=0.26.1",
108
+ "redis>=5.2.1",
109
+ {% endif %}
110
+ {% if cookiecutter.include_database == "yes" %}
111
+ "sqlmodel>=0.0.14",
112
+ "sqlalchemy>=2.0.0",
113
+ "aiosqlite>=0.19.0",
114
+ {% endif %}
115
+ ]
116
+ ```
117
+
118
+ ## Post-Generation Hook Patterns
119
+
120
+ ### Hook Responsibilities
121
+ The `hooks/post_gen_project.py` script:
122
+ 1. **Processes .j2 files** - Renders Jinja2 templates with cookiecutter context
123
+ 2. **Removes unused files** - Deletes component files when components not selected
124
+ 3. **Cleans up directories** - Removes empty directories after file cleanup
125
+ 4. **Auto-formats code** - Runs `make fix` to ensure generated code is clean
126
+
127
+ ### Adding New Component Logic
128
+ ```python
129
+ # In hooks/post_gen_project.py
130
+ if "{{ cookiecutter.include_new_component }}" != "yes":
131
+ # Remove component-specific files
132
+ remove_dir("app/components/new_component")
133
+ remove_file("app/entrypoints/new_component.py")
134
+ remove_file("tests/components/test_new_component.py")
135
+
136
+ # Database component logic
137
+ if "{{ cookiecutter.include_database }}" != "yes":
138
+ remove_file("app/core/db.py")
139
+ remove_sections_from_conftest("tests/conftest.py", ["database"])
140
+ ```
141
+
142
+ ### File Removal Patterns
143
+ ```python
144
+ # Remove individual files
145
+ remove_file("app/components/scheduler.py")
146
+ remove_file("tests/components/test_scheduler.py")
147
+
148
+ # Remove entire directories
149
+ remove_dir("app/components/worker")
150
+ ```
151
+
152
+ ## Template Development Workflow
153
+
154
+ ### CRITICAL: Never Edit Generated Projects
155
+ **Always follow this pattern:**
156
+
157
+ 1. **Edit template files** in `aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/`
158
+ 2. **Test template changes**: `make test-template`
159
+ 3. **If tests fail**: Fix the **template files** (step 1), never the generated projects
160
+ 4. **Repeat** until tests pass
161
+ 5. **Clean up**: `make clean-test-projects`
162
+
163
+ ### Adding New Template Files
164
+ ```bash
165
+ # 1. Create template file
166
+ vim aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/new_component.py
167
+
168
+ # 2. If using variables, make it a .j2 file
169
+ mv app/components/new_component.py app/components/new_component.py.j2
170
+
171
+ # 3. Add conditional logic to hook if needed
172
+ vim hooks/post_gen_project.py
173
+
174
+ # 4. Test the changes
175
+ make test-template
176
+ ```
177
+
178
+ ### Modifying Existing Templates
179
+ ```bash
180
+ # 1. Find the template file
181
+ find aegis/templates/ -name "*.py" -o -name "*.j2" | grep component_name
182
+
183
+ # 2. Edit the template
184
+ vim aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/path/to/file.j2
185
+
186
+ # 3. Test immediately
187
+ make test-template-quick
188
+
189
+ # 4. Full validation
190
+ make test-template
191
+ ```
192
+
193
+ ## Template Testing Integration
194
+
195
+ ### Template Validation Process
196
+ When you run `make test-template`:
197
+ 1. **Generates fresh project** using current templates
198
+ 2. **Processes .j2 files** through post-generation hook
199
+ 3. **Installs dependencies** in generated project
200
+ 4. **Runs quality checks** (lint, typecheck, tests)
201
+ 5. **Tests CLI installation** and functionality
202
+
203
+ ### Template-Specific Test Commands
204
+ ```bash
205
+ make test-template # Test basic project generation
206
+ make test-template-with-components # Test with scheduler component
207
+ make test-template-worker # Test worker component
208
+ make test-template-full # Test all components
209
+ ```
210
+
211
+ ### Auto-Fixing in Templates
212
+ The template system automatically:
213
+ - **Fixes linting issues** in generated code
214
+ - **Formats code** with ruff
215
+ - **Ensures proper imports** and structure
216
+ - **Validates type annotations**
217
+
218
+ ## Common Template Patterns
219
+
220
+ ### Configuration Management
221
+ ```python
222
+ # Use in templates for environment-dependent values
223
+ from app.core.config import settings
224
+
225
+ # Template generates proper imports
226
+ DATABASE_URL = settings.DATABASE_URL
227
+ REDIS_URL = settings.REDIS_URL
228
+ ```
229
+
230
+ ### Component Registration
231
+ ```python
232
+ # Backend component registration
233
+ # In app/components/backend/startup/component_health.py.j2
234
+ {% if cookiecutter.include_worker == "yes" %}
235
+ from app.components.worker.health import register_worker_health_checks
236
+ {% endif %}
237
+
238
+ async def register_component_health_checks() -> None:
239
+ """Register health checks for all enabled components."""
240
+ {% if cookiecutter.include_worker == "yes" %}
241
+ register_worker_health_checks()
242
+ {% endif %}
243
+ ```
244
+
245
+ ### Docker Service Configuration
246
+ ```yaml
247
+ # docker-compose.yml.j2
248
+ services:
249
+ webserver:
250
+ # Always included
251
+
252
+ {% if cookiecutter.include_worker == "yes" %}
253
+ worker-system:
254
+ build: .
255
+ command: ["worker-system"]
256
+ depends_on:
257
+ - redis
258
+ {% endif %}
259
+
260
+ {% if cookiecutter.include_scheduler == "yes" %}
261
+ scheduler:
262
+ build: .
263
+ command: ["scheduler"]
264
+ {% endif %}
265
+ ```
266
+
267
+ ## Template Debugging
268
+
269
+ ### Common Template Issues
270
+ - **Jinja2 syntax errors** - Check bracket matching, endif statements
271
+ - **Missing cookiecutter variables** - Verify variable names in cookiecutter.json
272
+ - **Conditional logic errors** - Test with different component combinations
273
+ - **File path issues** - Ensure proper directory structure
274
+
275
+ ### Debugging Template Generation
276
+ ```bash
277
+ # Generate project manually for debugging
278
+ uv run aegis init debug-project --output-dir ../debug --force --yes
279
+
280
+ # Check generated files
281
+ ls -la ../debug-project/
282
+
283
+ # Look for remaining .j2 files (should be none)
284
+ find ../debug-project/ -name "*.j2"
285
+
286
+ # Check variable substitution
287
+ grep -r "cookiecutter\." ../debug-project/ || echo "No unreplaced variables"
288
+ ```
289
+
290
+ ### Testing Individual Components
291
+ ```bash
292
+ # Test specific component combinations
293
+ make test-template-worker # Just worker component
294
+ make test-template-with-components # Just scheduler component
295
+ make test-template-full # All components
296
+
297
+ # Clean up between tests
298
+ make clean-test-projects
299
+ ```
300
+
301
+ ## Template Quality Standards
302
+
303
+ ### Code Generation Requirements
304
+ - **No .j2 files** remain in generated projects
305
+ - **All variables replaced** - no `{{ cookiecutter.* }}` in final code
306
+ - **Proper imports** - only import what's needed based on components
307
+ - **Type annotations** - all generated code must be properly typed
308
+ - **Linting passes** - generated code passes ruff checks
309
+ - **Tests included** - component tests generated with components
310
+
311
+ ### Component Isolation
312
+ - **Independent components** - each component can be enabled/disabled
313
+ - **Clean dependencies** - components only depend on what they need
314
+ - **Proper cleanup** - unused files removed when components disabled
315
+ - **No broken imports** - imports only exist when dependencies available
316
+
317
+ ### File Organization
318
+ - **Consistent structure** - follow established patterns
319
+ - **Logical grouping** - related files in same directories
320
+ - **Clear naming** - descriptive file and directory names
321
+ - **Proper permissions** - executable files marked as executable
322
+
323
+ ## Template Parity Patterns (Cookiecutter ↔ Copier Migration)
324
+
325
+ ### Overview
326
+ Aegis Stack maintains two parallel template engines during migration:
327
+ - **Cookiecutter** (legacy) - Uses `cookiecutter.json` + `.j2` files + post-generation hooks
328
+ - **Copier** (modern) - Uses `copier.yml` + `.jinja` files + built-in tasks
329
+
330
+ Both engines MUST generate byte-for-byte identical projects. The `tests/test_template_parity.py` suite verifies this across all component/service combinations.
331
+
332
+ ### Critical Pattern #1: Whitespace Control
333
+
334
+ **Problem**: Jinja2's `{%-` strips ALL preceding whitespace, including intentional blank lines.
335
+
336
+ **Rule**: Copier templates must match Cookiecutter's whitespace preservation.
337
+
338
+ ```jinja2
339
+ # ❌ WRONG - Copier template (strips blank lines)
340
+ from app.core.log import logger
341
+
342
+ {%- if include_auth %}
343
+ from app.models.user import User
344
+ {% endif %}
345
+
346
+ # ✅ CORRECT - Matches Cookiecutter
347
+ from app.core.log import logger
348
+
349
+ {% if include_auth %}
350
+ from app.models.user import User
351
+ {% endif %}
352
+ ```
353
+
354
+ **When This Matters**: When conditional blocks are skipped (e.g., `include_auth = false`), the `{%-` strips the blank line, creating a mismatch.
355
+
356
+ **Detection**: If parity tests show line number differences or unexpected blank lines, search for `{%-` in Copier templates.
357
+
358
+ ```bash
359
+ # Find all whitespace control usage
360
+ grep -n '{%-' aegis/templates/copier-aegis-project/**/*.jinja
361
+
362
+ # Compare with Cookiecutter equivalent
363
+ grep -n '{%' aegis/templates/cookiecutter-aegis-project/**/*.j2
364
+ ```
365
+
366
+ ### Critical Pattern #2: Type Mismatches (Boolean vs String)
367
+
368
+ **Problem**: Cookiecutter uses strings (`"yes"/"no"`), Copier uses native booleans (`true/false`).
369
+
370
+ **Rule**: Copier templates must use boolean logic, not string comparisons.
371
+
372
+ ```jinja2
373
+ # ❌ WRONG - Copier template comparing boolean to string
374
+ {% if include_worker == "yes" %}
375
+ from app.components.worker import WorkerConfig
376
+ {% endif %}
377
+
378
+ # ✅ CORRECT - Boolean comparison
379
+ {% if include_worker %}
380
+ from app.components.worker import WorkerConfig
381
+ {% endif %}
382
+ ```
383
+
384
+ **Common Mistakes**:
385
+ ```jinja2
386
+ # Cookiecutter (strings)
387
+ {% if cookiecutter.include_auth == "yes" %}
388
+ {% if cookiecutter.include_scheduler == "yes" and cookiecutter.include_database == "yes" %}
389
+
390
+ # Copier (booleans)
391
+ {% if include_auth %}
392
+ {% if include_scheduler and include_database %}
393
+ ```
394
+
395
+ **Detection**: If conditional content is missing from Copier output, check for string comparisons against boolean variables.
396
+
397
+ ### Critical Pattern #3: Service Dependency Auto-Resolution
398
+
399
+ **Problem**: Services declare `required_components` but templates must honor these dependencies.
400
+
401
+ **Architecture**:
402
+ ```python
403
+ # aegis/core/services.py
404
+ SERVICES = {
405
+ "auth": ServiceSpec(
406
+ name="auth",
407
+ required_components=["backend", "database"], # Auth needs database!
408
+ ),
409
+ }
410
+
411
+ # aegis/core/template_generator.py
412
+ # ✅ CORRECT - Auto-add service dependencies
413
+ for service_name in self.selected_services:
414
+ if service_name in SERVICES:
415
+ service_spec = SERVICES[service_name]
416
+ all_components.extend(service_spec.required_components)
417
+ ```
418
+
419
+ **Impact**: When `--services auth` is used, database component must be automatically enabled. Without this, alembic migrations fail with `ModuleNotFoundError: No module named 'sqlmodel'`.
420
+
421
+ **Testing**:
422
+ ```bash
423
+ # Auth service should auto-enable database
424
+ make test-parity # Includes test_parity_with_auth_service
425
+ ```
426
+
427
+ ### Critical Pattern #4: File Exclusion Consistency
428
+
429
+ **Problem**: Both templates must exclude the same files based on component selection.
430
+
431
+ **Rule**: Exclusions must match in both `copier.yml` and `hooks/post_gen_project.py`.
432
+
433
+ ```yaml
434
+ # copier.yml exclusions
435
+ _exclude:
436
+ # Scheduler memory backend exclusions
437
+ - "{% if scheduler_backend == 'memory' -%}{{ project_slug }}/app/services/scheduler{% endif %}"
438
+ - "{% if scheduler_backend == 'memory' -%}{{ project_slug }}/tests/services/test_scheduled_task_manager.py{% endif %}"
439
+ ```
440
+
441
+ ```python
442
+ # hooks/post_gen_project.py
443
+ if "{{ cookiecutter.scheduler_backend }}" == "memory":
444
+ remove_dir("app/services/scheduler")
445
+ remove_file("tests/services/test_scheduled_task_manager.py")
446
+ ```
447
+
448
+ **Detection**: If parity tests show file existence differences, check exclusion rules in both templates.
449
+
450
+ ### Parity Testing Workflow
451
+
452
+ **Running Parity Tests**:
453
+ ```bash
454
+ make test-parity # All 9 parity tests
455
+ make test-parity-quick # Base project only
456
+ make test-parity-components # All component combinations
457
+ make test-parity-services # All service combinations
458
+ ```
459
+
460
+ **Test Matrix** (9 comprehensive tests):
461
+ 1. `test_parity_base_project` - Backend + frontend only
462
+ 2. `test_parity_with_scheduler_memory` - Scheduler (memory backend)
463
+ 3. `test_parity_with_scheduler_sqlite` - Scheduler (sqlite backend)
464
+ 4. `test_parity_with_worker` - Worker component
465
+ 5. `test_parity_with_database` - Database component
466
+ 6. `test_parity_with_all_components` - Worker + scheduler + database
467
+ 7. `test_parity_with_auth_service` - Auth service (auto-enables database)
468
+ 8. `test_parity_with_ai_service` - AI service
469
+ 9. `test_parity_kitchen_sink` - Everything enabled
470
+
471
+ **What Parity Tests Verify**:
472
+ - File structure (same files exist in both outputs)
473
+ - File contents (byte-for-byte identical after normalization)
474
+ - File permissions (executables marked correctly)
475
+ - Template variable substitution (no unreplaced `{{ ... }}`)
476
+
477
+ **Normalization Process**:
478
+ Both outputs are auto-formatted with `ruff` before comparison to eliminate cosmetic differences like import ordering.
479
+
480
+ ### Debugging Parity Failures
481
+
482
+ **Step 1: Identify the failure**
483
+ ```bash
484
+ make test-parity 2>&1 | grep "FAILED"
485
+ # Example: test_parity_with_auth_service FAILED
486
+ ```
487
+
488
+ **Step 2: Focus on ONE mismatch**
489
+ Parity test output shows specific differences:
490
+ ```
491
+ 📝 Content mismatches:
492
+ alembic/env.py:
493
+ Cookiecutter: line 24: ...
494
+ Copier: line 24: from app.models.user import User # noqa: E402,F401...
495
+ ```
496
+
497
+ **Step 3: Generate both projects manually**
498
+ ```bash
499
+ # Cookiecutter
500
+ cd /tmp
501
+ aegis init ck-test --services auth --no-interactive --yes --force
502
+
503
+ # Copier
504
+ copier copy --trust --defaults \
505
+ --data project_slug="cp-test" \
506
+ --data include_auth=true \
507
+ aegis/templates/copier-aegis-project /tmp/cp-test
508
+ ```
509
+
510
+ **Step 4: Compare specific files**
511
+ ```bash
512
+ diff -u /tmp/ck-test/alembic/env.py /tmp/cp-test/cp-test/alembic/env.py
513
+
514
+ # Check line numbers
515
+ sed -n '20,30p' /tmp/ck-test/alembic/env.py
516
+ sed -n '20,30p' /tmp/cp-test/cp-test/alembic/env.py
517
+ ```
518
+
519
+ **Step 5: Identify the pattern**
520
+ - Blank line difference? → Check for `{%-` in Copier template
521
+ - Missing content? → Check for boolean vs string comparison
522
+ - Wrong imports? → Check service dependency resolution
523
+ - Missing file? → Check exclusion rules
524
+
525
+ **Step 6: Fix the template**
526
+ Always fix the **template files**, never the generated projects:
527
+ ```bash
528
+ vim aegis/templates/copier-aegis-project/{{ project_slug }}/alembic/env.py.jinja
529
+ # Change {%- if to {% if
530
+ ```
531
+
532
+ **Step 7: Re-test**
533
+ ```bash
534
+ make test-parity
535
+ # Should show one more test passing
536
+ ```
537
+
538
+ ### Common Parity Issues
539
+
540
+ **Issue**: 56 import ordering differences
541
+ **Cause**: Different ruff versions or incomplete normalization
542
+ **Fix**: Ensure `uv sync --all-extras` runs before `make fix` in Copier tasks
543
+
544
+ **Issue**: Alembic migration fails with "No module named 'sqlmodel'"
545
+ **Cause**: Auth service enabled without database component
546
+ **Fix**: TemplateGenerator must auto-add service dependencies
547
+
548
+ **Issue**: File has 6 lines in Copier, 113 lines in Cookiecutter
549
+ **Cause**: Boolean comparison bug (e.g., `include_scheduler == "yes"` when it's `true`)
550
+ **Fix**: Change to `include_scheduler` (boolean logic)
551
+
552
+ **Issue**: Blank line mismatch at line N
553
+ **Cause**: Copier uses `{%-` where Cookiecutter uses `{%`
554
+ **Fix**: Remove `-` to preserve whitespace
555
+
556
+ ### Best Practices
557
+
558
+ **When Adding New Templates**:
559
+ 1. Create in Cookiecutter first (`.j2` files)
560
+ 2. Copy to Copier and convert (`.jinja` files)
561
+ 3. Update variables: `cookiecutter.var` → `var`
562
+ 4. Update conditionals: `== "yes"` → boolean logic
563
+ 5. Check whitespace: `{%-` → `{%` (usually)
564
+ 6. Run `make test-parity` to verify
565
+
566
+ **When Modifying Existing Templates**:
567
+ 1. Edit **BOTH** Cookiecutter and Copier templates
568
+ 2. Keep the same logic, just adapt syntax
569
+ 3. Run `make test-parity` to catch drift
570
+ 4. Never assume templates are in sync
571
+
572
+ **When Services Change**:
573
+ 1. Update `aegis/core/services.py` with new dependencies
574
+ 2. Verify TemplateGenerator respects them
575
+ 3. Add parity test case if needed
576
+ 4. Document new service dependencies
577
+
578
+ ### Success Criteria
579
+
580
+ Parity is achieved when:
581
+ ```bash
582
+ make test-parity
583
+ # 9 passed in ~70 seconds
584
+ ```
585
+
586
+ All tests MUST pass before:
587
+ - Merging template changes
588
+ - Releasing new Aegis Stack versions
589
+ - Switching from Cookiecutter to Copier as primary engine
590
+
591
+ **Zero tolerance for drift** - Any parity failure indicates a real problem that will affect users.
@@ -0,0 +1,39 @@
1
+ {
2
+ "project_name": "My Aegis Stack Project",
3
+ "project_slug": "{{ cookiecutter.project_name.lower().replace(' ', '-').replace('_', '-') }}",
4
+ "project_description": "A production-ready async Python application built with Aegis Stack",
5
+ "author_name": "Your Name",
6
+ "author_email": "your.email@example.com",
7
+ "github_username": "your-username",
8
+ "version": "0.1.0",
9
+ "python_version": "3.11",
10
+
11
+ "_comment_components": "Component selection - these will be set by our CLI",
12
+ "include_scheduler": "no",
13
+ "include_redis": "no",
14
+ "include_worker": "no",
15
+ "include_database": "no",
16
+ "include_cache": "no",
17
+ "scheduler_backend": "memory",
18
+ "scheduler_with_persistence": "no",
19
+
20
+ "_comment_services": "Service selection - these will be set by our CLI",
21
+ "include_auth": "no",
22
+ "include_ai": "no",
23
+ "ai_providers": "openai",
24
+
25
+ "_comment_internal": "Internal variables for template logic",
26
+ "_has_additional_components": "{% if cookiecutter.include_scheduler == 'yes' or cookiecutter.include_redis == 'yes' or cookiecutter.include_worker == 'yes' or cookiecutter.include_database == 'yes' or cookiecutter.include_cache == 'yes' %}yes{% else %}no{% endif %}",
27
+ "_include_migrations": "{% if cookiecutter.include_auth == 'yes' %}yes{% else %}no{% endif %}",
28
+
29
+ "_comment_dependencies": "Component-specific dependencies",
30
+ "_scheduler_deps": "{% if cookiecutter.include_scheduler == 'yes' %}apscheduler>=3.10.0{% endif %}",
31
+ "_redis_deps": "{% if cookiecutter.include_redis == 'yes' %}redis>=5.0.0{% endif %}",
32
+ "_worker_deps": "{% if cookiecutter.include_worker == 'yes' %}arq>=0.25.0{% endif %}",
33
+ "_database_deps": "{% if cookiecutter.include_database == 'yes' %}sqlmodel>=0.0.14,sqlalchemy>=2.0.0,aiosqlite>=0.19.0{% endif %}",
34
+ "_cache_deps": "{% if cookiecutter.include_cache == 'yes' %}redis[hiredis]>=5.0.0{% endif %}",
35
+
36
+ "_comment_service_dependencies": "Service-specific dependencies",
37
+ "_auth_deps": "{% if cookiecutter.include_auth == 'yes' %}python-jose[cryptography]==3.3.0,passlib[bcrypt]==1.7.4,python-multipart==0.0.9{% endif %}",
38
+ "_ai_deps": "{% if cookiecutter.include_ai == 'yes' %}pydantic-ai-slim[{{ cookiecutter.ai_providers }}]==1.0.10,httpx>=0.27.0{% endif %}"
39
+ }