khaira 0.2.0__tar.gz

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 (283) hide show
  1. khaira-0.2.0/PKG-INFO +1244 -0
  2. khaira-0.2.0/README.md +1140 -0
  3. khaira-0.2.0/kaira/__init__.py +23 -0
  4. khaira-0.2.0/kaira/app/__init__.py +23 -0
  5. khaira-0.2.0/kaira/app/ai/__init__.py +9 -0
  6. khaira-0.2.0/kaira/app/ai/agent.py +28 -0
  7. khaira-0.2.0/kaira/app/ai/gateway.py +37 -0
  8. khaira-0.2.0/kaira/app/ai/rag.py +35 -0
  9. khaira-0.2.0/kaira/app/analytics/__init__.py +60 -0
  10. khaira-0.2.0/kaira/app/auth/__init__.py +17 -0
  11. khaira-0.2.0/kaira/app/auth/api_key.py +27 -0
  12. khaira-0.2.0/kaira/app/auth/jwt.py +65 -0
  13. khaira-0.2.0/kaira/app/auth/oauth2.py +25 -0
  14. khaira-0.2.0/kaira/app/auth/password.py +73 -0
  15. khaira-0.2.0/kaira/app/cache/__init__.py +7 -0
  16. khaira-0.2.0/kaira/app/container.py +31 -0
  17. khaira-0.2.0/kaira/app/database/__init__.py +19 -0
  18. khaira-0.2.0/kaira/app/dep.py +22 -0
  19. khaira-0.2.0/kaira/app/exceptions.py +51 -0
  20. khaira-0.2.0/kaira/app/export/__init__.py +73 -0
  21. khaira-0.2.0/kaira/app/kaira_app.py +279 -0
  22. khaira-0.2.0/kaira/app/lifecycle.py +46 -0
  23. khaira-0.2.0/kaira/app/logging.py +56 -0
  24. khaira-0.2.0/kaira/app/middleware/__init__.py +18 -0
  25. khaira-0.2.0/kaira/app/middleware/base.py +7 -0
  26. khaira-0.2.0/kaira/app/middleware/cors.py +21 -0
  27. khaira-0.2.0/kaira/app/middleware/layer_guard.py +84 -0
  28. khaira-0.2.0/kaira/app/middleware/rate_limit.py +52 -0
  29. khaira-0.2.0/kaira/app/middleware/security_headers.py +34 -0
  30. khaira-0.2.0/kaira/app/models/__init__.py +41 -0
  31. khaira-0.2.0/kaira/app/models/mongo.py +24 -0
  32. khaira-0.2.0/kaira/app/models/peewee.py +22 -0
  33. khaira-0.2.0/kaira/app/models/sqlalchemy.py +14 -0
  34. khaira-0.2.0/kaira/app/models/sqlmodel.py +24 -0
  35. khaira-0.2.0/kaira/app/models/tortoise.py +22 -0
  36. khaira-0.2.0/kaira/app/notify/__init__.py +28 -0
  37. khaira-0.2.0/kaira/app/providers/__init__.py +44 -0
  38. khaira-0.2.0/kaira/app/providers/auth.py +50 -0
  39. khaira-0.2.0/kaira/app/providers/base.py +28 -0
  40. khaira-0.2.0/kaira/app/providers/cache.py +79 -0
  41. khaira-0.2.0/kaira/app/providers/monitor.py +44 -0
  42. khaira-0.2.0/kaira/app/providers/task.py +43 -0
  43. khaira-0.2.0/kaira/app/search/__init__.py +18 -0
  44. khaira-0.2.0/kaira/app/security/__init__.py +32 -0
  45. khaira-0.2.0/kaira/app/storage/__init__.py +23 -0
  46. khaira-0.2.0/kaira/app/task/__init__.py +7 -0
  47. khaira-0.2.0/kaira/app/tracing.py +49 -0
  48. khaira-0.2.0/kaira/commands/__init__.py +1 -0
  49. khaira-0.2.0/kaira/commands/ai_cmd.py +540 -0
  50. khaira-0.2.0/kaira/commands/api_cmd.py +346 -0
  51. khaira-0.2.0/kaira/commands/audit_cmd.py +449 -0
  52. khaira-0.2.0/kaira/commands/auth_cmd.py +325 -0
  53. khaira-0.2.0/kaira/commands/cache_cmd.py +282 -0
  54. khaira-0.2.0/kaira/commands/check.py +66 -0
  55. khaira-0.2.0/kaira/commands/ci_cmd.py +94 -0
  56. khaira-0.2.0/kaira/commands/cloud_cmd.py +1047 -0
  57. khaira-0.2.0/kaira/commands/commands_cmd.py +243 -0
  58. khaira-0.2.0/kaira/commands/config_cmd.py +143 -0
  59. khaira-0.2.0/kaira/commands/dashboard.py +374 -0
  60. khaira-0.2.0/kaira/commands/db_cmd.py +1204 -0
  61. khaira-0.2.0/kaira/commands/deploy_cmd.py +301 -0
  62. khaira-0.2.0/kaira/commands/deps_cmd.py +416 -0
  63. khaira-0.2.0/kaira/commands/diff.py +219 -0
  64. khaira-0.2.0/kaira/commands/doc_migrate_cmd.py +126 -0
  65. khaira-0.2.0/kaira/commands/docker_cmd.py +1064 -0
  66. khaira-0.2.0/kaira/commands/docs.py +367 -0
  67. khaira-0.2.0/kaira/commands/env_cmd.py +671 -0
  68. khaira-0.2.0/kaira/commands/event_cmd.py +116 -0
  69. khaira-0.2.0/kaira/commands/export_cmd.py +994 -0
  70. khaira-0.2.0/kaira/commands/flags_cmd.py +223 -0
  71. khaira-0.2.0/kaira/commands/generate.py +587 -0
  72. khaira-0.2.0/kaira/commands/guide_cmd.py +1071 -0
  73. khaira-0.2.0/kaira/commands/health.py +293 -0
  74. khaira-0.2.0/kaira/commands/health_endpoint_cmd.py +100 -0
  75. khaira-0.2.0/kaira/commands/info.py +56 -0
  76. khaira-0.2.0/kaira/commands/integrate_cmd.py +256 -0
  77. khaira-0.2.0/kaira/commands/list_cmd.py +207 -0
  78. khaira-0.2.0/kaira/commands/loadtest_cmd.py +189 -0
  79. khaira-0.2.0/kaira/commands/menu_cmd.py +629 -0
  80. khaira-0.2.0/kaira/commands/middleware_cmd.py +170 -0
  81. khaira-0.2.0/kaira/commands/migrate.py +285 -0
  82. khaira-0.2.0/kaira/commands/monitor_cmd.py +1378 -0
  83. khaira-0.2.0/kaira/commands/notify_cmd.py +247 -0
  84. khaira-0.2.0/kaira/commands/onboarding.py +172 -0
  85. khaira-0.2.0/kaira/commands/profile_cmd.py +175 -0
  86. khaira-0.2.0/kaira/commands/project.py +1314 -0
  87. khaira-0.2.0/kaira/commands/quality_cmd.py +201 -0
  88. khaira-0.2.0/kaira/commands/recap_cmd.py +133 -0
  89. khaira-0.2.0/kaira/commands/relation.py +222 -0
  90. khaira-0.2.0/kaira/commands/run_cmd.py +537 -0
  91. khaira-0.2.0/kaira/commands/seed_cmd.py +614 -0
  92. khaira-0.2.0/kaira/commands/smart_errors.py +178 -0
  93. khaira-0.2.0/kaira/commands/status_cmd.py +203 -0
  94. khaira-0.2.0/kaira/commands/sync_cmd.py +552 -0
  95. khaira-0.2.0/kaira/commands/task_cmd.py +268 -0
  96. khaira-0.2.0/kaira/commands/test_cmd.py +199 -0
  97. khaira-0.2.0/kaira/commands/ux_helpers.py +235 -0
  98. khaira-0.2.0/kaira/commands/version_cmd.py +167 -0
  99. khaira-0.2.0/kaira/commands/websocket_cmd.py +79 -0
  100. khaira-0.2.0/kaira/config.py +292 -0
  101. khaira-0.2.0/kaira/console.py +25 -0
  102. khaira-0.2.0/kaira/core/__init__.py +12 -0
  103. khaira-0.2.0/kaira/core/ai_introspect.py +112 -0
  104. khaira-0.2.0/kaira/core/aliases.py +226 -0
  105. khaira-0.2.0/kaira/core/detector.py +203 -0
  106. khaira-0.2.0/kaira/core/docker_render.py +361 -0
  107. khaira-0.2.0/kaira/core/docker_state.py +788 -0
  108. khaira-0.2.0/kaira/core/docs_render.py +1425 -0
  109. khaira-0.2.0/kaira/core/drivers/__init__.py +23 -0
  110. khaira-0.2.0/kaira/core/drivers/base.py +61 -0
  111. khaira-0.2.0/kaira/core/drivers/document_driver.py +73 -0
  112. khaira-0.2.0/kaira/core/drivers/relational_driver.py +59 -0
  113. khaira-0.2.0/kaira/core/export.py +845 -0
  114. khaira-0.2.0/kaira/core/fallback_engine.py +84 -0
  115. khaira-0.2.0/kaira/core/generator.py +262 -0
  116. khaira-0.2.0/kaira/core/license.py +31 -0
  117. khaira-0.2.0/kaira/core/monitor_state.py +530 -0
  118. khaira-0.2.0/kaira/core/motion.py +228 -0
  119. khaira-0.2.0/kaira/core/parser.py +365 -0
  120. khaira-0.2.0/kaira/core/ports.py +311 -0
  121. khaira-0.2.0/kaira/core/progress.py +658 -0
  122. khaira-0.2.0/kaira/core/project_runner.py +81 -0
  123. khaira-0.2.0/kaira/core/prompts.py +397 -0
  124. khaira-0.2.0/kaira/core/provisioner.py +729 -0
  125. khaira-0.2.0/kaira/core/route_discovery.py +461 -0
  126. khaira-0.2.0/kaira/core/security.py +71 -0
  127. khaira-0.2.0/kaira/core/stats.py +210 -0
  128. khaira-0.2.0/kaira/core/theme.py +611 -0
  129. khaira-0.2.0/kaira/core/ui.py +780 -0
  130. khaira-0.2.0/kaira/core/wiring.py +48 -0
  131. khaira-0.2.0/kaira/main.py +573 -0
  132. khaira-0.2.0/kaira/migrations/__init__.py +16 -0
  133. khaira-0.2.0/kaira/migrations/config_updater.py +33 -0
  134. khaira-0.2.0/kaira/migrations/engine.py +110 -0
  135. khaira-0.2.0/kaira/migrations/file_splitter.py +51 -0
  136. khaira-0.2.0/kaira/migrations/file_writer.py +62 -0
  137. khaira-0.2.0/kaira/migrations/main_updater.py +76 -0
  138. khaira-0.2.0/kaira/migrations/rollback.py +77 -0
  139. khaira-0.2.0/kaira/migrations/rules.py +47 -0
  140. khaira-0.2.0/kaira/migrations/verifier.py +62 -0
  141. khaira-0.2.0/kaira/templates/_docker_macros.j2 +96 -0
  142. khaira-0.2.0/kaira/templates/_seed_macros.j2 +135 -0
  143. khaira-0.2.0/kaira/templates/abstraction_layer.py.j2 +268 -0
  144. khaira-0.2.0/kaira/templates/agents_project.md.j2 +108 -0
  145. khaira-0.2.0/kaira/templates/ai_agent.py.j2 +47 -0
  146. khaira-0.2.0/kaira/templates/ai_agent_router.py.j2 +42 -0
  147. khaira-0.2.0/kaira/templates/ai_gateway.py.j2 +176 -0
  148. khaira-0.2.0/kaira/templates/ai_rag_model.py.j2 +52 -0
  149. khaira-0.2.0/kaira/templates/ai_rag_repository.py.j2 +73 -0
  150. khaira-0.2.0/kaira/templates/ai_rag_router.py.j2 +76 -0
  151. khaira-0.2.0/kaira/templates/ai_rag_service.py.j2 +89 -0
  152. khaira-0.2.0/kaira/templates/ai_skill.py.j2 +63 -0
  153. khaira-0.2.0/kaira/templates/ai_supervisor_graph.py.j2 +75 -0
  154. khaira-0.2.0/kaira/templates/association.py.j2 +26 -0
  155. khaira-0.2.0/kaira/templates/auth.py.j2 +77 -0
  156. khaira-0.2.0/kaira/templates/auth_api_key.py.j2 +65 -0
  157. khaira-0.2.0/kaira/templates/auth_blacklisted_token_model.py.j2 +36 -0
  158. khaira-0.2.0/kaira/templates/auth_jwt_dependencies.py.j2 +58 -0
  159. khaira-0.2.0/kaira/templates/auth_jwt_router.py.j2 +118 -0
  160. khaira-0.2.0/kaira/templates/auth_jwt_schemas.py.j2 +15 -0
  161. khaira-0.2.0/kaira/templates/auth_jwt_service.py.j2 +229 -0
  162. khaira-0.2.0/kaira/templates/auth_jwt_utils.py.j2 +79 -0
  163. khaira-0.2.0/kaira/templates/auth_oauth2.py.j2 +190 -0
  164. khaira-0.2.0/kaira/templates/cache.py.j2 +107 -0
  165. khaira-0.2.0/kaira/templates/celery_app.py.j2 +33 -0
  166. khaira-0.2.0/kaira/templates/celery_task.py.j2 +56 -0
  167. khaira-0.2.0/kaira/templates/ci_bitbucket.yml.j2 +65 -0
  168. khaira-0.2.0/kaira/templates/ci_github.yml.j2 +38 -0
  169. khaira-0.2.0/kaira/templates/ci_github_deploy.yml.j2 +38 -0
  170. khaira-0.2.0/kaira/templates/ci_github_security.yml.j2 +31 -0
  171. khaira-0.2.0/kaira/templates/ci_gitlab.yml.j2 +58 -0
  172. khaira-0.2.0/kaira/templates/database.py.j2 +42 -0
  173. khaira-0.2.0/kaira/templates/database_async.py.j2 +90 -0
  174. khaira-0.2.0/kaira/templates/database_mongodb.py.j2 +112 -0
  175. khaira-0.2.0/kaira/templates/db_mode.py.j2 +131 -0
  176. khaira-0.2.0/kaira/templates/deploy_fly.toml.j2 +21 -0
  177. khaira-0.2.0/kaira/templates/deploy_railway.toml.j2 +14 -0
  178. khaira-0.2.0/kaira/templates/deploy_render.yaml.j2 +17 -0
  179. khaira-0.2.0/kaira/templates/deploy_vps_script.sh.j2 +30 -0
  180. khaira-0.2.0/kaira/templates/docker_compose.j2 +28 -0
  181. khaira-0.2.0/kaira/templates/docker_compose_prod.j2 +32 -0
  182. khaira-0.2.0/kaira/templates/docker_dockerfile.j2 +109 -0
  183. khaira-0.2.0/kaira/templates/docker_ignore.j2 +89 -0
  184. khaira-0.2.0/kaira/templates/docs/api-reference.md.j2 +13 -0
  185. khaira-0.2.0/kaira/templates/docs/architecture.md.j2 +40 -0
  186. khaira-0.2.0/kaira/templates/docs/index.md.j2 +16 -0
  187. khaira-0.2.0/kaira/templates/docs/migration-guide.md.j2 +26 -0
  188. khaira-0.2.0/kaira/templates/docs/setup.md.j2 +26 -0
  189. khaira-0.2.0/kaira/templates/embedded_model.py.j2 +43 -0
  190. khaira-0.2.0/kaira/templates/env_settings.py.j2 +93 -0
  191. khaira-0.2.0/kaira/templates/events_shutdown.py.j2 +30 -0
  192. khaira-0.2.0/kaira/templates/events_startup.py.j2 +29 -0
  193. khaira-0.2.0/kaira/templates/export_router_imports.py.j2 +9 -0
  194. khaira-0.2.0/kaira/templates/export_router_route.py.j2 +45 -0
  195. khaira-0.2.0/kaira/templates/export_service_imports.py.j2 +5 -0
  196. khaira-0.2.0/kaira/templates/export_service_method.py.j2 +31 -0
  197. khaira-0.2.0/kaira/templates/fallback_core.py.j2 +401 -0
  198. khaira-0.2.0/kaira/templates/firestore/model_firestore.py.j2 +49 -0
  199. khaira-0.2.0/kaira/templates/firestore/repository_firestore.py.j2 +155 -0
  200. khaira-0.2.0/kaira/templates/firestore/router_firestore.py.j2 +162 -0
  201. khaira-0.2.0/kaira/templates/firestore/schema_firestore.py.j2 +70 -0
  202. khaira-0.2.0/kaira/templates/firestore/service_firestore.py.j2 +152 -0
  203. khaira-0.2.0/kaira/templates/flags.py.j2 +35 -0
  204. khaira-0.2.0/kaira/templates/gitignore_project.j2 +40 -0
  205. khaira-0.2.0/kaira/templates/health_router.py.j2 +57 -0
  206. khaira-0.2.0/kaira/templates/integration_schema.py.j2 +33 -0
  207. khaira-0.2.0/kaira/templates/integration_service.py.j2 +101 -0
  208. khaira-0.2.0/kaira/templates/logger.py.j2 +495 -0
  209. khaira-0.2.0/kaira/templates/main_app.py.j2 +26 -0
  210. khaira-0.2.0/kaira/templates/main_app_v3.py.j2 +137 -0
  211. khaira-0.2.0/kaira/templates/main_simple.py.j2 +13 -0
  212. khaira-0.2.0/kaira/templates/makefile.j2 +48 -0
  213. khaira-0.2.0/kaira/templates/message_schema.py.j2 +9 -0
  214. khaira-0.2.0/kaira/templates/middleware_custom.py.j2 +54 -0
  215. khaira-0.2.0/kaira/templates/model.py.j2 +106 -0
  216. khaira-0.2.0/kaira/templates/model_mongodb.py.j2 +78 -0
  217. khaira-0.2.0/kaira/templates/monitor_dashboard.py.j2 +601 -0
  218. khaira-0.2.0/kaira/templates/monitor_metrics.py.j2 +789 -0
  219. khaira-0.2.0/kaira/templates/monitor_middleware.py.j2 +191 -0
  220. khaira-0.2.0/kaira/templates/monitor_probes_router.py.j2 +119 -0
  221. khaira-0.2.0/kaira/templates/monitor_router.py.j2 +188 -0
  222. khaira-0.2.0/kaira/templates/monitor_sdk.py.j2 +162 -0
  223. khaira-0.2.0/kaira/templates/pyproject_generated.toml.j2 +45 -0
  224. khaira-0.2.0/kaira/templates/rate_limit.py.j2 +6 -0
  225. khaira-0.2.0/kaira/templates/readme_project.md.j2 +129 -0
  226. khaira-0.2.0/kaira/templates/repository.py.j2 +80 -0
  227. khaira-0.2.0/kaira/templates/repository_async.py.j2 +137 -0
  228. khaira-0.2.0/kaira/templates/repository_mongodb.py.j2 +105 -0
  229. khaira-0.2.0/kaira/templates/requirements.txt.j2 +42 -0
  230. khaira-0.2.0/kaira/templates/router.py.j2 +185 -0
  231. khaira-0.2.0/kaira/templates/schema.py.j2 +147 -0
  232. khaira-0.2.0/kaira/templates/security_middleware.py.j2 +416 -0
  233. khaira-0.2.0/kaira/templates/seed_model_doc.py.j2 +108 -0
  234. khaira-0.2.0/kaira/templates/seed_model_sql.py.j2 +105 -0
  235. khaira-0.2.0/kaira/templates/service.py.j2 +249 -0
  236. khaira-0.2.0/kaira/templates/skills/skill_ai_agent.md.j2 +63 -0
  237. khaira-0.2.0/kaira/templates/skills/skill_db_migrations.md.j2 +51 -0
  238. khaira-0.2.0/kaira/templates/skills/skill_quality_gate.md.j2 +47 -0
  239. khaira-0.2.0/kaira/templates/skills/skill_scaffold_model.md.j2 +67 -0
  240. khaira-0.2.0/kaira/templates/skills/skill_sync_layers.md.j2 +43 -0
  241. khaira-0.2.0/kaira/templates/test_conftest.py.j2 +63 -0
  242. khaira-0.2.0/kaira/templates/test_repository.py.j2 +52 -0
  243. khaira-0.2.0/kaira/templates/test_router.py.j2 +109 -0
  244. khaira-0.2.0/kaira/templates/test_service.py.j2 +55 -0
  245. khaira-0.2.0/kaira/templates/ws_manager.py.j2 +134 -0
  246. khaira-0.2.0/kaira/templates/ws_router.py.j2 +108 -0
  247. khaira-0.2.0/kaira/templates/ws_schemas.py.j2 +50 -0
  248. khaira-0.2.0/khaira.egg-info/PKG-INFO +1244 -0
  249. khaira-0.2.0/khaira.egg-info/SOURCES.txt +281 -0
  250. khaira-0.2.0/khaira.egg-info/dependency_links.txt +1 -0
  251. khaira-0.2.0/khaira.egg-info/entry_points.txt +3 -0
  252. khaira-0.2.0/khaira.egg-info/requires.txt +96 -0
  253. khaira-0.2.0/khaira.egg-info/top_level.txt +1 -0
  254. khaira-0.2.0/pyproject.toml +151 -0
  255. khaira-0.2.0/setup.cfg +4 -0
  256. khaira-0.2.0/tests/test_ai_cmd.py +201 -0
  257. khaira-0.2.0/tests/test_commands.py +348 -0
  258. khaira-0.2.0/tests/test_detector.py +191 -0
  259. khaira-0.2.0/tests/test_generator.py +290 -0
  260. khaira-0.2.0/tests/test_parser.py +234 -0
  261. khaira-0.2.0/tests/test_phase10_route_discovery.py +341 -0
  262. khaira-0.2.0/tests/test_phase2.py +138 -0
  263. khaira-0.2.0/tests/test_phase3.py +115 -0
  264. khaira-0.2.0/tests/test_phase4_commands.py +460 -0
  265. khaira-0.2.0/tests/test_phase4_ux.py +160 -0
  266. khaira-0.2.0/tests/test_phase4_wiring.py +37 -0
  267. khaira-0.2.0/tests/test_phase55.py +507 -0
  268. khaira-0.2.0/tests/test_phase5_cloud.py +275 -0
  269. khaira-0.2.0/tests/test_phase5_fallback.py +352 -0
  270. khaira-0.2.0/tests/test_phase5_ux.py +259 -0
  271. khaira-0.2.0/tests/test_phase6.py +694 -0
  272. khaira-0.2.0/tests/test_phase75.py +906 -0
  273. khaira-0.2.0/tests/test_phase7_export.py +1158 -0
  274. khaira-0.2.0/tests/test_phase7_nosql.py +447 -0
  275. khaira-0.2.0/tests/test_phase8_logging.py +480 -0
  276. khaira-0.2.0/tests/test_phase9_embedded.py +687 -0
  277. khaira-0.2.0/tests/test_phase_banner.py +499 -0
  278. khaira-0.2.0/tests/test_phase_docker.py +1682 -0
  279. khaira-0.2.0/tests/test_phase_docs.py +617 -0
  280. khaira-0.2.0/tests/test_phase_monitoring.py +1443 -0
  281. khaira-0.2.0/tests/test_phase_motion.py +467 -0
  282. khaira-0.2.0/tests/test_phase_ports.py +329 -0
  283. khaira-0.2.0/tests/test_shortcuts.py +387 -0
