fastapi-startkit 0.40.1__tar.gz → 0.42.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 (387) hide show
  1. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/PKG-INFO +1 -1
  2. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/pyproject.toml +1 -1
  3. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/connections/manager.py +1 -0
  4. fastapi_startkit-0.42.0/src/fastapi_startkit/skills/__init__.py +7 -0
  5. fastapi_startkit-0.42.0/src/fastapi_startkit/skills/adapters/__init__.py +7 -0
  6. fastapi_startkit-0.42.0/src/fastapi_startkit/skills/adapters/base.py +57 -0
  7. fastapi_startkit-0.42.0/src/fastapi_startkit/skills/adapters/claude.py +91 -0
  8. fastapi_startkit-0.42.0/src/fastapi_startkit/skills/adapters/gemini.py +110 -0
  9. fastapi_startkit-0.42.0/src/fastapi_startkit/skills/commands/__init__.py +5 -0
  10. fastapi_startkit-0.42.0/src/fastapi_startkit/skills/commands/skills.py +80 -0
  11. fastapi_startkit-0.42.0/src/fastapi_startkit/skills/parser.py +74 -0
  12. fastapi_startkit-0.42.0/src/fastapi_startkit/skills/provider.py +17 -0
  13. fastapi_startkit-0.42.0/src/fastapi_startkit/skills/registry.py +158 -0
  14. fastapi_startkit-0.42.0/src/fastapi_startkit/skills/stubs/.ai/fastapi-startkit/database/SKILL.md +107 -0
  15. fastapi_startkit-0.42.0/src/fastapi_startkit/skills/stubs/.ai/fastapi-startkit/fastapi/SKILL.md +109 -0
  16. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/.DS_Store +0 -0
  17. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/__init__.py +0 -0
  18. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/ai/__init__.py +0 -0
  19. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/ai/agent.py +0 -0
  20. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/ai/audio.py +0 -0
  21. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/ai/audio_factory.py +0 -0
  22. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/ai/config.py +0 -0
  23. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/ai/decorators.py +0 -0
  24. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/ai/document.py +0 -0
  25. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/ai/image.py +0 -0
  26. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/ai/image_factory.py +0 -0
  27. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/ai/providers/__init__.py +0 -0
  28. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/ai/providers/ai_provider.py +0 -0
  29. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/ai/response.py +0 -0
  30. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/application.py +0 -0
  31. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/broadcasting/__init__.py +0 -0
  32. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/broadcasting/auth.py +0 -0
  33. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/broadcasting/channels.py +0 -0
  34. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/broadcasting/config.py +0 -0
  35. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/broadcasting/drivers/__init__.py +0 -0
  36. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/broadcasting/drivers/log_driver.py +0 -0
  37. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/broadcasting/drivers/reverb_driver.py +0 -0
  38. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/broadcasting/event.py +0 -0
  39. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/broadcasting/helpers.py +0 -0
  40. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/broadcasting/manager.py +0 -0
  41. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/broadcasting/provider.py +0 -0
  42. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/broadcasting/reverb/__init__.py +0 -0
  43. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/broadcasting/reverb/channel_manager.py +0 -0
  44. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/broadcasting/reverb/connection.py +0 -0
  45. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/broadcasting/reverb/server.py +0 -0
  46. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/broadcasting/stubs/__init__.py +0 -0
  47. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/broadcasting/stubs/channels.py +0 -0
  48. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/carbon/__init__.py +0 -0
  49. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/carbon/carbon.py +0 -0
  50. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/config/__init__.py +0 -0
  51. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/config/app.py +0 -0
  52. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/configuration/Configuration.py +0 -0
  53. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/configuration/__init__.py +0 -0
  54. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/configuration/config.py +0 -0
  55. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/configuration/helpers.py +0 -0
  56. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/configuration/providers/ConfigurationProvider.py +0 -0
  57. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/configuration/providers/__init__.py +0 -0
  58. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/console/__init__.py +0 -0
  59. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/console/application.py +0 -0
  60. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/console/can_override_config.py +0 -0
  61. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/console/can_override_default_options.py +0 -0
  62. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/console/command.py +0 -0
  63. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/console/publish_command.py +0 -0
  64. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/container/__init__.py +0 -0
  65. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/container/container.py +0 -0
  66. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/environment/__init__.py +0 -0
  67. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/environment/environment.py +0 -0
  68. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/exceptions/__init__.py +0 -0
  69. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/exceptions/exceptions.py +0 -0
  70. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/exceptions/handler.py +0 -0
  71. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/facades/AI.py +0 -0
  72. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/facades/AI.pyi +0 -0
  73. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/facades/Cache.py +0 -0
  74. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/facades/Config.py +0 -0
  75. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/facades/Config.pyi +0 -0
  76. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/facades/Dump.py +0 -0
  77. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/facades/Dump.pyi +0 -0
  78. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/facades/Facade.py +0 -0
  79. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/facades/Gate.py +0 -0
  80. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/facades/Gate.pyi +0 -0
  81. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/facades/Hash.py +0 -0
  82. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/facades/Hash.pyi +0 -0
  83. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/facades/Loader.py +0 -0
  84. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/facades/Loader.pyi +0 -0
  85. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/facades/Mail.py +0 -0
  86. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/facades/Mail.pyi +0 -0
  87. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/facades/Notification.py +0 -0
  88. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/facades/Notification.pyi +0 -0
  89. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/facades/Queue.py +0 -0
  90. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/facades/Queue.pyi +0 -0
  91. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/facades/RateLimiter.py +0 -0
  92. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/facades/RateLimiter.pyi +0 -0
  93. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/facades/Request.py +0 -0
  94. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/facades/Request.pyi +0 -0
  95. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/facades/Response.py +0 -0
  96. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/facades/Response.pyi +0 -0
  97. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/facades/Session.py +0 -0
  98. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/facades/Session.pyi +0 -0
  99. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/facades/Url.py +0 -0
  100. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/facades/Url.pyi +0 -0
  101. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/facades/View.py +0 -0
  102. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/facades/View.pyi +0 -0
  103. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/facades/Vite.py +0 -0
  104. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/facades/Vite.pyi +0 -0
  105. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/facades/__init__.py +0 -0
  106. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/fastapi/__init__.py +0 -0
  107. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/fastapi/commands/__init__.py +0 -0
  108. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/fastapi/commands/serve_command.py +0 -0
  109. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/fastapi/config/__init__.py +0 -0
  110. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/fastapi/config/fastapi.py +0 -0
  111. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/fastapi/exceptions.py +0 -0
  112. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/fastapi/providers/fastapi_provider.py +0 -0
  113. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/fastapi/requests/model.py +0 -0
  114. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/fastapi/routers/router.py +0 -0
  115. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/fastapi/testing/__init__.py +0 -0
  116. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/fastapi/testing/test_case.py +0 -0
  117. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/helpers/app.py +0 -0
  118. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/helpers/dataclass.py +0 -0
  119. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/inertia/__init__.py +0 -0
  120. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/inertia/constant.py +0 -0
  121. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/inertia/context.py +0 -0
  122. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/inertia/inertia.py +0 -0
  123. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/inertia/middleware.py +0 -0
  124. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/inertia/props/props.py +0 -0
  125. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/inertia/provider.py +0 -0
  126. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/jsonapi/__init__.py +0 -0
  127. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/jsonapi/response.py +0 -0
  128. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/loader/Loader.py +0 -0
  129. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/loader/__init__.py +0 -0
  130. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/logging/ChannelFactory.py +0 -0
  131. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/logging/__init__.py +0 -0
  132. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/logging/channels/BaseChannel.py +0 -0
  133. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/logging/channels/DailyChannel.py +0 -0
  134. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/logging/channels/MultiBaseChannel.py +0 -0
  135. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/logging/channels/SingleChannel.py +0 -0
  136. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/logging/channels/SlackChannel.py +0 -0
  137. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/logging/channels/StackChannel.py +0 -0
  138. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/logging/channels/SyslogChannel.py +0 -0
  139. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/logging/channels/TerminalChannel.py +0 -0
  140. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/logging/channels/__init__.py +0 -0
  141. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/logging/config/__init__.py +0 -0
  142. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/logging/config/channels.py +0 -0
  143. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/logging/config/logging.py +0 -0
  144. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/logging/drivers/BaseDriver.py +0 -0
  145. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/logging/drivers/LogSingleDriver.py +0 -0
  146. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/logging/drivers/LogSlackDriver.py +0 -0
  147. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/logging/drivers/LogSyslogDriver.py +0 -0
  148. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/logging/drivers/LogTerminalDriver.py +0 -0
  149. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/logging/drivers/__init__.py +0 -0
  150. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/logging/factory.py +0 -0
  151. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/logging/file.py +0 -0
  152. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/logging/handler.py +0 -0
  153. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/logging/listeners.py +0 -0
  154. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/logging/logger.py +0 -0
  155. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/logging/managers/LoggingManager.py +0 -0
  156. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/logging/managers/__init__.py +0 -0
  157. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/logging/providers/__init__.py +0 -0
  158. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/logging/providers/log_provider.py +0 -0
  159. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/__init__.py +0 -0
  160. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/collection/Collection.py +0 -0
  161. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/collection/__init__.py +0 -0
  162. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/commands/DBMigrateCommand.py +0 -0
  163. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/commands/DBSeedCommand.py +0 -0
  164. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/commands/MakeMigrationCommand.py +0 -0
  165. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/commands/MakeModelCommand.py +0 -0
  166. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/commands/MakeModelDocstringCommand.py +0 -0
  167. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/commands/MakeObserverCommand.py +0 -0
  168. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/commands/MakeSeedCommand.py +0 -0
  169. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/commands/MigrateFreshCommand.py +0 -0
  170. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/commands/MigrateRefreshCommand.py +0 -0
  171. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/commands/MigrateResetCommand.py +0 -0
  172. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/commands/MigrateRollbackCommand.py +0 -0
  173. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/commands/MigrateStatusCommand.py +0 -0
  174. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/commands/ShellCommand.py +0 -0
  175. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/commands/__init__.py +0 -0
  176. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/commands/stubs/create_migration.stub +0 -0
  177. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/commands/stubs/create_seed.stub +0 -0
  178. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/commands/stubs/model.stub +0 -0
  179. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/commands/stubs/observer.stub +0 -0
  180. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/commands/stubs/table_migration.stub +0 -0
  181. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/config/__init__.py +0 -0
  182. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/config/config.py +0 -0
  183. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/config/database.py +0 -0
  184. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/connections/connection.py +0 -0
  185. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/connections/factory.py +0 -0
  186. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/connections/mysql_connection.py +0 -0
  187. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/connections/postgres_connection.py +0 -0
  188. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/connections/sqlite_connection.py +0 -0
  189. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/exceptions.py +0 -0
  190. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/expressions/__init__.py +0 -0
  191. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/expressions/expressions.py +0 -0
  192. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/facades/DB.py +0 -0
  193. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/facades/Schema.py +0 -0
  194. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/facades/__init__.py +0 -0
  195. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/factory/__init__.py +0 -0
  196. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/factory/factory.py +0 -0
  197. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/helpers/__init__.py +0 -0
  198. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/helpers/misc.py +0 -0
  199. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/migrations/Migration.py +0 -0
  200. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/migrations/Migrator.py +0 -0
  201. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/migrations/__init__.py +0 -0
  202. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/models/MigrationModel.py +0 -0
  203. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/models/__init__.py +0 -0
  204. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/models/attribute.py +0 -0
  205. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/models/builder.py +0 -0
  206. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/models/caster.py +0 -0
  207. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/models/fields.py +0 -0
  208. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/models/model.py +0 -0
  209. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/models/observer.py +0 -0
  210. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/models/pivot.py +0 -0
  211. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/models/registry.py +0 -0
  212. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/models/relationship.py +0 -0
  213. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/observers/ObservesEvents.py +0 -0
  214. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/observers/__init__.py +0 -0
  215. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/pagination/BasePaginator.py +0 -0
  216. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/pagination/LengthAwarePaginator.py +0 -0
  217. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/pagination/SimplePaginator.py +0 -0
  218. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/pagination/__init__.py +0 -0
  219. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/providers/DatabaseProvider.py +0 -0
  220. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/providers/__init__.py +0 -0
  221. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/query/EagerLoadMixin.py +0 -0
  222. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/query/EagerRelation.py +0 -0
  223. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/query/__init__.py +0 -0
  224. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/query/grammars/BaseGrammar.py +0 -0
  225. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/query/grammars/MSSQLGrammar.py +0 -0
  226. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/query/grammars/MySQLGrammar.py +0 -0
  227. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/query/grammars/PostgresGrammar.py +0 -0
  228. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/query/grammars/SQLiteGrammar.py +0 -0
  229. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/query/grammars/__init__.py +0 -0
  230. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/query/processors/MSSQLPostProcessor.py +0 -0
  231. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/query/processors/MySQLPostProcessor.py +0 -0
  232. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/query/processors/PostgresPostProcessor.py +0 -0
  233. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/query/processors/SQLitePostProcessor.py +0 -0
  234. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/query/processors/__init__.py +0 -0
  235. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/query/support.py +0 -0
  236. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/relationships/BaseRelationship.py +0 -0
  237. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/relationships/BelongsTo.py +0 -0
  238. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/relationships/BelongsToMany.py +0 -0
  239. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/relationships/HasMany.py +0 -0
  240. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/relationships/HasManyThrough.py +0 -0
  241. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/relationships/HasOne.py +0 -0
  242. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/relationships/HasOneThrough.py +0 -0
  243. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/relationships/MorphMany.py +0 -0
  244. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/relationships/MorphOne.py +0 -0
  245. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/relationships/MorphTo.py +0 -0
  246. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/relationships/MorphToMany.py +0 -0
  247. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/relationships/__init__.py +0 -0
  248. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/schema/Blueprint.py +0 -0
  249. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/schema/Column.py +0 -0
  250. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/schema/ColumnDiff.py +0 -0
  251. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/schema/Constraint.py +0 -0
  252. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/schema/ForeignKeyConstraint.py +0 -0
  253. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/schema/Index.py +0 -0
  254. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/schema/Table.py +0 -0
  255. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/schema/TableDiff.py +0 -0
  256. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/schema/__init__.py +0 -0
  257. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/schema/platforms/MSSQLPlatform.py +0 -0
  258. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/schema/platforms/MySQLPlatform.py +0 -0
  259. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/schema/platforms/Platform.py +0 -0
  260. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/schema/platforms/PostgresPlatform.py +0 -0
  261. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/schema/platforms/SQLitePlatform.py +0 -0
  262. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/schema/platforms/__init__.py +0 -0
  263. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/schema/schema.py +0 -0
  264. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/seeds/Seeder.py +0 -0
  265. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/seeds/__init__.py +0 -0
  266. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/stubs/create-migration.html +0 -0
  267. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/stubs/table-migration.html +0 -0
  268. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/testing/__init__.py +0 -0
  269. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm/testing/transaction.py +0 -0
  270. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/.pytest_cache/.gitignore +0 -0
  271. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/.pytest_cache/CACHEDIR.TAG +0 -0
  272. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/.pytest_cache/README.md +0 -0
  273. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/.pytest_cache/v/cache/lastfailed +0 -0
  274. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/.pytest_cache/v/cache/nodeids +0 -0
  275. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/__init__.py +0 -0
  276. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/config/database.py +0 -0
  277. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/config.py +0 -0
  278. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/exceptions.py +0 -0
  279. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/factories/Factory.py +0 -0
  280. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/factories/__init__.py +0 -0
  281. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/schema/Schema.py +0 -0
  282. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/scopes/BaseScope.py +0 -0
  283. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/scopes/SoftDeleteScope.py +0 -0
  284. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/scopes/SoftDeletesMixin.py +0 -0
  285. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/scopes/UUIDPrimaryKeyMixin.py +0 -0
  286. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/scopes/UUIDPrimaryKeyScope.py +0 -0
  287. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/scopes/__init__.py +0 -0
  288. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/scopes/scope.py +0 -0
  289. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/testing/BaseTestCaseSelectGrammar.py +0 -0
  290. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/testing/Database.py +0 -0
  291. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/testing/TestCase.py +0 -0
  292. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/testing/__init__.py +0 -0
  293. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/User.py +0 -0
  294. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/connections/test_base_connections.py +0 -0
  295. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/eagers/test_eager.py +0 -0
  296. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/models/test_models.py +0 -0
  297. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/mssql/builder/test_mssql_query_builder.py +0 -0
  298. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/mssql/builder/test_mssql_query_builder_relationships.py +0 -0
  299. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/mssql/grammar/test_mssql_delete_grammar.py +0 -0
  300. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/mssql/grammar/test_mssql_insert_grammar.py +0 -0
  301. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/mssql/grammar/test_mssql_qmark.py +0 -0
  302. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/mssql/grammar/test_mssql_select_grammar.py +0 -0
  303. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/mssql/grammar/test_mssql_update_grammar.py +0 -0
  304. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/mssql/schema/test_mssql_schema_builder.py +0 -0
  305. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/mssql/schema/test_mssql_schema_builder_alter.py +0 -0
  306. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/builder/test_mysql_builder_transaction.py +0 -0
  307. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/builder/test_query_builder.py +0 -0
  308. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/builder/test_query_builder_scopes.py +0 -0
  309. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/builder/test_transactions.py +0 -0
  310. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/connections/test_mysql_connection_selects.py +0 -0
  311. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/grammar/test_mysql_delete_grammar.py +0 -0
  312. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/grammar/test_mysql_insert_grammar.py +0 -0
  313. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/grammar/test_mysql_qmark.py +0 -0
  314. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/grammar/test_mysql_select_grammar.py +0 -0
  315. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/grammar/test_mysql_update_grammar.py +0 -0
  316. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/model/test_accessors_and_mutators.py +0 -0
  317. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/model/test_model.py +0 -0
  318. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/relationships/test_belongs_to_many.py +0 -0
  319. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/relationships/test_has_many_through.py +0 -0
  320. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/relationships/test_has_one_through.py +0 -0
  321. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/relationships/test_relationships.py +0 -0
  322. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/schema/test_mysql_schema_builder.py +0 -0
  323. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/schema/test_mysql_schema_builder_alter.py +0 -0
  324. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/scopes/test_can_use_global_scopes.py +0 -0
  325. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/scopes/test_can_use_scopes.py +0 -0
  326. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/scopes/test_soft_delete.py +0 -0
  327. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/postgres/builder/test_postgres_query_builder.py +0 -0
  328. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/postgres/builder/test_postgres_transaction.py +0 -0
  329. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/postgres/grammar/test_delete_grammar.py +0 -0
  330. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/postgres/grammar/test_insert_grammar.py +0 -0
  331. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/postgres/grammar/test_select_grammar.py +0 -0
  332. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/postgres/grammar/test_update_grammar.py +0 -0
  333. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/postgres/relationships/test_postgres_relationships.py +0 -0
  334. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/postgres/schema/test_postgres_schema_builder.py +0 -0
  335. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/postgres/schema/test_postgres_schema_builder_alter.py +0 -0
  336. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/scopes/test_default_global_scopes.py +0 -0
  337. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/seeds/test_seeds.py +0 -0
  338. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/masoniteorm.backup/tests/utils.py +0 -0
  339. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/mcp/__init__.py +0 -0
  340. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/mcp/argument.py +0 -0
  341. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/mcp/prompt.py +0 -0
  342. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/mcp/protocol.py +0 -0
  343. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/mcp/providers/__init__.py +0 -0
  344. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/mcp/providers/mcp_provider.py +0 -0
  345. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/mcp/request.py +0 -0
  346. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/mcp/resource.py +0 -0
  347. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/mcp/response.py +0 -0
  348. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/mcp/server.py +0 -0
  349. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/mcp/tool.py +0 -0
  350. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/process/__init__.py +0 -0
  351. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/process/exception.py +0 -0
  352. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/process/fake.py +0 -0
  353. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/process/process.py +0 -0
  354. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/process/result.py +0 -0
  355. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/providers/Provider.py +0 -0
  356. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/providers/__init__.py +0 -0
  357. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/providers/app_provider.py +0 -0
  358. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/storage/__init__.py +0 -0
  359. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/storage/config/__init__.py +0 -0
  360. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/storage/config/storage.py +0 -0
  361. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/storage/data/mime.types +0 -0
  362. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/storage/drivers/__init__.py +0 -0
  363. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/storage/drivers/fake.py +0 -0
  364. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/storage/drivers/local.py +0 -0
  365. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/storage/drivers/s3.py +0 -0
  366. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/storage/file.py +0 -0
  367. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/storage/filestream.py +0 -0
  368. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/storage/helper.py +0 -0
  369. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/storage/providers/provider.py +0 -0
  370. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/storage/storage.py +0 -0
  371. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/support/__init__.py +0 -0
  372. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/support/collection.py +0 -0
  373. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/support/string.py +0 -0
  374. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/testing/__init__.py +0 -0
  375. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/testing/test_case.py +0 -0
  376. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/utils/structures.py +0 -0
  377. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/vite/__init__.py +0 -0
  378. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/vite/config/vite.py +0 -0
  379. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/vite/exceptions.py +0 -0
  380. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/vite/providers/provider.py +0 -0
  381. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/vite/stubs/package.json +0 -0
  382. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/vite/stubs/resources/css/app.css +0 -0
  383. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/vite/stubs/resources/js/app.ts +0 -0
  384. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/vite/stubs/templates/index.html +0 -0
  385. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/vite/stubs/tsconfig.json +0 -0
  386. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/vite/stubs/vite.config.ts +0 -0
  387. {fastapi_startkit-0.40.1 → fastapi_startkit-0.42.0}/src/fastapi_startkit/vite/vite.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: fastapi-startkit
