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.
- aegis/__init__.py +5 -0
- aegis/__main__.py +51 -0
- aegis/cli/__init__.py +6 -0
- aegis/cli/callbacks.py +114 -0
- aegis/cli/interactive.py +611 -0
- aegis/cli/utils.py +70 -0
- aegis/cli/validators.py +34 -0
- aegis/commands/__init__.py +6 -0
- aegis/commands/add.py +353 -0
- aegis/commands/add_service.py +332 -0
- aegis/commands/components.py +35 -0
- aegis/commands/init.py +370 -0
- aegis/commands/remove.py +227 -0
- aegis/commands/services.py +52 -0
- aegis/commands/update.py +252 -0
- aegis/commands/version.py +12 -0
- aegis/config/__init__.py +1 -0
- aegis/config/shared_files.py +136 -0
- aegis/core/CLAUDE.md +377 -0
- aegis/core/__init__.py +6 -0
- aegis/core/component_files.py +228 -0
- aegis/core/component_utils.py +220 -0
- aegis/core/components.py +127 -0
- aegis/core/copier_manager.py +315 -0
- aegis/core/copier_updater.py +475 -0
- aegis/core/dependency_resolver.py +119 -0
- aegis/core/manual_updater.py +554 -0
- aegis/core/post_gen_tasks.py +547 -0
- aegis/core/service_resolver.py +261 -0
- aegis/core/services.py +157 -0
- aegis/core/template_generator.py +266 -0
- aegis/core/version_compatibility.py +259 -0
- aegis/templates/CLAUDE.md +591 -0
- aegis/templates/cookiecutter-aegis-project/cookiecutter.json +39 -0
- aegis/templates/cookiecutter-aegis-project/hooks/post_gen_project.py +214 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/.dockerignore +71 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/.env.example.j2 +130 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/.gitignore +131 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/Dockerfile +53 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/Makefile +236 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/README.md.j2 +196 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/alembic/alembic.ini.j2 +111 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/alembic/env.py.j2 +91 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/alembic/script.py.mako +25 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/alembic/versions/001_initial_auth.py.j2 +51 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/__init__.py +5 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/cli/__init__.py +6 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/cli/ai.py.j2 +700 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/cli/ai_rendering.py +361 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/cli/auth.py.j2 +253 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/cli/health.py.j2 +419 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/cli/load_test.py.j2 +656 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/cli/main.py.j2 +65 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/cli/marko_terminal_renderer.py +489 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/cli/tasks.py.j2 +328 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/cli/{% if cookiecutter.include_scheduler == /"yes/" %}tasks.py{% endif %}" +340 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/__init__.py +0 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/api/__init__.py +0 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/api/ai/__init__.py +8 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/api/ai/router.py +329 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/api/auth/__init__.py +1 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/api/auth/router.py +64 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/api/deps.py +58 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/api/health.py +163 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/api/models.py.j2 +280 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/api/routing.py.j2 +32 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/api/scheduler.py.j2 +121 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/api/worker.py.j2 +478 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/hooks.py +144 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/main.py +31 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/middleware/__init__.py +1 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/middleware/cors.py +20 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/shutdown/__init__.py +1 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/shutdown/cleanup.py +14 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/startup/__init__.py +1 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/startup/component_health.py.j2 +418 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/backend/startup/database_init.py.j2 +83 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/__init__.py +5 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/controls/__init__.py +27 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/controls/table.py +78 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/controls/text.py +142 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/dashboard/cards/__init__.py.j2 +47 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/dashboard/cards/ai_card.py +287 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/dashboard/cards/auth_card.py +198 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/dashboard/cards/base_card.py +256 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/dashboard/cards/card_factory.py +227 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/dashboard/cards/card_utils.py +333 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/dashboard/cards/database_card.py +420 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/dashboard/cards/fastapi_card.py +328 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/dashboard/cards/flet_card.py +267 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/dashboard/cards/redis_card.py +322 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/dashboard/cards/scheduler_card.py +352 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/dashboard/cards/services_card.py +233 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/dashboard/cards/worker_card.py +684 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/main.py.j2 +653 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/frontend/theme.py +48 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/scheduler/__init__.py +1 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/scheduler/main.py.j2 +156 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/worker/CLAUDE.md.j2 +213 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/worker/__init__.py +6 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/worker/constants.py.j2 +30 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/worker/pools.py +97 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/worker/queues/__init__.py +1 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/worker/queues/load_test.py +55 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/worker/queues/media.py +49 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/worker/queues/system.py +44 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/worker/registry.py +139 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/worker/tasks/__init__.py +120 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/worker/tasks/load_tasks.py +507 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/worker/tasks/simple_system_tasks.py +33 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/components/worker/tasks/system_tasks.py +281 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/core/config.py.j2 +178 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/core/constants.py +58 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/core/db.py.j2 +176 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/core/log.py +92 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/core/security.py +62 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/entrypoints/__init__.py +1 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/entrypoints/webserver.py +40 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/entrypoints/{% if cookiecutter.include_scheduler == /"yes/" %}scheduler.py{% endif %}" +21 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/integrations/__init__.py +0 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/integrations/main.py +62 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/models/__init__.py +1 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/models/user.py +44 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/py.typed +0 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/__init__.py +1 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/ai/__init__.py +8 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/ai/config.py +130 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/ai/conversation.py +213 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/ai/health.py +96 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/ai/models.py +229 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/ai/providers.py +370 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/ai/service.py +388 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/auth/__init__.py +1 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/auth/auth_service.py +41 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/auth/health.py +164 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/auth/user_service.py +83 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/backend/middleware_inspector.py.j2 +223 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/backend/models.py.j2 +70 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/backend/route_inspector.py.j2 +155 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/load_test.py +679 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/load_test_models.py +266 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/scheduler/__init__.py.j2 +21 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/scheduler/models.py.j2 +119 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/scheduler/scheduled_task_manager.py.j2 +273 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/scheduler/task_monitor.py.j2 +189 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/shared/__init__.py +15 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/shared/models.py +26 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/system/__init__.py +52 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/system/alerts.py +94 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/system/backup.py.j2 +119 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/system/health.py.j2 +1333 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/system/models.py +243 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/app/services/system/ui.py +52 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/assets/aegis-manifesto-dark.png +0 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/assets/aegis-manifesto-square-backup.png +0 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/assets/aegis-manifesto.png +0 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/clean-validation/.dockerignore +71 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/clean-validation/.env.example.j2 +64 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/clean-validation/.gitignore +131 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/clean-validation/Dockerfile +53 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/clean-validation/Makefile +211 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/clean-validation/README.md.j2 +172 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/clean-validation/docker-compose.yml.j2 +78 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/clean-validation/mkdocs.yml.j2 +62 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/clean-validation/pyproject.toml.j2 +120 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/clean-validation/uv.lock +1673 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/docker-compose.yml.j2 +200 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/docs/api.md +191 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/docs/components/scheduler.md +0 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/docs/components/scheduler.md.j2 +621 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/docs/development.md +215 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/docs/health.md +240 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/docs/javascripts/mermaid-config.js +62 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/docs/stylesheets/mermaid.css +95 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/mkdocs.yml.j2 +62 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/pyproject.toml.j2 +131 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/scripts/entrypoint.sh +87 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/scripts/entrypoint.sh.j2 +93 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/scripts/gen_docs.py +16 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/api/__init__.py +1 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/api/test_auth_endpoints.py.j2 +307 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/api/test_health_endpoints.py.j2 +262 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/api/test_scheduler_endpoints.py.j2 +214 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/api/test_worker_endpoints.py.j2 +165 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/cli/test_ai_rendering.py +427 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/cli/test_conversation_memory.py +465 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/components/test_scheduler.py +43 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/conftest.py.j2 +195 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/services/__init__.py +1 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/services/ai/__init__.py +1 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/services/ai/conftest.py +78 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/services/ai/test_health.py +157 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/services/ai/test_models.py +164 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/services/ai/test_service.py +198 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/services/test_auth_integration.py.j2 +528 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/services/test_component_integration.py.j2 +387 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/services/test_conversation_persistence.py +342 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/services/test_health_logic.py.j2 +663 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/services/test_load_test_models.py +619 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/services/test_load_test_service.py +603 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/services/test_middleware_inspector.py.j2 +248 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/services/test_scheduled_task_manager.py.j2 +292 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/services/test_system_service.py +98 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/services/test_worker_health_registration.py.j2 +257 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/tests/test_core.py +49 -0
- aegis/templates/cookiecutter-aegis-project/{{cookiecutter.project_slug}}/uv.lock +1673 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/.copier-answers.yml.jinja +21 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/.dockerignore +71 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/.env.example.jinja +130 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/.gitignore +131 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/Dockerfile +53 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/Makefile.jinja +236 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/README.md.jinja +196 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/alembic/alembic.ini.jinja +111 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/alembic/env.py.jinja +91 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/alembic/script.py.mako +25 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/alembic/versions/001_initial_auth.py.jinja +51 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/__init__.py.jinja +5 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/cli/__init__.py.jinja +6 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/cli/ai.py.jinja +700 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/cli/ai_rendering.py +360 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/cli/auth.py.jinja +253 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/cli/health.py.jinja +419 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/cli/load_test.py.jinja +656 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/cli/main.py.jinja +65 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/cli/marko_terminal_renderer.py +489 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/cli/tasks.py.jinja +328 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/__init__.py +0 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/api/__init__.py +0 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/api/ai/__init__.py +8 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/api/ai/router.py +329 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/api/auth/__init__.py +1 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/api/auth/router.py +64 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/api/deps.py +58 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/api/health.py.jinja +163 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/api/models.py.jinja +280 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/api/routing.py.jinja +32 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/api/scheduler.py.jinja +121 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/api/worker.py.jinja +478 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/hooks.py +144 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/main.py +31 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/middleware/__init__.py +1 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/middleware/cors.py +20 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/shutdown/__init__.py +1 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/shutdown/cleanup.py +14 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/startup/__init__.py +1 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/startup/component_health.py.jinja +418 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/backend/startup/database_init.py.jinja +83 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/__init__.py +5 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/controls/__init__.py +27 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/controls/table.py +78 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/controls/text.py +142 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/dashboard/cards/__init__.py.jinja +47 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/dashboard/cards/ai_card.py +287 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/dashboard/cards/auth_card.py +198 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/dashboard/cards/base_card.py +256 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/dashboard/cards/card_factory.py +227 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/dashboard/cards/card_utils.py +333 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/dashboard/cards/database_card.py +420 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/dashboard/cards/fastapi_card.py +328 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/dashboard/cards/flet_card.py +267 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/dashboard/cards/redis_card.py +322 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/dashboard/cards/scheduler_card.py +352 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/dashboard/cards/services_card.py +233 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/dashboard/cards/worker_card.py +684 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/main.py.jinja +653 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/frontend/theme.py +48 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/scheduler/__init__.py +1 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/scheduler/main.py.jinja +156 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/worker/CLAUDE.md.jinja +213 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/worker/__init__.py +6 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/worker/constants.py.jinja +30 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/worker/pools.py +97 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/worker/queues/__init__.py +1 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/worker/queues/load_test.py +55 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/worker/queues/media.py +49 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/worker/queues/system.py +44 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/worker/registry.py +139 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/worker/tasks/__init__.py +120 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/worker/tasks/load_tasks.py +507 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/worker/tasks/simple_system_tasks.py +33 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/components/worker/tasks/system_tasks.py +281 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/core/config.py.jinja +178 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/core/constants.py +58 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/core/db.py.jinja +176 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/core/log.py +92 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/core/security.py +62 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/entrypoints/__init__.py +1 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/entrypoints/scheduler.py.jinja +21 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/entrypoints/webserver.py +39 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/integrations/__init__.py +0 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/integrations/main.py +61 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/models/__init__.py +1 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/models/user.py +44 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/py.typed +0 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/__init__.py +1 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/ai/__init__.py +8 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/ai/config.py +130 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/ai/conversation.py +213 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/ai/health.py +96 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/ai/models.py +229 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/ai/providers.py.jinja +370 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/ai/service.py +387 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/auth/__init__.py +1 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/auth/auth_service.py +40 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/auth/health.py +162 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/auth/user_service.py +82 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/backend/middleware_inspector.py.jinja +223 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/backend/models.py.jinja +70 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/backend/route_inspector.py.jinja +155 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/load_test.py +678 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/load_test_models.py +265 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/scheduler/__init__.py.jinja +21 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/scheduler/models.py.jinja +119 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/scheduler/scheduled_task_manager.py.jinja +273 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/scheduler/task_monitor.py.jinja +189 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/shared/__init__.py +15 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/shared/models.py +26 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/system/__init__.py +52 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/system/alerts.py +94 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/system/backup.py.jinja +119 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/system/health.py.jinja +1333 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/system/models.py +243 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/app/services/system/ui.py +52 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/assets/.!57223!aegis-manifesto.png +0 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/assets/.!57224!aegis-manifesto-dark.png +0 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/assets/.!57225!aegis-manifesto-square-backup.png +0 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/assets/.!57533!aegis-manifesto.png +0 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/assets/.!57534!aegis-manifesto-dark.png +0 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/assets/.!57538!aegis-manifesto-square-backup.png +0 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/assets/.!57897!aegis-manifesto.png +0 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/assets/.!57898!aegis-manifesto-dark.png +0 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/assets/.!57904!aegis-manifesto-square-backup.png +0 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/assets/.!58315!aegis-manifesto.png +0 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/assets/.!58316!aegis-manifesto-dark.png +0 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/assets/.!58324!aegis-manifesto-square-backup.png +0 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/assets/.!58837!aegis-manifesto.png +0 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/assets/.!58838!aegis-manifesto-dark.png +0 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/assets/.!58849!aegis-manifesto-square-backup.png +0 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/assets/aegis-manifesto-dark.png +0 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/assets/aegis-manifesto-square-backup.png +0 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/assets/aegis-manifesto.png +0 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/clean-validation/.env.example.jinja +64 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/clean-validation/README.md.jinja +172 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/clean-validation/docker-compose.yml.jinja +78 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/clean-validation/mkdocs.yml.jinja +62 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/clean-validation/pyproject.toml.jinja +120 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/docker-compose.yml.jinja +200 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/docs/api.md.jinja +191 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/docs/components/scheduler.md +0 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/docs/components/scheduler.md.jinja +621 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/docs/development.md.jinja +215 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/docs/health.md.jinja +240 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/docs/javascripts/mermaid-config.js +62 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/docs/stylesheets/mermaid.css +95 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/mkdocs.yml.jinja +62 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/pyproject.toml.jinja +131 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/scripts/entrypoint.sh +87 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/scripts/entrypoint.sh.jinja +93 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/scripts/gen_docs.py +16 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/tests/api/__init__.py +1 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/tests/api/test_auth_endpoints.py.jinja +307 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/tests/api/test_health_endpoints.py.jinja +262 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/tests/api/test_scheduler_endpoints.py.jinja +214 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/tests/api/test_worker_endpoints.py.jinja +165 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/tests/cli/test_ai_rendering.py +427 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/tests/cli/test_conversation_memory.py +465 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/tests/components/test_scheduler.py +43 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/tests/conftest.py.jinja +195 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/tests/services/__init__.py +1 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/tests/services/ai/__init__.py +1 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/tests/services/ai/conftest.py +78 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/tests/services/ai/test_health.py +157 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/tests/services/ai/test_models.py +164 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/tests/services/ai/test_service.py +198 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/tests/services/test_auth_integration.py.jinja +528 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/tests/services/test_component_integration.py.jinja +387 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/tests/services/test_conversation_persistence.py +342 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/tests/services/test_health_logic.py.jinja +663 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/tests/services/test_load_test_models.py +619 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/tests/services/test_load_test_service.py +603 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/tests/services/test_middleware_inspector.py.jinja +248 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/tests/services/test_scheduled_task_manager.py.jinja +292 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/tests/services/test_system_service.py +98 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/tests/services/test_worker_health_registration.py.jinja +257 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/tests/test_core.py +49 -0
- aegis/templates/copier-aegis-project/{{ project_slug }}/uv.lock +1673 -0
- aegis_stack-0.2.0rc2.dist-info/METADATA +165 -0
- aegis_stack-0.2.0rc2.dist-info/RECORD +392 -0
- aegis_stack-0.2.0rc2.dist-info/WHEEL +4 -0
- aegis_stack-0.2.0rc2.dist-info/entry_points.txt +3 -0
- aegis_stack-0.2.0rc2.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,547 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Shared post-generation tasks for Cookiecutter and Copier.
|
|
3
|
+
|
|
4
|
+
This module provides common post-generation functionality used by both
|
|
5
|
+
template engines to avoid code duplication and ensure consistent behavior.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
import shutil
|
|
10
|
+
import subprocess
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from typing import Any
|
|
13
|
+
|
|
14
|
+
# Task configuration constants (following tests/cli/test_utils.py pattern)
|
|
15
|
+
POST_GEN_TIMEOUT_INSTALL = 300 # 5 minutes for dependency installation
|
|
16
|
+
POST_GEN_TIMEOUT_FORMAT = 60 # 1 minute for code formatting
|
|
17
|
+
POST_GEN_TIMEOUT_MIGRATION = 30 # 30 seconds for database migration
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def get_component_file_mapping() -> dict[str, list[str]]:
|
|
21
|
+
"""
|
|
22
|
+
Get mapping of components to their files.
|
|
23
|
+
|
|
24
|
+
Returns a dictionary mapping component names to lists of files/directories
|
|
25
|
+
that belong to that component. This is used by both cleanup_components()
|
|
26
|
+
and component_files.py for consistency.
|
|
27
|
+
|
|
28
|
+
Returns:
|
|
29
|
+
Dict mapping component names to file paths (relative to project root)
|
|
30
|
+
"""
|
|
31
|
+
return {
|
|
32
|
+
"scheduler": [
|
|
33
|
+
"app/entrypoints/scheduler.py",
|
|
34
|
+
"app/components/scheduler",
|
|
35
|
+
"tests/components/test_scheduler.py",
|
|
36
|
+
"docs/components/scheduler.md",
|
|
37
|
+
"app/components/backend/api/scheduler.py",
|
|
38
|
+
"tests/api/test_scheduler_endpoints.py",
|
|
39
|
+
"app/components/frontend/dashboard/cards/scheduler_card.py",
|
|
40
|
+
"tests/services/test_scheduled_task_manager.py",
|
|
41
|
+
],
|
|
42
|
+
"scheduler_persistence": [ # Only for sqlite backend
|
|
43
|
+
"app/services/scheduler",
|
|
44
|
+
"app/cli/tasks.py",
|
|
45
|
+
"app/components/backend/api/scheduler.py",
|
|
46
|
+
"tests/api/test_scheduler_endpoints.py",
|
|
47
|
+
"tests/services/test_scheduled_task_manager.py",
|
|
48
|
+
],
|
|
49
|
+
"worker": [
|
|
50
|
+
"app/components/worker",
|
|
51
|
+
"app/cli/load_test.py",
|
|
52
|
+
"app/services/load_test.py",
|
|
53
|
+
"app/services/load_test_models.py",
|
|
54
|
+
"tests/services/test_load_test_models.py",
|
|
55
|
+
"tests/services/test_load_test_service.py",
|
|
56
|
+
"tests/services/test_worker_health_registration.py",
|
|
57
|
+
"app/components/backend/api/worker.py",
|
|
58
|
+
"tests/api/test_worker_endpoints.py",
|
|
59
|
+
"app/components/frontend/dashboard/cards/worker_card.py",
|
|
60
|
+
],
|
|
61
|
+
"database": [
|
|
62
|
+
"app/core/db.py",
|
|
63
|
+
],
|
|
64
|
+
"auth": [
|
|
65
|
+
"app/components/backend/api/auth",
|
|
66
|
+
"app/models/user.py",
|
|
67
|
+
"app/services/auth",
|
|
68
|
+
"app/core/security.py",
|
|
69
|
+
"app/cli/auth.py",
|
|
70
|
+
"tests/api/test_auth_endpoints.py",
|
|
71
|
+
"tests/services/test_auth_service.py",
|
|
72
|
+
"tests/services/test_auth_integration.py",
|
|
73
|
+
"tests/models/test_user.py",
|
|
74
|
+
"alembic",
|
|
75
|
+
],
|
|
76
|
+
"ai": [
|
|
77
|
+
"app/components/backend/api/ai",
|
|
78
|
+
"app/services/ai",
|
|
79
|
+
"app/cli/ai.py",
|
|
80
|
+
"app/cli/ai_rendering.py",
|
|
81
|
+
"app/cli/marko_terminal_renderer.py",
|
|
82
|
+
"tests/api/test_ai_endpoints.py",
|
|
83
|
+
"tests/services/test_conversation_persistence.py",
|
|
84
|
+
"tests/cli/test_ai_rendering.py",
|
|
85
|
+
"tests/cli/test_conversation_memory.py",
|
|
86
|
+
"tests/services/ai",
|
|
87
|
+
],
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def remove_file(project_path: Path, filepath: str) -> None:
|
|
92
|
+
"""
|
|
93
|
+
Remove a file from the generated project.
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
project_path: Path to the project directory
|
|
97
|
+
filepath: Relative path to the file to remove
|
|
98
|
+
"""
|
|
99
|
+
full_path = project_path / filepath
|
|
100
|
+
if full_path.exists():
|
|
101
|
+
full_path.unlink()
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def remove_dir(project_path: Path, dirpath: str) -> None:
|
|
105
|
+
"""
|
|
106
|
+
Remove a directory from the generated project.
|
|
107
|
+
|
|
108
|
+
Args:
|
|
109
|
+
project_path: Path to the project directory
|
|
110
|
+
dirpath: Relative path to the directory to remove
|
|
111
|
+
"""
|
|
112
|
+
full_path = project_path / dirpath
|
|
113
|
+
if full_path.exists():
|
|
114
|
+
shutil.rmtree(full_path)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def cleanup_components(project_path: Path, context: dict[str, Any]) -> None:
|
|
118
|
+
"""
|
|
119
|
+
Remove component files based on component selection.
|
|
120
|
+
|
|
121
|
+
This function handles component cleanup for both Cookiecutter and Copier
|
|
122
|
+
template engines, ensuring identical behavior.
|
|
123
|
+
|
|
124
|
+
Args:
|
|
125
|
+
project_path: Path to the generated project
|
|
126
|
+
context: Dictionary with component/service flags
|
|
127
|
+
|
|
128
|
+
Note:
|
|
129
|
+
Handles both Cookiecutter (string "yes"/"no") and Copier (boolean true/false)
|
|
130
|
+
context values for maximum compatibility.
|
|
131
|
+
"""
|
|
132
|
+
|
|
133
|
+
# Helper to handle both bool and string values from different template engines
|
|
134
|
+
def is_enabled(key: str) -> bool:
|
|
135
|
+
value = context.get(key)
|
|
136
|
+
return value is True or value == "yes"
|
|
137
|
+
|
|
138
|
+
# Remove scheduler component if not selected
|
|
139
|
+
if not is_enabled("include_scheduler"):
|
|
140
|
+
remove_file(project_path, "app/entrypoints/scheduler.py")
|
|
141
|
+
remove_dir(project_path, "app/components/scheduler")
|
|
142
|
+
remove_file(project_path, "tests/components/test_scheduler.py")
|
|
143
|
+
remove_file(project_path, "docs/components/scheduler.md")
|
|
144
|
+
remove_file(project_path, "app/components/backend/api/scheduler.py")
|
|
145
|
+
remove_file(project_path, "tests/api/test_scheduler_endpoints.py")
|
|
146
|
+
remove_file(
|
|
147
|
+
project_path, "app/components/frontend/dashboard/cards/scheduler_card.py"
|
|
148
|
+
)
|
|
149
|
+
remove_file(project_path, "tests/services/test_scheduled_task_manager.py")
|
|
150
|
+
|
|
151
|
+
# Remove scheduler service if using memory backend
|
|
152
|
+
# The service is only useful when we can persist to a database
|
|
153
|
+
scheduler_backend = context.get("scheduler_backend", "memory")
|
|
154
|
+
if scheduler_backend == "memory":
|
|
155
|
+
remove_dir(project_path, "app/services/scheduler")
|
|
156
|
+
remove_file(project_path, "app/cli/tasks.py")
|
|
157
|
+
remove_file(project_path, "app/components/backend/api/scheduler.py")
|
|
158
|
+
remove_file(project_path, "tests/api/test_scheduler_endpoints.py")
|
|
159
|
+
remove_file(project_path, "tests/services/test_scheduled_task_manager.py")
|
|
160
|
+
|
|
161
|
+
# Remove worker component if not selected
|
|
162
|
+
if not is_enabled("include_worker"):
|
|
163
|
+
remove_dir(project_path, "app/components/worker")
|
|
164
|
+
remove_file(project_path, "app/cli/load_test.py")
|
|
165
|
+
remove_file(project_path, "app/services/load_test.py")
|
|
166
|
+
remove_file(project_path, "app/services/load_test_models.py")
|
|
167
|
+
remove_file(project_path, "tests/services/test_load_test_models.py")
|
|
168
|
+
remove_file(project_path, "tests/services/test_load_test_service.py")
|
|
169
|
+
remove_file(project_path, "tests/services/test_worker_health_registration.py")
|
|
170
|
+
remove_file(project_path, "app/components/backend/api/worker.py")
|
|
171
|
+
remove_file(project_path, "tests/api/test_worker_endpoints.py")
|
|
172
|
+
remove_file(
|
|
173
|
+
project_path, "app/components/frontend/dashboard/cards/worker_card.py"
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
# Remove shared component integration tests only when BOTH scheduler AND worker disabled
|
|
177
|
+
if not is_enabled("include_scheduler") and not is_enabled("include_worker"):
|
|
178
|
+
remove_file(project_path, "tests/services/test_component_integration.py")
|
|
179
|
+
remove_file(project_path, "tests/services/test_health_logic.py")
|
|
180
|
+
|
|
181
|
+
# Remove database component if not selected
|
|
182
|
+
if not is_enabled("include_database"):
|
|
183
|
+
remove_file(project_path, "app/core/db.py")
|
|
184
|
+
|
|
185
|
+
# Remove cache component if not selected
|
|
186
|
+
if not is_enabled("include_cache"):
|
|
187
|
+
pass # Placeholder - cache component doesn't exist yet
|
|
188
|
+
|
|
189
|
+
# Remove auth service if not selected
|
|
190
|
+
if not is_enabled("include_auth"):
|
|
191
|
+
remove_dir(project_path, "app/components/backend/api/auth")
|
|
192
|
+
remove_file(project_path, "app/models/user.py")
|
|
193
|
+
remove_dir(project_path, "app/services/auth")
|
|
194
|
+
remove_file(project_path, "app/core/security.py")
|
|
195
|
+
remove_file(project_path, "app/cli/auth.py")
|
|
196
|
+
remove_file(project_path, "tests/api/test_auth_endpoints.py")
|
|
197
|
+
remove_file(project_path, "tests/services/test_auth_service.py")
|
|
198
|
+
remove_file(project_path, "tests/services/test_auth_integration.py")
|
|
199
|
+
remove_file(project_path, "tests/models/test_user.py")
|
|
200
|
+
remove_dir(project_path, "alembic")
|
|
201
|
+
|
|
202
|
+
# Remove AI service if not selected
|
|
203
|
+
if not is_enabled("include_ai"):
|
|
204
|
+
remove_dir(project_path, "app/components/backend/api/ai")
|
|
205
|
+
remove_dir(project_path, "app/services/ai")
|
|
206
|
+
remove_file(project_path, "app/cli/ai.py")
|
|
207
|
+
remove_file(project_path, "app/cli/ai_rendering.py")
|
|
208
|
+
remove_file(project_path, "app/cli/marko_terminal_renderer.py")
|
|
209
|
+
remove_file(project_path, "tests/api/test_ai_endpoints.py")
|
|
210
|
+
remove_file(project_path, "tests/services/test_conversation_persistence.py")
|
|
211
|
+
remove_file(project_path, "tests/cli/test_ai_rendering.py")
|
|
212
|
+
remove_file(project_path, "tests/cli/test_conversation_memory.py")
|
|
213
|
+
remove_dir(project_path, "tests/services/ai")
|
|
214
|
+
|
|
215
|
+
# Clean up empty docs/components directory if no components selected
|
|
216
|
+
if (
|
|
217
|
+
not is_enabled("include_scheduler")
|
|
218
|
+
and not is_enabled("include_worker")
|
|
219
|
+
and not is_enabled("include_database")
|
|
220
|
+
and not is_enabled("include_cache")
|
|
221
|
+
):
|
|
222
|
+
remove_dir(project_path, "docs/components")
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
def copy_service_files(
|
|
226
|
+
project_path: Path, service_name: str, template_path: Path
|
|
227
|
+
) -> None:
|
|
228
|
+
"""
|
|
229
|
+
Copy service-specific files from template to project.
|
|
230
|
+
|
|
231
|
+
This is needed when services are added post-generation via Copier update.
|
|
232
|
+
Copier can only re-render existing files - it cannot copy new directories
|
|
233
|
+
that were excluded during initial generation.
|
|
234
|
+
|
|
235
|
+
Args:
|
|
236
|
+
project_path: Path to the project directory
|
|
237
|
+
service_name: Name of the service ('auth', 'ai', etc.)
|
|
238
|
+
template_path: Path to the Copier template directory
|
|
239
|
+
|
|
240
|
+
Note:
|
|
241
|
+
Uses get_component_file_mapping() to know which files belong to each service.
|
|
242
|
+
"""
|
|
243
|
+
# Get the file mapping for this service
|
|
244
|
+
file_mapping = get_component_file_mapping()
|
|
245
|
+
if service_name not in file_mapping:
|
|
246
|
+
print(f"ā ļø Unknown service '{service_name}' - skipping file copy")
|
|
247
|
+
return
|
|
248
|
+
|
|
249
|
+
service_files = file_mapping[service_name]
|
|
250
|
+
print(f"š Copying {service_name} service files from template...")
|
|
251
|
+
|
|
252
|
+
# The template is at: aegis-stack/aegis/templates/copier-aegis-project/{{ project_slug }}/
|
|
253
|
+
# We need to find the template content directory
|
|
254
|
+
template_content = template_path / "{{ project_slug }}"
|
|
255
|
+
if not template_content.exists():
|
|
256
|
+
print(f"ā ļø Template content directory not found: {template_content}")
|
|
257
|
+
return
|
|
258
|
+
|
|
259
|
+
copied_count = 0
|
|
260
|
+
for rel_path in service_files:
|
|
261
|
+
src = template_content / rel_path
|
|
262
|
+
dst = project_path / rel_path
|
|
263
|
+
|
|
264
|
+
# Skip if source doesn't exist (might be conditional on other settings)
|
|
265
|
+
if not src.exists():
|
|
266
|
+
continue
|
|
267
|
+
|
|
268
|
+
# Create parent directory if needed
|
|
269
|
+
dst.parent.mkdir(parents=True, exist_ok=True)
|
|
270
|
+
|
|
271
|
+
# Copy file or directory
|
|
272
|
+
if src.is_dir():
|
|
273
|
+
if dst.exists():
|
|
274
|
+
# Skip if already exists (don't overwrite existing customizations)
|
|
275
|
+
continue
|
|
276
|
+
shutil.copytree(src, dst)
|
|
277
|
+
copied_count += 1
|
|
278
|
+
else:
|
|
279
|
+
# For files, check if .jinja extension (template file)
|
|
280
|
+
if src.suffix == ".jinja":
|
|
281
|
+
# This is a Jinja2 template - we need to render it
|
|
282
|
+
# For now, skip template files (they'll be handled by Copier update)
|
|
283
|
+
continue
|
|
284
|
+
# Copy regular file
|
|
285
|
+
shutil.copy2(src, dst)
|
|
286
|
+
copied_count += 1
|
|
287
|
+
|
|
288
|
+
if copied_count > 0:
|
|
289
|
+
print(f"ā
Copied {copied_count} {service_name} service files")
|
|
290
|
+
else:
|
|
291
|
+
print(f"ā ļø No {service_name} files copied (may already exist or be templates)")
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
def install_dependencies(project_path: Path) -> bool:
|
|
295
|
+
"""
|
|
296
|
+
Install project dependencies using uv.
|
|
297
|
+
|
|
298
|
+
Args:
|
|
299
|
+
project_path: Path to the project directory
|
|
300
|
+
|
|
301
|
+
Returns:
|
|
302
|
+
True if installation succeeded, False otherwise
|
|
303
|
+
"""
|
|
304
|
+
try:
|
|
305
|
+
print("š¦ Installing dependencies with uv...")
|
|
306
|
+
|
|
307
|
+
# Unset VIRTUAL_ENV to avoid conflicts with parent project's venv
|
|
308
|
+
env = os.environ.copy()
|
|
309
|
+
env.pop("VIRTUAL_ENV", None)
|
|
310
|
+
|
|
311
|
+
result = subprocess.run(
|
|
312
|
+
["uv", "sync"],
|
|
313
|
+
cwd=project_path,
|
|
314
|
+
capture_output=True,
|
|
315
|
+
text=True,
|
|
316
|
+
timeout=POST_GEN_TIMEOUT_INSTALL,
|
|
317
|
+
env=env,
|
|
318
|
+
)
|
|
319
|
+
|
|
320
|
+
if result.returncode == 0:
|
|
321
|
+
print("ā
Dependencies installed successfully")
|
|
322
|
+
return True
|
|
323
|
+
else:
|
|
324
|
+
print("ā ļø Dependency installation failed")
|
|
325
|
+
if result.stderr:
|
|
326
|
+
print(f" Error: {result.stderr.strip()}")
|
|
327
|
+
print("š” Run 'uv sync' manually after project creation")
|
|
328
|
+
return False
|
|
329
|
+
|
|
330
|
+
except subprocess.TimeoutExpired:
|
|
331
|
+
print("ā ļø Dependency installation timeout - run 'uv sync' manually")
|
|
332
|
+
return False
|
|
333
|
+
except FileNotFoundError:
|
|
334
|
+
print("ā ļø uv not found in PATH")
|
|
335
|
+
print("š” Install uv first: https://github.com/astral-sh/uv")
|
|
336
|
+
return False
|
|
337
|
+
except Exception as e:
|
|
338
|
+
print(f"ā ļø Dependency installation failed: {e}")
|
|
339
|
+
print("š” Run 'uv sync' manually after project creation")
|
|
340
|
+
return False
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
def setup_env_file(project_path: Path) -> bool:
|
|
344
|
+
"""
|
|
345
|
+
Copy .env.example to .env if .env doesn't exist.
|
|
346
|
+
|
|
347
|
+
Args:
|
|
348
|
+
project_path: Path to the project directory
|
|
349
|
+
|
|
350
|
+
Returns:
|
|
351
|
+
True if setup succeeded or .env already exists, False on error
|
|
352
|
+
"""
|
|
353
|
+
try:
|
|
354
|
+
print("š Setting up environment configuration...")
|
|
355
|
+
env_example = project_path / ".env.example"
|
|
356
|
+
env_file = project_path / ".env"
|
|
357
|
+
|
|
358
|
+
if env_example.exists() and not env_file.exists():
|
|
359
|
+
shutil.copy(env_example, env_file)
|
|
360
|
+
print("ā
Environment file created from .env.example")
|
|
361
|
+
return True
|
|
362
|
+
elif env_file.exists():
|
|
363
|
+
print("ā
Environment file already exists")
|
|
364
|
+
return True
|
|
365
|
+
else:
|
|
366
|
+
print("ā ļø No .env.example file found")
|
|
367
|
+
return False
|
|
368
|
+
|
|
369
|
+
except Exception as e:
|
|
370
|
+
print(f"ā ļø Environment setup failed: {e}")
|
|
371
|
+
print("š” Copy .env.example to .env manually")
|
|
372
|
+
return False
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
def run_migrations(project_path: Path, include_auth: bool = False) -> bool:
|
|
376
|
+
"""
|
|
377
|
+
Run Alembic database migrations if auth service is enabled.
|
|
378
|
+
|
|
379
|
+
Args:
|
|
380
|
+
project_path: Path to the project directory
|
|
381
|
+
include_auth: Whether auth service is enabled
|
|
382
|
+
|
|
383
|
+
Returns:
|
|
384
|
+
True if migrations succeeded or not needed, False on error
|
|
385
|
+
"""
|
|
386
|
+
if not include_auth:
|
|
387
|
+
return True # No migrations needed
|
|
388
|
+
|
|
389
|
+
try:
|
|
390
|
+
print("šļø Setting up database with auth schema...")
|
|
391
|
+
|
|
392
|
+
# Ensure data directory exists
|
|
393
|
+
data_dir = project_path / "data"
|
|
394
|
+
data_dir.mkdir(exist_ok=True)
|
|
395
|
+
|
|
396
|
+
# Verify alembic config exists before running migration
|
|
397
|
+
alembic_ini_path = project_path / "alembic" / "alembic.ini"
|
|
398
|
+
if not alembic_ini_path.exists():
|
|
399
|
+
print(f"ā ļø Alembic config file not found at {alembic_ini_path}")
|
|
400
|
+
print(
|
|
401
|
+
"š” Skipping database migration. Please ensure the config file exists "
|
|
402
|
+
"and run 'alembic upgrade head' manually."
|
|
403
|
+
)
|
|
404
|
+
return False
|
|
405
|
+
|
|
406
|
+
# Run alembic migrations using uv run (ensures correct environment)
|
|
407
|
+
# Unset VIRTUAL_ENV to avoid conflicts with parent project's venv
|
|
408
|
+
env = os.environ.copy()
|
|
409
|
+
env.pop("VIRTUAL_ENV", None)
|
|
410
|
+
|
|
411
|
+
result = subprocess.run(
|
|
412
|
+
[
|
|
413
|
+
"uv",
|
|
414
|
+
"run",
|
|
415
|
+
"alembic",
|
|
416
|
+
"-c",
|
|
417
|
+
str(alembic_ini_path),
|
|
418
|
+
"upgrade",
|
|
419
|
+
"head",
|
|
420
|
+
],
|
|
421
|
+
cwd=project_path,
|
|
422
|
+
capture_output=True,
|
|
423
|
+
text=True,
|
|
424
|
+
timeout=POST_GEN_TIMEOUT_MIGRATION,
|
|
425
|
+
env=env,
|
|
426
|
+
)
|
|
427
|
+
|
|
428
|
+
if result.returncode == 0:
|
|
429
|
+
print("ā
Database tables created successfully")
|
|
430
|
+
return True
|
|
431
|
+
else:
|
|
432
|
+
print("ā ļø Database migration setup failed")
|
|
433
|
+
if result.stderr:
|
|
434
|
+
print(f" Error: {result.stderr.strip()}")
|
|
435
|
+
print("š” Run 'alembic upgrade head' manually after project creation")
|
|
436
|
+
return False
|
|
437
|
+
|
|
438
|
+
except subprocess.TimeoutExpired:
|
|
439
|
+
print("ā ļø Migration setup timeout - run 'alembic upgrade head' manually")
|
|
440
|
+
return False
|
|
441
|
+
except Exception as e:
|
|
442
|
+
print(f"ā ļø Migration setup failed: {e}")
|
|
443
|
+
print("š” Run 'alembic upgrade head' manually after project creation")
|
|
444
|
+
return False
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
def format_code(project_path: Path) -> bool:
|
|
448
|
+
"""
|
|
449
|
+
Auto-format generated code using make fix.
|
|
450
|
+
|
|
451
|
+
Args:
|
|
452
|
+
project_path: Path to the project directory
|
|
453
|
+
|
|
454
|
+
Returns:
|
|
455
|
+
True if formatting succeeded, False otherwise
|
|
456
|
+
"""
|
|
457
|
+
try:
|
|
458
|
+
print("šØ Auto-formatting generated code...")
|
|
459
|
+
|
|
460
|
+
# Call make fix to auto-format the generated project
|
|
461
|
+
# Unset VIRTUAL_ENV to avoid conflicts with parent project's venv
|
|
462
|
+
env = os.environ.copy()
|
|
463
|
+
env.pop("VIRTUAL_ENV", None)
|
|
464
|
+
|
|
465
|
+
result = subprocess.run(
|
|
466
|
+
["make", "fix"],
|
|
467
|
+
cwd=project_path,
|
|
468
|
+
capture_output=True,
|
|
469
|
+
text=True,
|
|
470
|
+
timeout=POST_GEN_TIMEOUT_FORMAT,
|
|
471
|
+
env=env,
|
|
472
|
+
)
|
|
473
|
+
|
|
474
|
+
if result.returncode == 0:
|
|
475
|
+
print("ā
Code formatting completed successfully")
|
|
476
|
+
return True
|
|
477
|
+
else:
|
|
478
|
+
print(
|
|
479
|
+
"ā ļø Some formatting issues detected, but project created successfully"
|
|
480
|
+
)
|
|
481
|
+
print("š” Run 'make fix' manually to resolve remaining issues")
|
|
482
|
+
return False
|
|
483
|
+
|
|
484
|
+
except FileNotFoundError:
|
|
485
|
+
print("š” Run 'make fix' to format code when ready")
|
|
486
|
+
return False
|
|
487
|
+
except subprocess.TimeoutExpired:
|
|
488
|
+
print("ā ļø Formatting timeout - run 'make fix' manually when ready")
|
|
489
|
+
return False
|
|
490
|
+
except Exception as e:
|
|
491
|
+
print(f"ā ļø Auto-formatting skipped: {e}")
|
|
492
|
+
print("š” Run 'make fix' manually to format code")
|
|
493
|
+
return False
|
|
494
|
+
|
|
495
|
+
|
|
496
|
+
def run_post_generation_tasks(project_path: Path, include_auth: bool = False) -> bool:
|
|
497
|
+
"""
|
|
498
|
+
Run all post-generation tasks for a project.
|
|
499
|
+
|
|
500
|
+
This is the main entry point called by both Cookiecutter hooks
|
|
501
|
+
and Copier updaters.
|
|
502
|
+
|
|
503
|
+
Args:
|
|
504
|
+
project_path: Path to the generated/updated project
|
|
505
|
+
include_auth: Whether auth service is enabled (triggers migrations)
|
|
506
|
+
|
|
507
|
+
Returns:
|
|
508
|
+
True if all critical tasks succeeded, False otherwise
|
|
509
|
+
|
|
510
|
+
Note:
|
|
511
|
+
Individual task failures don't stop execution - we try to complete
|
|
512
|
+
as many tasks as possible and report what needs manual intervention.
|
|
513
|
+
"""
|
|
514
|
+
print("\nš Setting up your project environment...")
|
|
515
|
+
|
|
516
|
+
# Task 1: Install dependencies (critical)
|
|
517
|
+
deps_success = install_dependencies(project_path)
|
|
518
|
+
|
|
519
|
+
# Task 2: Setup .env file (non-critical)
|
|
520
|
+
setup_env_file(project_path)
|
|
521
|
+
|
|
522
|
+
# Task 3: Run migrations if auth enabled (non-critical)
|
|
523
|
+
run_migrations(project_path, include_auth)
|
|
524
|
+
|
|
525
|
+
# Task 4: Format code (non-critical)
|
|
526
|
+
format_code(project_path)
|
|
527
|
+
|
|
528
|
+
# Print final status
|
|
529
|
+
print("\n" + "=" * 60)
|
|
530
|
+
if deps_success:
|
|
531
|
+
print("ā
Project ready to run!")
|
|
532
|
+
print("\nš Next steps:")
|
|
533
|
+
print(f" cd {project_path.name}")
|
|
534
|
+
print(" make server")
|
|
535
|
+
print("\nš” Your application is fully configured and ready to use!")
|
|
536
|
+
else:
|
|
537
|
+
print("ā ļø Project created with some setup issues")
|
|
538
|
+
print("\nš Manual setup required:")
|
|
539
|
+
print(f" cd {project_path.name}")
|
|
540
|
+
print(" uv sync")
|
|
541
|
+
print(" cp .env.example .env")
|
|
542
|
+
if include_auth:
|
|
543
|
+
print(" alembic upgrade head")
|
|
544
|
+
print(" make server")
|
|
545
|
+
print("=" * 60)
|
|
546
|
+
|
|
547
|
+
return deps_success
|