khaira-0.2.0/PKG-INFO ADDED
@@ -0,0 +1,1244 @@
1
+ Metadata-Version: 2.4
2
+ Name: khaira
3
+ Version: 0.2.0
4
+ Summary: Automated FastAPI scaffolding CLI and framework runtime
5
+ Author: Khair
6
+ License: MIT
7
+ Keywords: fastapi,scaffolding,cli,codegen,sqlalchemy,framework
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.10
10
+ Classifier: Programming Language :: Python :: 3.11
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Topic :: Software Development :: Code Generators
15
+ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
16
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
17
+ Classifier: Topic :: Utilities
18
+ Requires-Python: >=3.10
19
+ Description-Content-Type: text/markdown
20
+ Requires-Dist: typer[all]>=0.12.0
21
+ Requires-Dist: rich>=13.0.0
22
+ Requires-Dist: jinja2>=3.1.0
23
+ Requires-Dist: fastapi>=0.110.0
24
+ Requires-Dist: sqlalchemy>=2.0.0
25
+ Requires-Dist: alembic>=1.13.0
26
+ Requires-Dist: pydantic>=2.0.0
27
+ Requires-Dist: httpx>=0.27.0
28
+ Requires-Dist: python-dotenv>=1.0.0
29
+ Requires-Dist: loguru>=0.7.0
30
+ Requires-Dist: questionary>=2.0.1
31
+ Requires-Dist: InquirerPy>=0.3.4
32
+ Provides-Extra: framework
33
+ Requires-Dist: fastapi>=0.110.0; extra == "framework"
34
+ Requires-Dist: uvicorn>=0.30.0; extra == "framework"
35
+ Provides-Extra: security
36
+ Requires-Dist: argon2-cffi>=23.1.0; extra == "security"
37
+ Requires-Dist: bcrypt>=4.0.0; extra == "security"
38
+ Requires-Dist: PyJWT>=2.8.0; extra == "security"
39
+ Requires-Dist: Authlib>=1.3.0; extra == "security"
40
+ Requires-Dist: cryptography>=41.0.0; extra == "security"
41
+ Requires-Dist: pip-audit>=2.7.0; extra == "security"
42
+ Requires-Dist: slowapi>=0.1.9; extra == "security"
43
+ Requires-Dist: python-dotenv>=1.0.0; extra == "security"
44
+ Provides-Extra: ai
45
+ Requires-Dist: openai>=1.0.0; extra == "ai"
46
+ Requires-Dist: anthropic>=0.30.0; extra == "ai"
47
+ Requires-Dist: langchain>=0.1.0; extra == "ai"
48
+ Requires-Dist: langchain-community; extra == "ai"
49
+ Requires-Dist: langchain-openai; extra == "ai"
50
+ Requires-Dist: langgraph>=0.2.0; extra == "ai"
51
+ Requires-Dist: llama-index>=0.10.0; extra == "ai"
52
+ Requires-Dist: cohere>=5.0.0; extra == "ai"
53
+ Requires-Dist: google-generativeai; extra == "ai"
54
+ Requires-Dist: chromadb>=0.4.0; extra == "ai"
55
+ Provides-Extra: orm
56
+ Requires-Dist: sqlalchemy>=2.0.0; extra == "orm"
57
+ Requires-Dist: sqlmodel>=0.0.14; extra == "orm"
58
+ Requires-Dist: peewee>=3.17.0; extra == "orm"
59
+ Requires-Dist: tortoise-orm>=0.20.0; extra == "orm"
60
+ Requires-Dist: beanie>=1.24.0; extra == "orm"
61
+ Provides-Extra: dev
62
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
63
+ Requires-Dist: pytest-cov>=5.0.0; extra == "dev"
64
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
65
+ Requires-Dist: mypy>=1.8.0; extra == "dev"
66
+ Requires-Dist: ruff>=0.4.0; extra == "dev"
67
+ Requires-Dist: bandit>=1.7.0; extra == "dev"
68
+ Requires-Dist: PyYAML>=6.0.0; extra == "dev"
69
+ Requires-Dist: prometheus-client>=0.20.0; extra == "dev"
70
+ Provides-Extra: cache
71
+ Requires-Dist: redis>=5.0.0; extra == "cache"
72
+ Provides-Extra: task
73
+ Requires-Dist: celery[redis]>=5.4.0; extra == "task"
74
+ Requires-Dist: flower>=2.0.0; extra == "task"
75
+ Provides-Extra: fuzzy
76
+ Requires-Dist: rapidfuzz>=3.0.0; extra == "fuzzy"
77
+ Provides-Extra: audit
78
+ Requires-Dist: pip-audit>=2.7.0; extra == "audit"
79
+ Provides-Extra: export
80
+ Requires-Dist: openpyxl>=3.1.0; extra == "export"
81
+ Requires-Dist: reportlab>=4.0.0; extra == "export"
82
+ Requires-Dist: python-docx>=1.1.0; extra == "export"
83
+ Provides-Extra: all
84
+ Requires-Dist: redis>=5.0.0; extra == "all"
85
+ Requires-Dist: celery[redis]>=5.4.0; extra == "all"
86
+ Requires-Dist: flower>=2.0.0; extra == "all"
87
+ Requires-Dist: rapidfuzz>=3.0.0; extra == "all"
88
+ Requires-Dist: pip-audit>=2.7.0; extra == "all"
89
+ Requires-Dist: InquirerPy>=0.3.4; extra == "all"
90
+ Requires-Dist: asyncpg>=0.29.0; extra == "all"
91
+ Requires-Dist: motor>=3.3.0; extra == "all"
92
+ Requires-Dist: beanie>=1.24.0; extra == "all"
93
+ Requires-Dist: google-cloud-firestore>=2.16.0; extra == "all"
94
+ Requires-Dist: aiosqlite>=0.20.0; extra == "all"
95
+ Requires-Dist: openpyxl>=3.1.0; extra == "all"
96
+ Requires-Dist: reportlab>=4.0.0; extra == "all"
97
+ Requires-Dist: python-docx>=1.1.0; extra == "all"
98
+ Provides-Extra: cloud
99
+ Requires-Dist: asyncpg>=0.29.0; extra == "cloud"
100
+ Requires-Dist: motor>=3.3.0; extra == "cloud"
101
+ Requires-Dist: beanie>=1.24.0; extra == "cloud"
102
+ Requires-Dist: google-cloud-firestore>=2.16.0; extra == "cloud"
103
+ Requires-Dist: aiosqlite>=0.20.0; extra == "cloud"
104
+
105
+ # Kaira ⚡
106
+
107
+ **Automated FastAPI scaffolding CLI** — generate complete 5-layer backend pipelines from model definitions.
108
+
109
+ ```
110
+ kaira generate model User --fields "username:str, email:str, age:int"
111
+ ```
112
+
113
+ In one command, Kaira generates:
114
+
115
+ | Layer | File | Description |
116
+ |-------|------|-------------|
117
+ | Model | `models/user.py` | SQLAlchemy ORM with typed columns |
118
+ | Repository | `repositories/user_repository.py` | CRUD data access layer |
119
+ | Schema | `schemas/user_schema.py` | Pydantic v2 Base/Create/Update/Response |
120
+ | Service | `services/user_service.py` | Business logic with HTTPException handling |
121
+ | Router | `routers/user_router.py` | FastAPI endpoints with Depends injection |
122
+
123
+ ---
124
+
125
+ ## Installation
126
+
127
+ ### Requirements
128
+
129
+ - Python 3.10+
130
+ - pip
131
+
132
+ ### Install from source
133
+
134
+ ```bash
135
+ # Clone or unzip the project
136
+ cd Kaira
137
+
138
+ # Install in editable mode — registers the `kaira` command globally
139
+ pip install -e .
140
+
141
+ # Verify installation
142
+ kaira --version
143
+ kaira --help
144
+ ```
145
+
146
+ ---
147
+
148
+ ## Quick Start
149
+
150
+ ```bash
151
+ # 1. Initialize a new FastAPI project in the current directory
152
+ kaira init
153
+
154
+ # 2. (Optional) Initialize with JWT auth boilerplate
155
+ kaira init --with-auth
156
+
157
+ # 3. Generate a complete 5-layer pipeline
158
+ kaira generate model User --fields "username:str, email:str, age:int"
159
+
160
+ # 4. Generate another model
161
+ kaira generate model Post --fields "title:str, body:str, published:bool"
162
+
163
+ # 5. Add a relationship
164
+ kaira add relation Post --has-many Comment --cascade "all, delete-orphan"
165
+
166
+ # 6. Initialize Alembic and run migrations
167
+ kaira migrate init
168
+ kaira migrate make "initial migration"
169
+ kaira migrate run
170
+
171
+ # 7. Start the server
172
+ uvicorn main:app --reload
173
+ ```
174
+
175
+ ---
176
+
177
+ ## Command Shortcuts & Shell Completion
178
+
179
+ Kaira provides shell tab-completion and a small, curated set of shortcuts for high-frequency daily commands. Shortcuts are strictly additive; long-form commands remain canonical everywhere.
180
+
181
+ ### Shell Tab-Completion
182
+
183
+ Install tab-completion for your current shell (`bash`, `zsh`, `fish`, `PowerShell`):
184
+
185
+ ```bash
186
+ kaira --install-completion
187
+ ```
188
+
189
+ Tab-completion features dynamic model name completion for `generate model`, `sync model`, `test generate`, and `seed run` from `.kaira.json`, as well as completion for `guide` topics.
190
+
191
+ ### Shortcuts Table
192
+
193
+ | Shortcut | Expands to | Description |
194
+ |---|---|---|
195
+ | `g` | `generate model` | Primary scaffolding command |
196
+ | `gb` | `generate bulk` | Bulk scaffolding from JSON |
197
+ | `sm` | `sync model` | Cascade field changes across layers |
198
+ | `mm` | `migrate make` | Create database migration revision |
199
+ | `mr` | `migrate run` | Apply database migrations |
200
+ | `st` | `status` | Live project status snapshot |
201
+ | `up` | `docker up` | Start docker containers |
202
+ | `dn` | `docker down` | Stop docker containers |
203
+ | `ds` | `docker status` | Container status |
204
+ | `q` | `quality` | Full code quality gate |
205
+ | `t` | `test run` | Run test suite |
206
+ | `?` | `menu` | Interactive command palette (`kaira '?'` in zsh) |
207
+
208
+ > **Safety Guarantee**: Destructive commands (`db reset`, `migrate rollback`, `seed clear`, `docker down --volumes`, etc.) **never** have shortcuts and must always be typed in full. Every shortcut echoes its resolved long form before running (suppressed with `--quiet`).
209
+
210
+ ---
211
+
212
+ ## All Commands
213
+
214
+ ### `kaira init`
215
+
216
+ Scaffold a full FastAPI project structure:
217
+
218
+ ```
219
+ project/
220
+ ├── main.py # FastAPI app factory
221
+ ├── database.py # SQLAlchemy engine + session + Base
222
+ ├── models/
223
+ ├── repositories/
224
+ ├── schemas/
225
+ ├── services/
226
+ ├── routers/
227
+ ├── tests/
228
+ ├── docs/
229
+ ├── alembic/
230
+ ├── .env.example
231
+ ├── .gitignore
232
+ ├── Dockerfile
233
+ ├── requirements.txt
234
+ └── .kaira.json # Kaira project config
235
+ ```
236
+
237
+ ```bash
238
+ kaira init
239
+ kaira init --with-auth # Adds auth.py with JWT boilerplate
240
+ ```
241
+
242
+ ---
243
+
244
+ ## Phase 3: Project Wizard, Database Modes, and Security Defaults
245
+
246
+ Phase 3 expands `kaira init` into a named project scaffold with database-aware templates,
247
+ auth boilerplate, Docker/CI options, logging, security middleware, and generated project docs.
248
+
249
+ ```bash
250
+ # Interactive wizard
251
+ kaira init
252
+
253
+ # Non-interactive project creation
254
+ kaira init myproject --db sqlite --auth jwt --docker --ci github
255
+ kaira init myproject --db postgresql --auth none --no-docker --ci none
256
+ kaira init myproject --db mongodb --auth api-key --docker --ci gitlab
257
+ ```
258
+
259
+ Supported database modes:
260
+
261
+ | `--db` | Generated database layer |
262
+ |--------|---------------------------|
263
+ | `sqlite` | Async SQLAlchemy + aiosqlite |
264
+ | `postgresql` | Async SQLAlchemy + asyncpg |
265
+ | `mysql` | Async SQLAlchemy + aiomysql |
266
+ | `mongodb` | Motor + Beanie ODM |
267
+
268
+ Supported auth modes:
269
+
270
+ | `--auth` | Generated auth layer |
271
+ |----------|----------------------|
272
+ | `jwt` | JWT routes, dependencies, schemas, token utilities |
273
+ | `oauth2` | OAuth2 boilerplate |
274
+ | `api-key` | API-key dependency boilerplate |
275
+ | `none` | No auth scaffold |
276
+
277
+ Phase 3 projects include:
278
+
279
+ - `core/database.py` selected for the configured database
280
+ - `core/logger.py` with Loguru setup
281
+ - `middleware/security.py` for CORS, headers, request logging, and exception handlers
282
+ - `rate_limit.py` with SlowAPI limiter setup
283
+ - `.env`, `.env.development`, `.env.staging`, `.env.production`, and `.env.example`
284
+ - generated `pyproject.toml`, `README.md`, `.gitignore`, and optional Docker/CI files
285
+
286
+ ### `kaira guide`
287
+
288
+ Use the built-in guides for copy-pasteable examples:
289
+
290
+ ```bash
291
+ kaira guide
292
+ kaira guide init
293
+ kaira guide generate
294
+ kaira guide db
295
+ kaira guide config
296
+ kaira guide export
297
+ ```
298
+
299
+ ### Database-aware generation
300
+
301
+ `kaira generate` reads `.kaira.json` and switches templates based on `db_type`:
302
+
303
+ - `sqlite`, `postgresql`, `mysql` use SQLAlchemy models plus async repositories.
304
+ - `mongodb` uses Beanie document models plus MongoDB repositories.
305
+
306
+ ```bash
307
+ kaira config set db_type postgresql
308
+ kaira config set auth_type jwt
309
+ kaira config set api_version v2
310
+ kaira generate model User --fields "username:str, email:str"
311
+ ```
312
+
313
+ Routers generated inside a Phase 3 project are registered in `main.py` under the configured API prefix.
314
+
315
+ ---
316
+
317
+ ### `kaira generate`
318
+
319
+ #### Generate full pipeline
320
+
321
+ ```bash
322
+ kaira generate model <ModelName> --fields "<field_definitions>"
323
+
324
+ # Examples
325
+ kaira generate model User --fields "username:str, email:str, age:int"
326
+ kaira generate model Product --fields "name:str, price:float, in_stock:bool"
327
+ kaira generate model Event --fields "title:str, start_at:datetime, description:Optional[str]"
328
+
329
+ # Complexity tiers
330
+ kaira generate model User --fields "name:str" --tier simple # model + schema + router only
331
+ kaira generate model User --fields "name:str" --tier full # all 5 layers (default)
332
+
333
+ # Force overwrite without prompting
334
+ kaira generate model User --fields "name:str" --force
335
+ ```
336
+
337
+ #### Supported field types
338
+
339
+ | Type | SQLAlchemy | Python |
340
+ |------|-----------|--------|
341
+ | `str` | `String` | `str` |
342
+ | `int` | `Integer` | `int` |
343
+ | `float` | `Float` | `float` |
344
+ | `bool` | `Boolean` | `bool` |
345
+ | `datetime` | `DateTime` | `datetime` |
346
+ | `Optional[str]` | `String(nullable=True)` | `Optional[str]` |
347
+ | `Optional[int]` | `Integer(nullable=True)` | `Optional[int]` |
348
+ | `Optional[float]` | `Float(nullable=True)` | `Optional[float]` |
349
+ | `Optional[bool]` | `Boolean(nullable=True)` | `Optional[bool]` |
350
+ | `Optional[datetime]` | `DateTime(nullable=True)` | `Optional[datetime]` |
351
+
352
+ #### Generate single layers
353
+
354
+ ```bash
355
+ kaira generate router User --fields "name:str"
356
+ kaira generate service User --fields "name:str"
357
+ kaira generate schema User --fields "name:str"
358
+ kaira generate repository User --fields "name:str"
359
+ ```
360
+
361
+ #### Bulk generation from JSON
362
+
363
+ ```bash
364
+ kaira generate bulk models.json
365
+ kaira generate bulk models.json --force
366
+ ```
367
+
368
+ **models.json format:**
369
+
370
+ ```json
371
+ [
372
+ {
373
+ "name": "User",
374
+ "fields": {
375
+ "username": "str",
376
+ "email": "str",
377
+ "age": "int"
378
+ }
379
+ },
380
+ {
381
+ "name": "Post",
382
+ "fields": {
383
+ "title": "str",
384
+ "body": "str"
385
+ },
386
+ "relations": [
387
+ { "type": "many-to-one", "target": "User" }
388
+ ],
389
+ "tier": "full"
390
+ }
391
+ ]
392
+ ```
393
+
394
+ ---
395
+
396
+ ### `kaira add`
397
+
398
+ #### Add relationships
399
+
400
+ ```bash
401
+ # One-to-many (Post has many Comments)
402
+ kaira add relation Post --has-many Comment --cascade "all, delete-orphan"
403
+
404
+ # Many-to-one (Post belongs to User)
405
+ kaira add relation Post --has-one User
406
+
407
+ # Many-to-many (Post has many Tags)
408
+ kaira add relation Post --many-to-many Tag
409
+ ```
410
+
411
+ Appends the relationship code directly to the existing model file.
412
+
413
+ ---
414
+
415
+ ### `kaira migrate`
416
+
417
+ ```bash
418
+ kaira migrate make "msg" # New migration (runs: alembic revision --autogenerate -m "msg")
419
+ kaira migrate run # Apply migrations (runs: alembic upgrade head)
420
+ kaira migrate rollback # Revert last migration (runs: alembic downgrade -1)
421
+ kaira migrate init # Initialize Alembic (runs: alembic init alembic)
422
+ ```
423
+
424
+ > **Note:** Kaira provides a **zero-configuration** migration workflow. You do not need to run `kaira migrate init` or manually configure `alembic/env.py`. Running any migration command (`make`, `run`, or `rollback`) automatically initializes and pre-configures Alembic behind the scenes if it hasn't been set up yet.
425
+
426
+ ---
427
+
428
+ ### `kaira db`
429
+
430
+ Database verification, diagnostics, and schema/table structure inspection:
431
+
432
+ ```bash
433
+ kaira db create # Auto-provision the database (detect server, create DB, wire DSN)
434
+ kaira db status # Display active DB type, connection URL, and login status
435
+ kaira db connect # Perform a real database login check & verification query
436
+ kaira db info # List all tables & column counts (or collections & doc counts)
437
+ kaira db shell # Launch an interactive database shell (psql, mysql, sqlite3)
438
+ kaira db backup # Backup active database to a SQL dump/file
439
+ kaira db restore <file> # Restore active database from a SQL dump/file
440
+ kaira db reset # Drop and recreate the database (destructive)
441
+ kaira db switch <type> # Switch DB type (routes cloud providers to cloud connect)
442
+ kaira db benchmark # Time connection/query latency
443
+ ```
444
+
445
+ *(10 commands total.)*
446
+
447
+ > **Note:** All database commands dynamically resolve the active connection URL from your environment profile (e.g. `.env.development`) and fall back to your default local SQLite configuration if no credentials are provided. Connection URLs and driver error messages are always credential-masked (`user:****@host`).
448
+
449
+ ---
450
+
451
+ ### `kaira sync model`
452
+
453
+ Cascade a model's field changes across all five layers — the *continuous* half of continuous scaffolding. Add a field once and schema + router regenerate to match; the service layer is flagged (never auto-rewritten):
454
+
455
+ ```bash
456
+ kaira sync model User --fields "phone:str, verified:bool" # add fields inline
457
+ kaira sync model User # detect hand-edits to models/user.py
458
+ kaira sync model User --dry-run # preview the per-layer plan
459
+ kaira sync model --all # sync every registered model
460
+ ```
461
+
462
+ | Layer | Action |
463
+ |---|---|
464
+ | Model | Apply field changes (overwrite with confirm) |
465
+ | Schema | Regenerate — mirrors model fields |
466
+ | Router | Regenerate — re-point schema references |
467
+ | Repository | Untouched |
468
+ | Service | Flagged for manual review — never auto-rewritten |
469
+
470
+ > Removed fields require a typed confirmation (never silently dropped). After a relational sync, run `kaira migrate make "sync <model>"`.
471
+
472
+ ---
473
+
474
+ ### `kaira env audit` / `kaira env prune`
475
+
476
+ Keep `.env` files lean — audit every key against enabled features, then prune the ones for features you never turned on:
477
+
478
+ ```bash
479
+ kaira env audit # table: key · owning feature · referenced in code? · keep/unused
480
+ kaira env prune # remove unused-feature keys from all .env.* files (typed confirm)
481
+ ```
482
+
483
+ > Core keys (`DATABASE_URL`, `APP_ENV`, …) and any key referenced in your code are never pruned. `env prune` is blocked when `APP_ENV=production`.
484
+
485
+ ---
486
+
487
+ ### `kaira info`
488
+
489
+ Show current project configuration and all tracked models:
490
+
491
+ ```bash
492
+ kaira info
493
+ ```
494
+
495
+ ---
496
+
497
+ ### `kaira check`
498
+
499
+ Show what files would be overwritten without writing anything:
500
+
501
+ ```bash
502
+ kaira check
503
+ ```
504
+
505
+ ---
506
+
507
+ ### `kaira diff`
508
+
509
+ Show a colored unified diff between existing and freshly generated files:
510
+
511
+ ```bash
512
+ kaira diff User
513
+ kaira diff User --layer router
514
+ kaira diff User --fields "username:str, email:str, bio:Optional[str]"
515
+ ```
516
+
517
+ ---
518
+
519
+ ### `kaira list`
520
+
521
+ ```bash
522
+ kaira list models # List all files in models/
523
+ kaira list routes # List all router files and their endpoints
524
+ ```
525
+
526
+ ---
527
+
528
+ ### `kaira docs`
529
+
530
+ AI-powered documentation generation (requires API key):
531
+
532
+ ```bash
533
+ kaira docs generate # Generate docs for all models → docs/api.md
534
+ kaira docs generate User # Generate docs for one model → docs/User.md
535
+ ```
536
+
537
+ **Configure AI provider:**
538
+
539
+ ```bash
540
+ kaira config set ai_provider openai # or: anthropic
541
+ kaira config set ai_model gpt-4o
542
+ kaira config set ai_api_key_env OPENAI_API_KEY
543
+ ```
544
+
545
+ Set your API key in `.env`:
546
+
547
+ ```bash
548
+ OPENAI_API_KEY=sk-...
549
+ # or
550
+ ANTHROPIC_API_KEY=sk-ant-...
551
+ ```
552
+
553
+ If no API key is set, Kaira generates a basic Markdown doc without AI.
554
+
555
+ ---
556
+
557
+ ### `kaira config`
558
+
559
+ ```bash
560
+ kaira config show # Display full config
561
+ kaira config get default_tier # Get a value
562
+ kaira config set default_tier simple # Set a value
563
+ kaira config set models_dir app/models # Change output directories
564
+ ```
565
+
566
+ **Settable keys:**
567
+
568
+ | Key | Default | Description |
569
+ |-----|---------|-------------|
570
+ | `output_dir` | `.` | Root output directory |
571
+ | `models_dir` | `models` | Models directory |
572
+ | `repositories_dir` | `repositories` | Repositories directory |
573
+ | `schemas_dir` | `schemas` | Schemas directory |
574
+ | `services_dir` | `services` | Services directory |
575
+ | `routers_dir` | `routers` | Routers directory |
576
+ | `default_tier` | `full` | Default complexity tier |
577
+ | `ai_provider` | `openai` | AI documentation provider |
578
+ | `ai_model` | `gpt-4o` | AI model to use |
579
+ | `ai_api_key_env` | `OPENAI_API_KEY` | Env var for API key |
580
+ | `db_type` | `sqlite` | Database engine (`postgresql`/`mysql`/`mongodb`/`sqlite`) |
581
+ | `api_version` | `v1` | API version prefix |
582
+ | `auth_type` | `none` | Auth scaffold (`jwt`/`oauth2`/`api-key`/`none`) |
583
+ | `db_name` | `""` | Sanitized database identifier (set by provisioning, Phase 6) |
584
+ | `db_provisioned` | `false` | Whether the database has been created/confirmed (Phase 6) |
585
+ | `db_mode` | `online` | Resolved bind mode: `online`/`offline`/`auto` (Phase 6) |
586
+
587
+ The last three fields are written by auto-provisioning (`kaira init` / `kaira db create`) and read by every mode-reporting surface — you normally don't set them by hand.
588
+
589
+ ---
590
+
591
+ ## Phase 4 Commands & Features
592
+
593
+ Phase 4 adds 87 new commands across 14 new functional areas:
594
+
595
+ ### ⚡ Caching (`kaira cache`)
596
+ Redis cache management and route caching:
597
+ - `kaira cache init` — Scaffold `core/cache.py` and register in settings
598
+ - `kaira cache add GET <route> [--ttl 300]` — Add GET route caching
599
+ - `kaira cache clear [<route> | --all]` — Clear cached routes
600
+ - `kaira cache status` — View Redis status and keys
601
+
602
+ ### ⚡ Background Tasks (`kaira task`)
603
+ Scaffold background tasks via Celery:
604
+ - `kaira task init` — Scaffolds celery configurations
605
+ - `kaira task generate <TaskName> [--schedule "<cron>"]` — Scaffolds background task
606
+ - `kaira task list` — List all Celery tasks
607
+ - `kaira task run <TaskName>` — Run background task immediately
608
+ - `kaira task monitor` — Open Flower dashboard
609
+
610
+ ### ⚡ Third-Party Integrations (`kaira integrate`)
611
+ Scaffold 15 integration providers across 6 categories:
612
+ - `kaira integrate --provider <category>/<provider>` (e.g. `email/sendgrid`, `payment/stripe`, `storage/s3`, `monitor/sentry`, etc.)
613
+ - `kaira integrate list` — View all available integration options
614
+
615
+ ### ⚡ API Inspection & client generation (`kaira api`)
616
+ - `kaira api export [--format json|yaml]` — Save OpenAPI spec
617
+ - `kaira api validate` — Validate local OpenAPI spec
618
+ - `kaira api list` — List all endpoints
619
+ - `kaira api test <METHOD> <route>` — Send test request to local server
620
+ - `kaira api postman` — Generate Postman collection
621
+ - `kaira api client [--lang typescript|javascript]` — Scaffolds client SDK
622
+
623
+ ### ⚡ Profiling & Loadtesting (`kaira profile` & `kaira loadtest`)
624
+ - `kaira profile run <METHOD> <route>` — Trace route response latency (p50/p95/p99)
625
+ - `kaira profile report` — View last profile run
626
+ - `kaira loadtest run <METHOD> <route>` — Perform concurrent load test (localhost-only safety lock)
627
+
628
+ ### ⚡ Deployment Configs (`kaira deploy`)
629
+ - `kaira deploy generate --platform <platform>` — Scaffold Render/Railway/Fly/VPS configs
630
+ - `kaira deploy checklist` / `kaira deploy check` — Deploy readiness audit
631
+ - `kaira deploy run --platform <platform>` — Trigger deployment (requires passing checklist)
632
+
633
+ ### ⚡ Scaffolding Layers (`kaira middleware`, `kaira event`, `kaira flags`, `kaira health-endpoint`)
634
+ - `kaira middleware add <MiddlewareName>` — Scaffold Starlette middleware
635
+ - `kaira event generate <startup|shutdown>` — Scaffold lifespan hooks
636
+ - `kaira flags add <flag_name>` — Scaffold feature flag toggle
637
+ - `kaira health-endpoint generate` — Scaffold unauthenticated /health route
638
+
639
+ ---
640
+
641
+ ## Docker (`kaira docker`)
642
+
643
+ Docker configuration is **reactive to project state**. The compose services and
644
+ the Dockerfile's system build dependencies are rendered from `.kaira.json`, so
645
+ enabling a subsystem changes what Docker generates — no hand-editing, no
646
+ re-running `init` and losing your setup.
647
+
648
+ | Project state | Docker reacts |
649
+ | --- | --- |
650
+ | `db_type: postgresql` / `supabase` | Builder stage gets `gcc libpq-dev` |
651
+ | `db_type: mysql` | Builder stage gets `gcc default-libmysqlclient-dev pkg-config` |
652
+ | `db_type: mongodb` / `atlas` / `sqlite` / `firebase` | No system build deps at all — the `apt-get` layer is omitted |
653
+ | `db_type: postgresql` / `mysql` / `mongodb` | Compose gets a database service with a healthcheck and a named volume |
654
+ | `db_type: sqlite` / `supabase` / `atlas` / `firebase` | No database service — file-based or cloud-hosted |
655
+ | `cache_enabled: true` | Compose gets Redis with a healthcheck |
656
+ | `task_enabled: true` | Compose gets a Celery worker plus the Redis broker |
657
+ | `search_provider: elasticsearch` / `meilisearch` | Compose gets that search engine with a healthcheck and volume |
658
+ | Any integration SDK | Lands in `requirements.txt` — pip installs it during build, no Dockerfile change |
659
+
660
+ ### Commands
661
+
662
+ ```bash
663
+ # Scaffold
664
+ kaira docker init --with-compose --python 3.12 # --python accepts 3.10–3.13
665
+ kaira docker sync # regenerate from current state
666
+ kaira docker sync --dry-run # show the diff, write nothing
667
+
668
+ # Build and run a single container
669
+ kaira docker build --tag myapp # spinner, image size, smart errors
670
+ kaira docker build --verbose # full Docker output
671
+ kaira docker run --tag myapp # --init, --read-only, no-new-privileges
672
+
673
+ # Compose lifecycle
674
+ kaira docker up # dev stack + .env.development
675
+ kaira docker up --prod --build # prod stack (typed confirmation)
676
+ kaira docker down # stop containers, remove network
677
+ kaira docker down --volumes # also destroy data (typed confirm)
678
+ kaira docker status # health, ports, image + volume size
679
+
680
+ # Security
681
+ kaira docker scan --fix # exits 1 on HIGH/CRITICAL
682
+ ```
683
+
684
+ `kaira docker up` picks the right compose file and env file for the environment;
685
+ `kaira docker scan` auto-detects `docker scout`, `trivy`, or `grype` (in that
686
+ order), renders a severity-sorted table, and scans local images only unless you
687
+ pass `--remote`.
688
+
689
+ ### Staying in sync
690
+
691
+ Commands that change project state — `cache init`, `task init`, `integrate`,
692
+ `db switch`, `cloud connect` — offer to regenerate the Docker files when they
693
+ detect drift. Pass `--quiet` to skip the prompt in CI; you then run
694
+ `kaira docker sync` yourself.
695
+
696
+ ### What the generated Dockerfile guarantees
697
+
698
+ Multi-stage build; base image pinned to a full patch version; `--user` pip
699
+ install copied into the runtime stage; `--no-install-recommends` with
700
+ same-layer apt cleanup; `--no-cache-dir` on pip; dependency manifest copied
701
+ before source for layer caching; non-root `addgroup --system` user; in-image
702
+ `HEALTHCHECK` using stdlib `urllib` (so `curl` is never installed); exec-form
703
+ `CMD`; `EXPOSE` as a documentation contract; and a comprehensive
704
+ `.dockerignore` that keeps `.env` out while explicitly allowing `.env.example`.
705
+
706
+ Production compose adds `read_only`, a size-capped `tmpfs`, `no-new-privileges`,
707
+ `json-file` log rotation, resource limits, and keeps database, cache, and search
708
+ ports off the host.
709
+
710
+ ---
711
+
712
+ ## Phase 6: Auto DB Provisioning, `run` Overhaul & Offline/Online Engine
713
+
714
+ ### Auto database provisioning
715
+
716
+ `kaira init` no longer stops at scaffolding — it provisions the actual database. It detects a local database **server** (never a GUI client like pgAdmin/Compass), creates a database named after the project, and wires the DSN into `.env.development`:
717
+
718
+ ```bash
719
+ kaira init proj9 --db postgresql # provision as part of init
720
+ kaira db create # standalone: provision for current project
721
+ kaira db create --name customdb # override the derived name
722
+ kaira db create --skip # scaffold the DSN only, don't touch the server
723
+ ```
724
+
725
+ - **Passwordless-first.** Trust/socket/env auth connects with no prompt. Only if the server rejects auth are you asked for a password — masked, retried up to 3×, blank = skip.
726
+ - **Secrets stay put.** An entered password is written **only** to `.env.development` (git-ignored) and masked in every printed connection string and driver error.
727
+ - **Always completes.** No server reachable, or you skip the password? Kaira falls back to offline SQLite at `./.kaira/offline.db` and records `DB_MODE=offline` — explicitly, never silently.
728
+ - **Profiles.** `--profile solo` (default) auto-creates; `standard` confirms first; `scale` never auto-creates (managed DB assumed).
729
+ - Project names are sanitized to valid DB identifiers (validated against `^[a-z_][a-z0-9_]*$` before any DDL) and stored as `db_name`.
730
+
731
+ ### Offline / Online engine (Layer 1)
732
+
733
+ The app binds exactly **one** database at startup, governed by two independent dials:
734
+
735
+ - `DB_MODE` = `online` (default) · `offline` · `auto` — which database binds. Default is **online** on purpose: a transient blip must never silently divert writes onto a throwaway database. Opt into `auto` for a dev-time swap.
736
+ - `FALLBACK_MODE` = `off` (default) — runtime resilience (Layers 2/3) is specified but **not built** this release.
737
+
738
+ **Which DB am I on?** Reported identically on five surfaces from one resolved value — `kaira run` banner, `GET /health` (`database` block, no DSN), the `X-Kaira-DB-Mode` response header, `kaira status`, and the welcome dashboard. The offline store matches your data model: SQLite for relational, a local MongoDB namespace for Mongo (never SQLite).
739
+
740
+ ### Cleaner `kaira run`
741
+
742
+ - SQL echo is **off by default** — `kaira run --sql` (or `--verbose`) surfaces it for a single run.
743
+ - A Loguru `InterceptHandler` unifies uvicorn + SQLAlchemy logging into one format and sink.
744
+ - The launch banner shows the database engine, name, and online/offline mode.
745
+ - **A taken port is not an error.** Port 8000 is the FastAPI default, so it is also the port another project is most likely holding. `kaira run` binds the next free one and says so:
746
+
747
+ ```
748
+ Port 8001 moved from 8000 — another server is on it
749
+ URL http://127.0.0.1:8001
750
+ ```
751
+
752
+ The check binds rather than connects — "is something listening" and "can I listen here" are different questions, and only the second decides whether the server starts. The scan is bounded to 20 consecutive ports. Pass `--strict-port` when the number is part of a contract (an OAuth callback, a proxy, a published container port) and it fails cleanly instead of moving.
753
+
754
+ The bound address is recorded in `.kaira/runtime.json` while the server runs, so `kaira api`, `status`, `profile`, `loadtest`, `monitor` and the welcome dashboard follow it off 8000 instead of assuming the default.
755
+
756
+ See `kaira guide db-provision` and `kaira guide offline` for full walkthroughs.
757
+
758
+ ---
759
+
760
+ ## Phase 7: Data Export (`kaira export`)
761
+
762
+ Getting data **out** — for you at the terminal, and for the users of the app you scaffolded. Two trust boundaries, one serialization pipeline in `core/export.py`, so neither side can end up with a weaker rule than the other.
763
+
764
+ ### `kaira export data` — your own pull (CLI)
765
+
766
+ ```bash
767
+ kaira export data User --format xlsx
768
+ kaira export data User --format pdf --limit 500
769
+ kaira export data User --format docx --fields "username,email,created_at"
770
+ kaira export data User --format xlsx --filter "status:active,role:admin"
771
+ kaira export data User --format xlsx --output ./reports/users.xlsx
772
+
773
+ kaira export data --all --format xlsx # one workbook, one sheet per model
774
+ kaira export data --all --format pdf # one file per model
775
+ ```
776
+
777
+ - Rows stream in batches (`LIMIT`/`OFFSET` on SQL, cursor batching on Mongo) — a table larger than RAM exports fine with or without `--limit`.
778
+ - Output defaults to `./exports/<model>_<timestamp>.<ext>`; `exports/` is created and added to `.gitignore` automatically, because an export file *is* customer data sitting in the working tree.
779
+ - `--filter` uses the same `key:value` grammar as the rest of Kaira. Equality only — operators are out of scope.
780
+
781
+ ### `kaira export add` — self-serve endpoint (generated API)
782
+
783
+ ```bash
784
+ kaira auth add-guard User # required first — no unguarded exports
785
+ kaira export add User --format xlsx
786
+ kaira export add Order --format all # xlsx + pdf + docx
787
+ kaira export list
788
+ kaira export remove User
789
+ ```
790
+
791
+ Generates into the model's **existing** router and service — no new layer:
792
+
793
+ ```
794
+ GET /api/v1/users/export?format=xlsx
795
+ ```
796
+
797
+ - **Auth-gated by default, no opt-out.** `kaira export add` refuses to run on an unguarded model and points you at `kaira auth add-guard`.
798
+ - Rate-limited via `settings.EXPORT_RATE_LIMIT` (default `5/minute`, tighter than a normal GET because one call reads a whole table). The setting is injected into `config/settings.py` on first `export add`, so pre-Phase-7 projects get it too.
799
+ - `StreamingResponse`, serialized to a temp file *before* the response starts — a failure returns a real 500 instead of truncating a `200 OK` mid-download.
800
+ - Response carries `X-Kaira-Export-Format`, matching the `X-Kaira-DB-Mode` header pattern.
801
+ - Raw exception details never reach the client; they go to Loguru and the client gets a generic 500.
802
+ - `kaira export remove` deletes the endpoint **and its imports** — marker-delimited blocks, so nothing is left orphaned.
803
+
804
+ ### What is never exported
805
+
806
+ Any field whose name contains `password`, `hashed_password`, `token`, `secret`, or `api_key` is stripped from every file, in every format, on both paths. There is no flag to keep them, and they are rejected as `--filter` keys too — an equality filter against a hash is a guessing oracle.
807
+
808
+ `kaira export data --all` against `APP_ENV=production` requires you to type the project name, and `--force` does not buy you past it.
809
+
810
+ See `kaira guide export` for the full walkthrough.
811
+
812
+ ---
813
+
814
+ ## Monitoring (`kaira monitor`)
815
+
816
+ Runtime monitoring for a generated project — metrics, Kubernetes-style probes, a
817
+ self-hosted mini dashboard, and threshold alerts. No infrastructure, no accounts,
818
+ no Prometheus stack to stand up: everything below runs inside the app you already
819
+ have.
820
+
821
+ Entirely opt-in. A project that never runs `kaira monitor init` is byte-for-byte
822
+ what it was before.
823
+
824
+ ```bash
825
+ kaira monitor init # metrics + probes
826
+ kaira monitor init --dashboard --auth token # and the mini dashboard
827
+ kaira monitor status # configured + live self-check
828
+ kaira monitor watch # alert when a threshold trips
829
+ kaira monitor diff --since yesterday # compare two snapshots
830
+ ```
831
+
832
+ ### What `init` adds
833
+
834
+ | Route | Purpose | Auth |
835
+ |---|---|---|
836
+ | `GET /metrics` | Prometheus exposition — request counts, latency histogram, errors | none (scrapers have no credentials) |
837
+ | `GET /healthz` | Liveness — process is up. Checks nothing external | none |
838
+ | `GET /readyz` | Readiness — dependencies reachable, `503` when not | none |
839
+ | `GET /_kaira/monitor` | Mini dashboard (opt-in) | **required** |
840
+ | `GET /_kaira/monitor/data` | JSON the dashboard polls | **required** |
841
+
842
+ **`/health` is not touched.** Phase 4 owns it, Docker's `HEALTHCHECK` points at
843
+ it, and it behaves exactly as before. The probes are added *beside* it, because
844
+ "is the process alive" and "can this instance serve traffic" are different
845
+ questions — answering both with one endpoint is how a database blip gets your
846
+ healthy process restarted.
847
+
848
+ The metrics middleware registers **after** the security middleware and reads the
849
+ duration that middleware already computed for `X-Response-Time`. One stopwatch
850
+ per request, and CORS/security headers keep the position they have always had.
851
+
852
+ Metric labels use the **route template** (`/api/v1/users/{uuid}`), never the
853
+ concrete path. A label per resource id is unbounded cardinality — it takes down
854
+ the metrics backend before it tells you anything.
855
+
856
+ ### The mini dashboard
857
+
858
+ Off by default and not switchable to public:
859
+
860
+ - `KAIRA_MONITOR_ENABLED=true` is required, or both routes return `404` — the
861
+ same answer an unmounted path gives.
862
+ - An auth strategy is required: reuse the project's own guard, or a bearer token
863
+ in `KAIRA_MONITOR_TOKEN` (generated for you, 32+ chars, constant-time compare).
864
+
865
+ Unlike `/health`, this page reports which routes are hot, which are failing, how
866
+ many auth attempts are being rejected, and how close the database is to its plan
867
+ limit. That is a map of a system's soft spots.
868
+
869
+ > **Scope: single worker.** The dashboard's metrics are in-memory and
870
+ > per-process. Under one uvicorn worker they are the whole truth; under
871
+ > `gunicorn -w 4` you are looking at whichever worker answered the request —
872
+ > roughly a quarter of your traffic, not a quarter-scale copy of it. `/metrics`
873
+ > has the same property, and that is fine: a scraper hits every replica and
874
+ > aggregates. Cross-worker aggregation needs a shared backend and is deliberately
875
+ > not built.
876
+
877
+ ### What only Kaira can show you
878
+
879
+ Because Kaira owns the model → router pipeline and the command history:
880
+
881
+ - **Model activity** — traffic and errors per *model*, not per URL prefix.
882
+ - **Change markers** — `migrate run`, `sync model`, `deploy run` from
883
+ `.kaira/history.jsonl`, drawn on the latency timeline. "Latency jumped right
884
+ after this migration" becomes visible instead of inferred.
885
+ - **Self-baseline anomalies** — a route flagged only against its own 7-day p95,
886
+ so a legitimately slow route never trips the flag by being slow. No ML, no
887
+ external service.
888
+ - **Security feed** — the 401/403/429 your auth guard and slowapi already
889
+ return, counted. Not a new detection system.
890
+ - **Storage runway** — a periodic database-size query and a linear projection:
891
+ *"at current growth, ~19 days to your plan's storage limit."* Set
892
+ `KAIRA_STORAGE_LIMIT_MB` to get a date.
893
+
894
+ ### Structured logs
895
+
896
+ ```bash
897
+ KAIRA_LOG_FORMAT=json # one JSON object per line, on stdout
898
+ ```
899
+
900
+ That is how Railway, Render, Fly and CloudWatch ingest logs — they capture the
901
+ process's stdout. **Kaira never writes a log file**, and this does not change
902
+ that: it is a formatter switch on the sink that was already there.
903
+
904
+ ### Third-party providers
905
+
906
+ `kaira integrate --provider monitor/sentry|datadog|newrelic` now actually calls
907
+ the SDK's `init()` in your lifespan, instead of only installing the package and
908
+ writing env keys.
909
+
910
+ Sampling is cost-conscious because these are metered services: traces at `0.2` in
911
+ production and `1.0` in development, via `settings.MONITOR_TRACES_SAMPLE_RATE`
912
+ rather than a hardcoded call-site value. Errors are never sampled. A missing
913
+ credential logs one line and boots normally — an observability tool must never be
914
+ the reason a service fails to start.
915
+
916
+ Nothing in the three tiers above needs a provider account.
917
+
918
+ See `kaira guide monitor` for the full walkthrough, or
919
+ [`docs/MONITORING_USAGE.md`](docs/MONITORING_USAGE.md) for a command-by-command
920
+ reference.
921
+
922
+ ---
923
+
924
+
925
+ ## Change Detection
926
+
927
+ Kaira **never silently overwrites** files. When a file already exists:
928
+
929
+ ```
930
+ ┌─ File Conflict ──────────────────────────────────────────────────┐
931
+ │ ⚠ File already exists: models/user.py │
932
+ │ Choose an action: │
933
+ │ o — overwrite │
934
+ │ s — skip │
935
+ │ d — show diff │
936
+ └──────────────────────────────────────────────────────────────────┘
937
+ Your choice [o/s/d] (s):
938
+ ```
939
+
940
+ Use `--force` to bypass prompts and always overwrite.
941
+
942
+ ---
943
+
944
+ ## Phase 7.5 Presentation & Discovery
945
+
946
+ ### Command Index (`kaira commands`)
947
+
948
+ Scan or filter all registered commands without executing anything:
949
+
950
+ ```bash
951
+ kaira commands # View all commands grouped by category
952
+ kaira commands --group db # Show only database commands
953
+ kaira commands --search export # Search across names & descriptions
954
+ ```
955
+
956
+ ### Brand Banner
957
+
958
+ Kaira has exactly two banners, and they do different jobs.
959
+
960
+ | Banner | Job | Where | Frequency |
961
+ |---|---|---|---|
962
+ | **Large** | First impression — ceremony for the moment a project starts | `kaira init` only | Once per project, ever |
963
+ | **Small** | Wayfinding — quiet identity that doubles as a divider | bare `kaira`, `--version`, `about`, `commands` | Many times per day |
964
+
965
+ The large banner is block art: a five-row lockup composited with a dim shadow
966
+ offset one row down and one column right, over the tagline
967
+ `Continuous model-level FastAPI scaffolding`. The small banner is a single line
968
+ — `⚡ kaira ────… v0.1.0` — whose rule stretches to fill the gap between the
969
+ mark and the version, capped at 80 columns.
970
+
971
+ Every other command gets **no banner**. Neither appears under `--quiet`, and
972
+ neither is ever printed twice in one invocation.
973
+
974
+ Four-tier degradation, resolved once per invocation:
975
+
976
+ | Tier | Condition | Output |
977
+ |---|---|---|
978
+ | 1 | `kaira init`, width ≥ 44, colour, UTF-8 | Large banner **with** shadow |
979
+ | 2 | `kaira init`, width ≥ 40, UTF-8, no colour (or `NO_COLOR`) | Large banner, **flat** main layer |
980
+ | 3 | Width < 40, non-TTY, or a small-banner surface | Small banner |
981
+ | 4 | UTF-8 unavailable | `kaira v0.1.0` — plain ASCII |
982
+
983
+ Piped output never gets block art: `kaira init > log.txt` writes a readable
984
+ log, not 200 block characters. Below a width threshold the banner drops a tier
985
+ rather than clipping, wrapping, or scaling.
986
+
987
+ ### Welcome Dashboard (bare `kaira`)
988
+
989
+ Running `kaira` with no arguments inside a project opens as an overview, not a
990
+ report. A headline names the project and its connection state, a **setup meter**
991
+ answers how far along it is before anything is read, and the checks beneath are
992
+ the detail behind that fraction:
993
+
994
+ ```
995
+ ⚡ kaira ───────────────────────────────────────────────────────────────────────
996
+
997
+ proj29 ● online
998
+ api v1 · postgresql · proj29
999
+
1000
+ setup ████████████████░░░░ 4/5
1001
+ ✓ connection online · connected · localhost:5432
1002
+ ✓ auth setup jwt · configured
1003
+ ✓ docker Dockerfile present
1004
+ ! migrations not initialized
1005
+ ✓ ci github
1006
+ ✓ server http://127.0.0.1:8001
1007
+
1008
+ resources
1009
+ ────────────────────────────────────────────
1010
+ models 5 · routers 5 · tests 0
1011
+ last action generate model User · 2026-08-04
1012
+
1013
+ action required
1014
+ ────────────────────────────────────────────
1015
+ → kaira migrate init
1016
+
1017
+ next
1018
+ ────────────────────────────────────────────
1019
+ → kaira generate model <Name> --fields "field:type"
1020
+ → kaira run
1021
+ → kaira commands
1022
+ ```
1023
+
1024
+ The meter and the *action required* list come from one checklist, so the count
1025
+ and the commands cannot disagree. The `server` line is only present when one is
1026
+ running, and reports the address it actually bound — which is not always 8000.
1027
+
1028
+ In a live terminal the body cascades into place and a highlight sweeps once
1029
+ along the `⚡ kaira` rule. The whole surface is composed before any of it is
1030
+ printed, so a pipe, a log, `CI`, `NO_COLOR`, `--quiet` or `KAIRA_NO_MOTION`
1031
+ receives byte-identical text with no pauses — motion changes the timing, never
1032
+ the output. One 340 ms budget covers the whole invocation and every effect draws
1033
+ from it, so a longer surface animates faster rather than taking longer.
1034
+
1035
+ Outside a project it prints a short "no project here" body pointing at
1036
+ `kaira init`. Help is still one keystroke away via `kaira --help`, and the full
1037
+ index via `kaira commands`.
1038
+
1039
+ ### Output Language
1040
+
1041
+ Every long-running command reads as a sequence of named sections laid out
1042
+ against one content column, inside one gutter — no full-width boxes, no
1043
+ per-command divider styles:
1044
+
1045
+ ```
1046
+ scaffold
1047
+ ────────────────────────────────────────────
1048
+ database postgresql
1049
+ auth jwt
1050
+
1051
+ ✓ project files 412ms
1052
+ ✓ virtualenv .venv · 2.4s
1053
+
1054
+ database · postgresql
1055
+ ────────────────────────────────────────────
1056
+ · detected postgresql localhost:5432
1057
+ ! auth required postgres@localhost:5432 → proj29
1058
+ blank to skip and use offline SQLite
1059
+ ? password ****
1060
+ ✓ created proj29 · user postgres · localhost:5432
1061
+ ✓ credentials .env.development · git-ignored
1062
+
1063
+ ────────────────────────────────────────────
1064
+ ✓ proj29 ready in 84.1s
1065
+ → cd proj29
1066
+ → kaira run
1067
+ ```
1068
+
1069
+ The vocabulary lives in `core/ui.py` — `section`, `step`, `note`, `field`,
1070
+ `subtext`, `hint`, `rule`, plus `headline`, `caption`, `pill`, `meter` and
1071
+ `stats` for surfaces you *land* on rather than read through — and shares its
1072
+ symbols, colours, gutter and rule width with the progress renderer via
1073
+ `core/theme.py`:
1074
+
1075
+ - `✓ ✗ ! ◐ ◌` are **verdicts**; `·` is an **observation** that makes no claim
1076
+ either way; a bare label/value **field** is a setting, not a step; `● ○` is a
1077
+ **pill**, a condition rather than an outcome — the colour says healthy, the
1078
+ shape says live.
1079
+ - Every element comes in two halves: `fmt_step` returns the markup, `step`
1080
+ prints it. Animated surfaces must compose a whole block before any of it
1081
+ reaches the screen, and two spellings of one layout is how two surfaces end
1082
+ up disagreeing about where the value column is.
1083
+ - Labels sit in a fixed column, so values line up down a whole section. The
1084
+ symbol column is padded to a uniform width, which keeps the alignment intact
1085
+ when symbols fall back to `[ok]` / `[x]` on a non-UTF-8 console.
1086
+ - Rules are clamped to the content width and to the terminal, whichever is
1087
+ narrower — a rule stretched across a 200-column window puts the eye a long
1088
+ way from the text it belongs to.
1089
+
1090
+ ### Multi-Step Progress UI
1091
+
1092
+ One shared renderer (`kaira/core/progress.py`) behind `kaira init`, `deps add`,
1093
+ `deps update`, `generate model`, `generate bulk`, `test generate --all`, and
1094
+ `seed run --all`. Every phase is visible from the start, so the shape of the job
1095
+ is clear before it runs:
1096
+
1097
+ ```
1098
+ ⚡ installing · uv · 12 packages
1099
+ ────────────────────────────────────────────
1100
+ ✓ resolve 12 packages · 340ms
1101
+ ✓ download 18.2 MB · 2.1s
1102
+ ◐ install
1103
+ ✓ fastapi 0.115.0
1104
+ ✓ sqlalchemy 2.0.36
1105
+ ◐ pydantic
1106
+ ◌ alembic
1107
+ ◌ +7 more
1108
+ ────────────────────────────────────────────
1109
+ ████████████░░░░░░░░░░░░ 6/12 · 4.8s
1110
+ ```
1111
+
1112
+ - States: `pending ◌` · `active ◐` · `done ✓` · `partial !` · `failed ✗`, each
1113
+ with an ASCII fallback (`.`, `>`, `[ok]`, `[!]`, `[x]`).
1114
+ - The nested list is capped at a fixed height, so the block never grows with the
1115
+ project size.
1116
+ - On full success the detail collapses but the per-phase timings stay — a slow
1117
+ resolve means a dependency conflict, a slow download means the network.
1118
+ - On failure only the failing phase expands, with a short reason and
1119
+ copy-pasteable fix commands.
1120
+ - Under `NO_COLOR`, a pipe, or CI: no animation, no repainting, no cursor codes —
1121
+ one plain line per phase as it resolves, then the summary.
1122
+
1123
+ ### Installer
1124
+
1125
+ `uv` is used when it is on `PATH`, otherwise it falls back to `pip` silently.
1126
+ Either way the full package set goes to a **single** invocation so the resolver
1127
+ can backtrack across the whole dependency graph. Phase and item states come from
1128
+ parsing the installer's real output, never from timers. Raw installer output is
1129
+ never printed: failures are mapped to a short reason (missing PostgreSQL headers,
1130
+ dependency conflict, network unreachable, …) plus a fix command, so index URLs
1131
+ and stack traces cannot leak into the terminal.
1132
+
1133
+ ---
1134
+
1135
+ ## Documentation Generation (`kaira docs`)
1136
+
1137
+ Kaira projects include a deterministic documentation engine that projects internal project state (`.kaira.json`, models, route discovery, and env configuration) directly into markdown reference documents in `./docs`.
1138
+
1139
+ ```bash
1140
+ # Generate complete documentation suite
1141
+ kaira docs generate
1142
+
1143
+ # Check documentation freshness against project state (read-only)
1144
+ kaira docs status
1145
+
1146
+ # Surgically regenerate documentation for a single model (preserves other models)
1147
+ kaira docs generate User
1148
+
1149
+ # Generate specific document only
1150
+ kaira docs generate --only models # docs/models.md
1151
+ kaira docs generate --only endpoints # docs/endpoints.md
1152
+ kaira docs generate --only erd # docs/erd.md
1153
+ kaira docs generate --only config # docs/configuration.md
1154
+
1155
+ # Preview planned changes without writing to disk
1156
+ kaira docs generate --dry-run
1157
+
1158
+ # Specify custom output directory
1159
+ kaira docs generate --output ./documentation
1160
+
1161
+ # Non-interactive CI mode (overwrites silently without prompts)
1162
+ kaira docs generate --quiet
1163
+ ```
1164
+
1165
+ ### Generated Documentation Files
1166
+
1167
+ | File | Content |
1168
+ |---|---|
1169
+ | `docs/README.md` | Navigation index linking all reference docs, project metadata, and pointers to OpenAPI (`kaira api export`) & Postman (`kaira api postman`). |
1170
+ | `docs/models.md` | Complete model reference with field tables, data types, constraints (e.g. `max_length`, `ge`, `email`), nullability, and relationship links. Supports surgical single-model updates. |
1171
+ | `docs/endpoints.md` | Discovered API routes grouped by resource tag, HTTP method, authentication requirements (🔒 Required / Public), cache TTL, and rate limits. |
1172
+ | `docs/erd.md` | Live Mermaid `erDiagram` visualizing entity relationships with exact cardinalities (`||--o{`, `}o--||`, `}o--o{`, `||--||`) for relational databases, or logical document relationships for MongoDB/Atlas/Firestore. |
1173
+ | `docs/configuration.md` | Environment variable reference detailing key names, ownership, requirements, and placeholder formats. **Zero access to live `.env` files** — secrets are never read or stored. |
1174
+
1175
+ ---
1176
+
1177
+ ## Project Structure (Generated)
1178
+
1179
+ ```
1180
+ my-api/
1181
+ ├── main.py
1182
+ ├── database.py
1183
+ ├── auth/
1184
+ ├── models/
1185
+ │ ├── __init__.py
1186
+ │ ├── user.py
1187
+ │ └── post.py
1188
+ ├── repositories/
1189
+ │ ├── user_repository.py
1190
+ │ └── post_repository.py
1191
+ ├── schemas/
1192
+ │ ├── user_schema.py
1193
+ │ └── post_schema.py
1194
+ ├── services/
1195
+ │ ├── user_service.py
1196
+ │ └── post_service.py
1197
+ ├── routers/
1198
+ │ ├── user_router.py
1199
+ │ └── post_router.py
1200
+ ├── tests/
1201
+ ├── docs/
1202
+ │ ├── README.md
1203
+ │ ├── models.md
1204
+ │ ├── endpoints.md
1205
+ │ ├── erd.md
1206
+ │ └── configuration.md
1207
+ ├── alembic/
1208
+ ├── .env
1209
+ ├── .env.example
1210
+ ├── .gitignore
1211
+ ├── Dockerfile
1212
+ ├── requirements.txt
1213
+ └── .kaira.json
1214
+ ```
1215
+
1216
+ ---
1217
+
1218
+ ## Running Tests
1219
+
1220
+ ```bash
1221
+ pip install -e ".[dev]"
1222
+ pytest tests/ -v
1223
+ pytest tests/ --cov=kaira --cov-report=term-missing
1224
+ ```
1225
+
1226
+ ---
1227
+
1228
+ ## Tech Stack
1229
+
1230
+ | Component | Library |
1231
+ |-----------|---------|
1232
+ | CLI | [Typer](https://typer.tiangolo.com/) + [Rich](https://rich.readthedocs.io/) |
1233
+ | Templates | [Jinja2](https://jinja.palletsprojects.com/) |
1234
+ | ORM | [SQLAlchemy 2.x](https://docs.sqlalchemy.org/en/20/) |
1235
+ | Schemas | [Pydantic v2](https://docs.pydantic.dev/) |
1236
+ | API | [FastAPI](https://fastapi.tiangolo.com/) |
1237
+ | Migrations | [Alembic](https://alembic.sqlalchemy.org/) |
1238
+ | AI Docs | OpenAI / Anthropic (via [httpx](https://www.python-httpx.org/)) |
1239
+
1240
+ ---
1241
+
1242
+ ## License
1243
+
1244
+ MIT