3
- Version: 0.40.1
3
+ Version: 0.42.0
4
4
  Summary: Fastapi Starter kit components
5
5
  Author: Bedram Tamang
6
6
  Author-email: Bedram Tamang <tmgbedu@gmail.com>
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "fastapi-startkit"
3
- version = "0.40.1"
3
+ version = "0.42.0"
4
4
  description = "Fastapi Starter kit components"
5
5
  authors = [
6
6
  {name = "Bedram Tamang", email = "tmgbedu@gmail.com"}
@@ -41,5 +41,6 @@ class DatabaseManager:
41
41
 
42
42
  async def clear(self):
43
43
  for conn in self.connections.values():
44
+ await conn.close()
44
45
  await conn.engine.dispose()
45
46
  self.connections.clear()
@@ -0,0 +1,7 @@
1
+ from .registry import SkillRegistry
2
+ from .provider import AISkillProvider
3
+
4
+ __all__ = [
5
+ "SkillRegistry",
6
+ "AISkillProvider",
7
+ ]
@@ -0,0 +1,7 @@
1
+ """Adapter layer for rendering canonical skills into agent-specific formats."""
2
+
3
+ from .base import BaseAdapter
4
+ from .claude import ClaudeAdapter
5
+ from .gemini import GeminiAdapter
6
+
7
+ __all__ = ["BaseAdapter", "ClaudeAdapter", "GeminiAdapter"]
@@ -0,0 +1,57 @@
1
+ """BaseAdapter — abstract base class for all skill adapters.
2
+
3
+ New adapters (e.g. Codex) only need to subclass :class:`BaseAdapter` and
4
+ implement :meth:`render` and :meth:`prune`.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from abc import ABC, abstractmethod
10
+ from pathlib import Path
11
+ from typing import Callable, Sequence
12
+
13
+ from fastapi_startkit.skills.registry import Skill
14
+
15
+
16
+ class BaseAdapter(ABC):
17
+ """Abstract base for skill adapters.
18
+
19
+ Parameters
20
+ ----------
21
+ base_path:
22
+ Root of the project (where ``.claude/``, ``GEMINI.md``, etc. live).
23
+ Defaults to the current working directory.
24
+ """
25
+
26
+ #: Short identifier shown in CLI output (e.g. "claude", "gemini").
27
+ name: str = ""
28
+
29
+ def __init__(self, base_path: Path | str | None = None) -> None:
30
+ self.base_path = Path(base_path) if base_path else Path.cwd()
31
+
32
+ # ------------------------------------------------------------------
33
+ # Abstract interface
34
+ # ------------------------------------------------------------------
35
+
36
+ @abstractmethod
37
+ def render(
38
+ self,
39
+ skills: Sequence[Skill],
40
+ force: bool = False,
41
+ confirm: Callable[..., bool] | None = None,
42
+ ) -> list[str]:
43
+ """Write *skills* to the target format.
44
+
45
+ Existing files are preserved unless *force* is true or *confirm*
46
+ returns true for the overwrite prompt — mirroring ``provider:publish``.
47
+
48
+ Returns a list of human-readable lines describing what was written
49
+ (suitable for printing in the ``ai:skills`` command).
50
+ """
51
+
52
+ @abstractmethod
53
+ def prune(self, skills: Sequence[Skill]) -> list[str]:
54
+ """Remove previously-synced skills that are *not* in *skills*.
55
+
56
+ Returns a list of human-readable lines describing what was removed.
57
+ """
@@ -0,0 +1,91 @@
1
+ """ClaudeAdapter — renders skills into ``.claude/skills/<name>/SKILL.md``."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pathlib import Path
6
+ from typing import Callable, Sequence
7
+
8
+ from fastapi_startkit.skills.registry import Skill
9
+ from .base import BaseAdapter
10
+
11
+
12
+ class ClaudeAdapter(BaseAdapter):
13
+ """Writes canonical skills into Claude Code's skill directory.
14
+
15
+ Each skill is rendered as ``.claude/skills/<skill-name>/SKILL.md`` with a
16
+ YAML front-matter block followed by the original body. Publishing follows
17
+ the same rules as ``provider:publish``: a missing file is written, an
18
+ existing file is left untouched unless ``force`` is set or the caller
19
+ confirms the overwrite.
20
+ """
21
+
22
+ name = "claude"
23
+
24
+ # ------------------------------------------------------------------
25
+ # Public API
26
+ # ------------------------------------------------------------------
27
+
28
+ def render(
29
+ self,
30
+ skills: Sequence[Skill],
31
+ force: bool = False,
32
+ confirm: Callable[..., bool] | None = None,
33
+ ) -> list[str]:
34
+ messages: list[str] = []
35
+ for skill in skills:
36
+ dest = self._skill_path(skill.name)
37
+ rel = f".claude/skills/{skill.name}/SKILL.md"
38
+ content = self._build_content(skill)
39
+
40
+ if dest.exists() and not force:
41
+ if not self._confirm_overwrite(confirm, rel):
42
+ messages.append(f"[claude] Skipped <comment>{rel}</comment> (already exists)")
43
+ continue
44
+ verb = "Overwrote"
45
+ else:
46
+ verb = "Overwrote" if dest.exists() else "Published"
47
+
48
+ dest.parent.mkdir(parents=True, exist_ok=True)
49
+ dest.write_text(content, encoding="utf-8")
50
+ messages.append(f"[claude] {verb} <info>{rel}</info>")
51
+ return messages
52
+
53
+ @staticmethod
54
+ def _confirm_overwrite(confirm: Callable[..., bool] | None, rel: str) -> bool:
55
+ """Ask the caller whether to overwrite *rel*; default to no."""
56
+ if confirm is None:
57
+ return False
58
+ return bool(confirm(f" <comment>{rel}</comment> already exists. Overwrite?", default=False))
59
+
60
+ def prune(self, skills: Sequence[Skill]) -> list[str]:
61
+ """Remove ``.claude/skills/<name>/`` dirs not represented in *skills*."""
62
+ messages: list[str] = []
63
+ known_names = {s.name for s in skills}
64
+ skills_root = self.base_path / ".claude" / "skills"
65
+ if not skills_root.is_dir():
66
+ return messages
67
+
68
+ for child in sorted(skills_root.iterdir()):
69
+ if child.is_dir() and child.name not in known_names:
70
+ import shutil
71
+
72
+ shutil.rmtree(child)
73
+ messages.append(f"[claude] Pruned .claude/skills/{child.name}/")
74
+ return messages
75
+
76
+ # ------------------------------------------------------------------
77
+ # Internal helpers
78
+ # ------------------------------------------------------------------
79
+
80
+ def _skill_path(self, skill_name: str) -> Path:
81
+ return self.base_path / ".claude" / "skills" / skill_name / "SKILL.md"
82
+
83
+ @staticmethod
84
+ def _build_content(skill: Skill) -> str:
85
+ """Render the SKILL.md content for *skill*."""
86
+ lines = ["---", f"name: {skill.name}", f"description: {skill.description}", "---"]
87
+ if skill.body:
88
+ lines.append("")
89
+ lines.append(skill.body)
90
+ lines.append("")
91
+ return "\n".join(lines)
@@ -0,0 +1,110 @@
1
+ """GeminiAdapter — renders skills into ``GEMINI.md`` via marker blocks.
2
+
3
+ The adapter manages only the region of ``GEMINI.md`` that lies between the
4
+ ``<!-- skills:start -->`` and ``<!-- skills:end -->`` markers. Content
5
+ outside those markers is **never** modified, making the adapter safe to use
6
+ even when the user has hand-edited the rest of the file.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from pathlib import Path
12
+ from typing import Callable, Sequence
13
+
14
+ from fastapi_startkit.skills.registry import Skill
15
+ from .base import BaseAdapter
16
+
17
+ _MARKER_START = "<!-- skills:start -->"
18
+ _MARKER_END = "<!-- skills:end -->"
19
+
20
+
21
+ class GeminiAdapter(BaseAdapter):
22
+ """Writes canonical skills into ``GEMINI.md`` with HTML comment markers.
23
+
24
+ If ``GEMINI.md`` does not exist it is created from scratch. If it exists
25
+ the content between the markers is replaced; everything outside is left
26
+ unchanged. The write is idempotent.
27
+ """
28
+
29
+ name = "gemini"
30
+
31
+ # ------------------------------------------------------------------
32
+ # Public API
33
+ # ------------------------------------------------------------------
34
+
35
+ def render(
36
+ self,
37
+ skills: Sequence[Skill],
38
+ force: bool = False,
39
+ confirm: Callable[..., bool] | None = None,
40
+ ) -> list[str]:
41
+ # GEMINI.md edits are confined to the skills marker block, so user
42
+ # content is never clobbered — force/confirm are accepted for a uniform
43
+ # adapter interface but the block is always kept in sync.
44
+ gemini_md = self.base_path / "GEMINI.md"
45
+ new_section = self._build_section(skills)
46
+ changed = self._update_file(gemini_md, new_section)
47
+ verb = "Updated" if changed else "Unchanged"
48
+ return [f"[gemini] {verb} <info>GEMINI.md</info> ({len(skills)} skill(s))"]
49
+
50
+ def prune(self, skills: Sequence[Skill]) -> list[str]:
51
+ """For Gemini, pruning just re-renders with the current skill list.
52
+
53
+ Since everything lives in a single file within a marked block,
54
+ rendering the new (shorter) list is equivalent to pruning.
55
+ """
56
+ return self.render(skills)
57
+
58
+ # ------------------------------------------------------------------
59
+ # Internal helpers
60
+ # ------------------------------------------------------------------
61
+
62
+ def _build_section(self, skills: Sequence[Skill]) -> str:
63
+ """Return the full marker block to inject into GEMINI.md."""
64
+ parts = [_MARKER_START]
65
+ for skill in skills:
66
+ parts.append(f"\n## {skill.name}\n")
67
+ if skill.description:
68
+ parts.append(f"{skill.description}\n")
69
+ if skill.body:
70
+ parts.append(f"\n{skill.body}\n")
71
+ parts.append(_MARKER_END)
72
+ return "\n".join(parts)
73
+
74
+ def _update_file(self, path: Path, section: str) -> bool:
75
+ """Inject *section* into *path*, preserving content outside markers.
76
+
77
+ Returns *True* when the file was (re)written, *False* when unchanged.
78
+ """
79
+ if path.exists():
80
+ original = path.read_text(encoding="utf-8")
81
+ else:
82
+ original = ""
83
+
84
+ new_content = self._splice(original, section)
85
+
86
+ if original == new_content:
87
+ return False
88
+
89
+ path.parent.mkdir(parents=True, exist_ok=True)
90
+ path.write_text(new_content, encoding="utf-8")
91
+ return True
92
+
93
+ @staticmethod
94
+ def _splice(original: str, section: str) -> str:
95
+ """Replace the skills block inside *original* with *section*.
96
+
97
+ If the markers do not exist yet the section is appended to the file
98
+ (separated by a blank line).
99
+ """
100
+ start_idx = original.find(_MARKER_START)
101
+ end_idx = original.find(_MARKER_END)
102
+
103
+ if start_idx != -1 and end_idx != -1 and end_idx > start_idx:
104
+ before = original[:start_idx]
105
+ after = original[end_idx + len(_MARKER_END) :]
106
+ return before + section + after
107
+ else:
108
+ # No markers yet — append
109
+ separator = "\n\n" if original and not original.endswith("\n\n") else ""
110
+ return original + separator + section + "\n"
@@ -0,0 +1,5 @@
1
+ """Cleo commands for the skills module."""
2
+
3
+ from .skills import SkillsCommand
4
+
5
+ __all__ = ["SkillsCommand"]
@@ -0,0 +1,80 @@
1
+ """ai:skills — list or sync provider-declared AI skills.
2
+
3
+ Examples::
4
+
5
+ artisan ai:skills --list
6
+ artisan ai:skills --sync
7
+ artisan ai:skills --sync --target=claude --prune
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ from cleo.helpers import option
13
+
14
+ from fastapi_startkit.console import Command
15
+
16
+
17
+ class SkillsCommand(Command):
18
+ name = "ai:skills"
19
+ description = "List or sync provider-declared AI skills."
20
+
21
+ options = [
22
+ option("list", "l", flag=True, description="List providers that declare skills (default)."),
23
+ option("sync", "s", flag=True, description="Publish skills and sync them to AI agents."),
24
+ option(
25
+ "target",
26
+ "t",
27
+ flag=False,
28
+ description="Sync target: claude | gemini | all. Prompts if omitted.",
29
+ ),
30
+ option(
31
+ "prune",
32
+ None,
33
+ flag=True,
34
+ description="Remove skill files no longer declared by any provider.",
35
+ ),
36
+ option(
37
+ "force",
38
+ "f",
39
+ flag=True,
40
+ description="Overwrite existing files without prompting.",
41
+ ),
42
+ ]
43
+
44
+ def handle(self) -> int:
45
+ from fastapi_startkit.skills.registry import SkillRegistry
46
+
47
+ registry: SkillRegistry = self.container.make("ai_skill.skills.registry")
48
+
49
+ # --target / --prune only make sense when syncing, so they imply --sync.
50
+ if self.option("sync") or self.option("prune") or self.option("target"):
51
+ return self._sync(registry)
52
+
53
+ return self._list(registry)
54
+
55
+ def _list(self, registry) -> int:
56
+ providers = registry.get_providers()
57
+
58
+ if providers.is_empty():
59
+ self.line("<comment>No skills found in any registered provider.</comment>")
60
+ return 0
61
+
62
+ self.info("Skill(s) found for the following provider(s):")
63
+ for index, provider_key in enumerate(providers, start=1):
64
+ self.info(f"{index}. {provider_key}")
65
+ return 0
66
+
67
+ def _sync(self, registry) -> int:
68
+ choices = ["all", "claude", "gemini"]
69
+ target = self.option("target")
70
+ if not target:
71
+ answer = self.choice("Which agent do you want to publish for?", choices, default=0)
72
+ # Interactive returns the value; non-interactive returns the default index.
73
+ target = choices[answer] if isinstance(answer, int) else answer
74
+ target = target.lower()
75
+ prune = bool(self.option("prune"))
76
+ force = bool(self.option("force"))
77
+
78
+ for message in registry.publish(target=target, prune=prune, force=force, confirm=self.confirm):
79
+ self.line(f" {message}")
80
+ return 0
@@ -0,0 +1,74 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass, field
4
+ from pathlib import Path
5
+
6
+
7
+ @dataclass
8
+ class Skill:
9
+ name: str
10
+ description: str
11
+ path: Path
12
+ provider_key: str = "fastapi-startkit"
13
+ body: str = field(default="", repr=False)
14
+ metadata: dict = field(default_factory=dict, repr=False)
15
+
16
+
17
+ class SkillParser:
18
+ """Parses SKILL.md files into :class:`Skill` objects."""
19
+
20
+ def parse(self, path: Path, provider_key: str = "fastapi-startkit") -> "Skill | None":
21
+ """Read and parse *path* into a Skill, or ``None`` if it can't be read
22
+ or has no name."""
23
+ try:
24
+ text = path.read_text(encoding="utf-8")
25
+ except OSError:
26
+ return None
27
+
28
+ meta, body = self.parse_frontmatter(text)
29
+ name = (meta.get("name") or path.parent.name or "").strip()
30
+ if not name:
31
+ return None
32
+
33
+ description = (meta.get("description") or "").strip()
34
+ extra = {k: v for k, v in meta.items() if k not in ("name", "description")}
35
+ return Skill(
36
+ name=name,
37
+ description=description,
38
+ path=path,
39
+ provider_key=provider_key,
40
+ body=body.strip(),
41
+ metadata=extra,
42
+ )
43
+
44
+ @staticmethod
45
+ def parse_frontmatter(text: str) -> tuple[dict, str]:
46
+ """Split YAML front-matter from the body. Returns (meta_dict, body_str)."""
47
+ lines = text.splitlines(keepends=True)
48
+ if not lines or lines[0].strip() != "---":
49
+ return {}, text
50
+
51
+ end_idx = None
52
+ for i, line in enumerate(lines[1:], start=1):
53
+ if line.strip() == "---":
54
+ end_idx = i
55
+ break
56
+
57
+ if end_idx is None:
58
+ return {}, text
59
+
60
+ fm_text = "".join(lines[1:end_idx])
61
+ body = "".join(lines[end_idx + 1 :])
62
+
63
+ try:
64
+ import yaml
65
+
66
+ meta = yaml.safe_load(fm_text) or {}
67
+ except ModuleNotFoundError:
68
+ meta = {}
69
+ for line in lines[1:end_idx]:
70
+ if ":" in line:
71
+ k, _, v = line.partition(":")
72
+ meta[k.strip()] = v.strip()
73
+
74
+ return meta, body
@@ -0,0 +1,17 @@
1
+ from __future__ import annotations
2
+
3
+ from fastapi_startkit.providers import Provider
4
+
5
+
6
+ class AISkillProvider(Provider):
7
+ provider_key = "ai_skill"
8
+
9
+ def register(self) -> None:
10
+ from fastapi_startkit.skills.registry import SkillRegistry
11
+
12
+ self.app.bind(f"{self.provider_key}.skills.registry", SkillRegistry(self.app))
13
+
14
+ def boot(self) -> None:
15
+ from fastapi_startkit.skills.commands import SkillsCommand
16
+
17
+ self.commands([SkillsCommand])
@@ -0,0 +1,158 @@
1
+ """SkillRegistry — maps providers to their skill files and publishes them.
2
+
3
+ Each provider key in :attr:`SkillRegistry.skills` points at one or more
4
+ ``SKILL.md`` destinations under ``.ai/fastapi-startkit/``. The framework ships a
5
+ matching stub for each at ``skills/stubs/<dest>``.
6
+
7
+ * ``get_providers()`` — registered providers that declare skills (used by list).
8
+ * ``publish()`` — copy stubs into the project then render to AI agents.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ from pathlib import Path
14
+ from typing import Callable, TYPE_CHECKING
15
+
16
+ from fastapi_startkit.skills.parser import Skill, SkillParser
17
+ from fastapi_startkit.support.collection import collect
18
+
19
+ if TYPE_CHECKING:
20
+ from fastapi_startkit.application import Application
21
+ from fastapi_startkit.support.collection import Collection
22
+
23
+ __all__ = ["Skill", "SkillRegistry", "STUBS_BASE_PATH"]
24
+
25
+ #: Source location of framework-shipped skill stubs, organised by provider key:
26
+ #: stubs/.ai/fastapi-startkit/<provider_key>/SKILL.md
27
+ STUBS_BASE_PATH = Path(__file__).resolve().parent / "stubs" / ".ai" / "fastapi-startkit"
28
+
29
+
30
+ class SkillRegistry:
31
+ skills = {
32
+ "fastapi": [
33
+ ".ai/fastapi-startkit/fastapi/SKILL.md",
34
+ ],
35
+ "database": [
36
+ ".ai/fastapi-startkit/database/SKILL.md",
37
+ ],
38
+ }
39
+
40
+ def __init__(self, app: "Application") -> None:
41
+ self.application = app
42
+ self.parser = SkillParser()
43
+
44
+ @property
45
+ def base_path(self) -> Path:
46
+ return Path(self.application.base_path)
47
+
48
+ @property
49
+ def stubs_root(self) -> Path:
50
+ return STUBS_BASE_PATH.parent.parent # .../skills/stubs
51
+
52
+ def get_providers(self) -> "Collection":
53
+ """Registered providers that declare skills (keyed by provider key)."""
54
+ return (
55
+ collect(self.application.providers)
56
+ .map(lambda provider: provider.provider_key)
57
+ .filter(lambda key: key in self.skills)
58
+ )
59
+
60
+ def discover(self) -> list[Skill]:
61
+ """Load a Skill for every declared file of every registered provider.
62
+
63
+ Prefers the project copy under ``.ai/`` (so user edits flow through) and
64
+ falls back to the bundled stub when the project hasn't published it yet.
65
+ """
66
+ skills: list[Skill] = []
67
+ for provider_key in self.get_providers():
68
+ for dest in self.skills.get(provider_key, []):
69
+ source = self.base_path / dest
70
+ if not source.is_file():
71
+ source = self.stubs_root / dest
72
+ skill = self.parser.parse(source, provider_key)
73
+ if skill is not None:
74
+ skills.append(skill)
75
+
76
+ return skills
77
+
78
+ def publish(
79
+ self,
80
+ target: str = "all",
81
+ prune: bool = False,
82
+ force: bool = False,
83
+ confirm: Callable[..., bool] | None = None,
84
+ ) -> list[str]:
85
+ """Copy stubs into the project, then render skills to the AI agent(s).
86
+
87
+ Existing destination files are preserved unless *force* is set or
88
+ *confirm* approves the overwrite — matching ``provider:publish``.
89
+
90
+ Returns human-readable log lines for the calling command to print.
91
+ """
92
+ messages = self._publish_stubs(force=force, confirm=confirm)
93
+
94
+ skills = self.discover()
95
+ if not skills:
96
+ messages.append("<comment>No skills found in any registered provider.</comment>")
97
+ return messages
98
+
99
+ adapters = self._resolve_adapters(target)
100
+ if not adapters:
101
+ messages.append(f"<error>Unknown target '{target}'. Use: claude, gemini, all.</error>")
102
+ return messages
103
+
104
+ messages.append(f"<info>Syncing {len(skills)} skill(s) to: {target}…</info>")
105
+ for adapter in adapters:
106
+ messages.extend(adapter.render(skills, force=force, confirm=confirm))
107
+ if prune:
108
+ messages.extend(adapter.prune(skills))
109
+ return messages
110
+
111
+ def _publish_stubs(
112
+ self,
113
+ force: bool = False,
114
+ confirm: Callable[..., bool] | None = None,
115
+ ) -> list[str]:
116
+ """Copy bundled stubs into the project's ``.ai/``.
117
+
118
+ A missing file is always written. An existing file is left untouched
119
+ (preserving user edits) unless *force* is set or *confirm* approves the
120
+ overwrite — so framework stub updates can be pulled in deliberately.
121
+ """
122
+ import shutil
123
+
124
+ messages: list[str] = []
125
+ for provider_key in self.get_providers():
126
+ for dest in self.skills.get(provider_key, []):
127
+ source = self.stubs_root / dest
128
+ if not source.is_file():
129
+ continue
130
+
131
+ dest_path = self.base_path / dest
132
+ existed = dest_path.exists()
133
+ if existed and not force:
134
+ if confirm is None or not confirm(
135
+ f" <comment>{dest}</comment> already exists. Overwrite?", default=False
136
+ ):
137
+ messages.append(f"Skipped <comment>{dest}</comment> (already exists)")
138
+ continue
139
+
140
+ dest_path.parent.mkdir(parents=True, exist_ok=True)
141
+ shutil.copy2(source, dest_path)
142
+ verb = "Overwrote" if existed else "Published"
143
+ messages.append(f"{verb} <info>{dest}</info>")
144
+ return messages
145
+
146
+ def _resolve_adapters(self, target: str) -> list:
147
+ from fastapi_startkit.skills.adapters import ClaudeAdapter, GeminiAdapter
148
+
149
+ all_adapters = {
150
+ "claude": ClaudeAdapter,
151
+ "gemini": GeminiAdapter,
152
+ }
153
+
154
+ if target == "all":
155
+ return [cls(self.base_path) for cls in all_adapters.values()]
156
+
157
+ cls = all_adapters.get(target)
158
+ return [cls(self.base_path)] if cls else []