fastapi-startkit 0.40.1__tar.gz → 0.41.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.
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/PKG-INFO +1 -1
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/pyproject.toml +1 -1
- fastapi_startkit-0.41.0/src/fastapi_startkit/skills/__init__.py +24 -0
- fastapi_startkit-0.41.0/src/fastapi_startkit/skills/adapters/__init__.py +7 -0
- fastapi_startkit-0.41.0/src/fastapi_startkit/skills/adapters/base.py +49 -0
- fastapi_startkit-0.41.0/src/fastapi_startkit/skills/adapters/claude.py +82 -0
- fastapi_startkit-0.41.0/src/fastapi_startkit/skills/adapters/gemini.py +102 -0
- fastapi_startkit-0.41.0/src/fastapi_startkit/skills/commands/__init__.py +6 -0
- fastapi_startkit-0.41.0/src/fastapi_startkit/skills/commands/list.py +73 -0
- fastapi_startkit-0.41.0/src/fastapi_startkit/skills/commands/sync.py +91 -0
- fastapi_startkit-0.41.0/src/fastapi_startkit/skills/provider.py +51 -0
- fastapi_startkit-0.41.0/src/fastapi_startkit/skills/registry.py +126 -0
- fastapi_startkit-0.41.0/src/fastapi_startkit/skills/rules/__init__.py +8 -0
- fastapi_startkit-0.41.0/src/fastapi_startkit/skills/rules/adapters/__init__.py +6 -0
- fastapi_startkit-0.41.0/src/fastapi_startkit/skills/rules/adapters/claude.py +90 -0
- fastapi_startkit-0.41.0/src/fastapi_startkit/skills/rules/adapters/gemini.py +74 -0
- fastapi_startkit-0.41.0/src/fastapi_startkit/skills/rules/commands/__init__.py +6 -0
- fastapi_startkit-0.41.0/src/fastapi_startkit/skills/rules/commands/list.py +57 -0
- fastapi_startkit-0.41.0/src/fastapi_startkit/skills/rules/commands/sync.py +81 -0
- fastapi_startkit-0.41.0/src/fastapi_startkit/skills/rules/registry.py +164 -0
- fastapi_startkit-0.41.0/src/fastapi_startkit/skills/stubs/.ai/fastapi-startkit/fastapi-startkit/SKILL.md +109 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/.DS_Store +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/ai/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/ai/agent.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/ai/audio.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/ai/audio_factory.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/ai/config.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/ai/decorators.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/ai/document.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/ai/image.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/ai/image_factory.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/ai/providers/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/ai/providers/ai_provider.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/ai/response.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/application.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/broadcasting/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/broadcasting/auth.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/broadcasting/channels.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/broadcasting/config.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/broadcasting/drivers/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/broadcasting/drivers/log_driver.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/broadcasting/drivers/reverb_driver.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/broadcasting/event.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/broadcasting/helpers.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/broadcasting/manager.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/broadcasting/provider.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/broadcasting/reverb/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/broadcasting/reverb/channel_manager.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/broadcasting/reverb/connection.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/broadcasting/reverb/server.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/broadcasting/stubs/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/broadcasting/stubs/channels.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/carbon/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/carbon/carbon.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/config/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/config/app.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/configuration/Configuration.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/configuration/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/configuration/config.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/configuration/helpers.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/configuration/providers/ConfigurationProvider.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/configuration/providers/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/console/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/console/application.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/console/can_override_config.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/console/can_override_default_options.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/console/command.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/console/publish_command.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/container/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/container/container.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/environment/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/environment/environment.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/exceptions/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/exceptions/exceptions.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/exceptions/handler.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/facades/AI.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/facades/AI.pyi +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/facades/Cache.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/facades/Config.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/facades/Config.pyi +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/facades/Dump.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/facades/Dump.pyi +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/facades/Facade.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/facades/Gate.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/facades/Gate.pyi +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/facades/Hash.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/facades/Hash.pyi +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/facades/Loader.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/facades/Loader.pyi +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/facades/Mail.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/facades/Mail.pyi +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/facades/Notification.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/facades/Notification.pyi +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/facades/Queue.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/facades/Queue.pyi +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/facades/RateLimiter.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/facades/RateLimiter.pyi +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/facades/Request.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/facades/Request.pyi +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/facades/Response.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/facades/Response.pyi +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/facades/Session.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/facades/Session.pyi +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/facades/Url.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/facades/Url.pyi +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/facades/View.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/facades/View.pyi +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/facades/Vite.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/facades/Vite.pyi +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/facades/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/fastapi/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/fastapi/commands/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/fastapi/commands/serve_command.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/fastapi/config/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/fastapi/config/fastapi.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/fastapi/exceptions.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/fastapi/providers/fastapi_provider.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/fastapi/requests/model.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/fastapi/routers/router.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/fastapi/testing/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/fastapi/testing/test_case.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/helpers/app.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/helpers/dataclass.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/inertia/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/inertia/constant.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/inertia/context.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/inertia/inertia.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/inertia/middleware.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/inertia/props/props.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/inertia/provider.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/jsonapi/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/jsonapi/response.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/loader/Loader.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/loader/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/logging/ChannelFactory.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/logging/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/logging/channels/BaseChannel.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/logging/channels/DailyChannel.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/logging/channels/MultiBaseChannel.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/logging/channels/SingleChannel.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/logging/channels/SlackChannel.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/logging/channels/StackChannel.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/logging/channels/SyslogChannel.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/logging/channels/TerminalChannel.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/logging/channels/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/logging/config/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/logging/config/channels.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/logging/config/logging.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/logging/drivers/BaseDriver.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/logging/drivers/LogSingleDriver.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/logging/drivers/LogSlackDriver.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/logging/drivers/LogSyslogDriver.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/logging/drivers/LogTerminalDriver.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/logging/drivers/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/logging/factory.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/logging/file.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/logging/handler.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/logging/listeners.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/logging/logger.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/logging/managers/LoggingManager.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/logging/managers/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/logging/providers/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/logging/providers/log_provider.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/collection/Collection.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/collection/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/commands/DBMigrateCommand.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/commands/DBSeedCommand.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/commands/MakeMigrationCommand.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/commands/MakeModelCommand.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/commands/MakeModelDocstringCommand.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/commands/MakeObserverCommand.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/commands/MakeSeedCommand.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/commands/MigrateFreshCommand.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/commands/MigrateRefreshCommand.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/commands/MigrateResetCommand.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/commands/MigrateRollbackCommand.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/commands/MigrateStatusCommand.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/commands/ShellCommand.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/commands/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/commands/stubs/create_migration.stub +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/commands/stubs/create_seed.stub +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/commands/stubs/model.stub +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/commands/stubs/observer.stub +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/commands/stubs/table_migration.stub +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/config/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/config/config.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/config/database.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/connections/connection.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/connections/factory.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/connections/manager.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/connections/mysql_connection.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/connections/postgres_connection.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/connections/sqlite_connection.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/exceptions.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/expressions/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/expressions/expressions.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/facades/DB.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/facades/Schema.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/facades/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/factory/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/factory/factory.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/helpers/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/helpers/misc.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/migrations/Migration.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/migrations/Migrator.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/migrations/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/models/MigrationModel.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/models/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/models/attribute.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/models/builder.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/models/caster.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/models/fields.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/models/model.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/models/observer.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/models/pivot.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/models/registry.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/models/relationship.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/observers/ObservesEvents.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/observers/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/pagination/BasePaginator.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/pagination/LengthAwarePaginator.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/pagination/SimplePaginator.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/pagination/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/providers/DatabaseProvider.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/providers/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/query/EagerLoadMixin.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/query/EagerRelation.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/query/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/query/grammars/BaseGrammar.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/query/grammars/MSSQLGrammar.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/query/grammars/MySQLGrammar.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/query/grammars/PostgresGrammar.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/query/grammars/SQLiteGrammar.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/query/grammars/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/query/processors/MSSQLPostProcessor.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/query/processors/MySQLPostProcessor.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/query/processors/PostgresPostProcessor.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/query/processors/SQLitePostProcessor.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/query/processors/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/query/support.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/relationships/BaseRelationship.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/relationships/BelongsTo.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/relationships/BelongsToMany.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/relationships/HasMany.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/relationships/HasManyThrough.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/relationships/HasOne.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/relationships/HasOneThrough.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/relationships/MorphMany.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/relationships/MorphOne.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/relationships/MorphTo.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/relationships/MorphToMany.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/relationships/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/schema/Blueprint.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/schema/Column.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/schema/ColumnDiff.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/schema/Constraint.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/schema/ForeignKeyConstraint.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/schema/Index.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/schema/Table.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/schema/TableDiff.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/schema/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/schema/platforms/MSSQLPlatform.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/schema/platforms/MySQLPlatform.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/schema/platforms/Platform.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/schema/platforms/PostgresPlatform.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/schema/platforms/SQLitePlatform.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/schema/platforms/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/schema/schema.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/seeds/Seeder.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/seeds/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/stubs/create-migration.html +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/stubs/table-migration.html +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/testing/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm/testing/transaction.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/.pytest_cache/.gitignore +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/.pytest_cache/CACHEDIR.TAG +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/.pytest_cache/README.md +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/.pytest_cache/v/cache/lastfailed +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/.pytest_cache/v/cache/nodeids +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/config/database.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/config.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/exceptions.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/factories/Factory.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/factories/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/schema/Schema.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/scopes/BaseScope.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/scopes/SoftDeleteScope.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/scopes/SoftDeletesMixin.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/scopes/UUIDPrimaryKeyMixin.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/scopes/UUIDPrimaryKeyScope.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/scopes/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/scopes/scope.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/testing/BaseTestCaseSelectGrammar.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/testing/Database.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/testing/TestCase.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/testing/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/User.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/connections/test_base_connections.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/eagers/test_eager.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/models/test_models.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/mssql/builder/test_mssql_query_builder.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/mssql/builder/test_mssql_query_builder_relationships.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/mssql/grammar/test_mssql_delete_grammar.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/mssql/grammar/test_mssql_insert_grammar.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/mssql/grammar/test_mssql_qmark.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/mssql/grammar/test_mssql_select_grammar.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/mssql/grammar/test_mssql_update_grammar.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/mssql/schema/test_mssql_schema_builder.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/mssql/schema/test_mssql_schema_builder_alter.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/builder/test_mysql_builder_transaction.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/builder/test_query_builder.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/builder/test_query_builder_scopes.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/builder/test_transactions.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/connections/test_mysql_connection_selects.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/grammar/test_mysql_delete_grammar.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/grammar/test_mysql_insert_grammar.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/grammar/test_mysql_qmark.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/grammar/test_mysql_select_grammar.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/grammar/test_mysql_update_grammar.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/model/test_accessors_and_mutators.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/model/test_model.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/relationships/test_belongs_to_many.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/relationships/test_has_many_through.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/relationships/test_has_one_through.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/relationships/test_relationships.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/schema/test_mysql_schema_builder.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/schema/test_mysql_schema_builder_alter.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/scopes/test_can_use_global_scopes.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/scopes/test_can_use_scopes.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/scopes/test_soft_delete.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/postgres/builder/test_postgres_query_builder.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/postgres/builder/test_postgres_transaction.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/postgres/grammar/test_delete_grammar.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/postgres/grammar/test_insert_grammar.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/postgres/grammar/test_select_grammar.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/postgres/grammar/test_update_grammar.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/postgres/relationships/test_postgres_relationships.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/postgres/schema/test_postgres_schema_builder.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/postgres/schema/test_postgres_schema_builder_alter.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/scopes/test_default_global_scopes.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/seeds/test_seeds.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/masoniteorm.backup/tests/utils.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/mcp/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/mcp/argument.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/mcp/prompt.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/mcp/protocol.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/mcp/providers/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/mcp/providers/mcp_provider.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/mcp/request.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/mcp/resource.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/mcp/response.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/mcp/server.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/mcp/tool.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/process/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/process/exception.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/process/fake.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/process/process.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/process/result.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/providers/Provider.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/providers/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/providers/app_provider.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/storage/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/storage/config/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/storage/config/storage.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/storage/data/mime.types +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/storage/drivers/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/storage/drivers/fake.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/storage/drivers/local.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/storage/drivers/s3.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/storage/file.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/storage/filestream.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/storage/helper.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/storage/providers/provider.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/storage/storage.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/support/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/support/collection.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/support/string.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/testing/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/testing/test_case.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/utils/structures.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/vite/__init__.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/vite/config/vite.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/vite/exceptions.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/vite/providers/provider.py +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/vite/stubs/package.json +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/vite/stubs/resources/css/app.css +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/vite/stubs/resources/js/app.ts +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/vite/stubs/templates/index.html +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/vite/stubs/tsconfig.json +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/vite/stubs/vite.config.ts +0 -0
- {fastapi_startkit-0.40.1 → fastapi_startkit-0.41.0}/src/fastapi_startkit/vite/vite.py +0 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""fastapi_startkit.skills — AI skill & rules registry and adapters.
|
|
2
|
+
|
|
3
|
+
Skills and their nested rules both live under:
|
|
4
|
+
.ai/fastapi-startkit/<skill-name>/
|
|
5
|
+
SKILL.md
|
|
6
|
+
rules/
|
|
7
|
+
<rule-name>.md
|
|
8
|
+
|
|
9
|
+
Run ``artisan skills:sync`` to deploy skills, ``artisan rules:sync`` for rules.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from .registry import Skill, SkillRegistry, SKILLS_BASE_PATH, _parse_frontmatter
|
|
13
|
+
from .provider import SkillsServiceProvider
|
|
14
|
+
from .rules import Rule, RulesRegistry
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"Skill",
|
|
18
|
+
"SkillRegistry",
|
|
19
|
+
"SkillsServiceProvider",
|
|
20
|
+
"SKILLS_BASE_PATH",
|
|
21
|
+
"Rule",
|
|
22
|
+
"RulesRegistry",
|
|
23
|
+
"_parse_frontmatter",
|
|
24
|
+
]
|
|
@@ -0,0 +1,49 @@
|
|
|
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 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(self, skills: Sequence[Skill]) -> list[str]:
|
|
38
|
+
"""Write *skills* to the target format.
|
|
39
|
+
|
|
40
|
+
Returns a list of human-readable lines describing what was written
|
|
41
|
+
(suitable for printing in the ``skills:sync`` command).
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
@abstractmethod
|
|
45
|
+
def prune(self, skills: Sequence[Skill]) -> list[str]:
|
|
46
|
+
"""Remove previously-synced skills that are *not* in *skills*.
|
|
47
|
+
|
|
48
|
+
Returns a list of human-readable lines describing what was removed.
|
|
49
|
+
"""
|
|
@@ -0,0 +1,82 @@
|
|
|
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 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. Writes are
|
|
17
|
+
idempotent — the file is only (over)written when its content would change.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
name = "claude"
|
|
21
|
+
|
|
22
|
+
# ------------------------------------------------------------------
|
|
23
|
+
# Public API
|
|
24
|
+
# ------------------------------------------------------------------
|
|
25
|
+
|
|
26
|
+
def render(self, skills: Sequence[Skill]) -> list[str]:
|
|
27
|
+
messages: list[str] = []
|
|
28
|
+
for skill in skills:
|
|
29
|
+
dest = self._skill_path(skill.name)
|
|
30
|
+
content = self._build_content(skill)
|
|
31
|
+
written = self._write_idempotent(dest, content)
|
|
32
|
+
verb = "Synced" if written else "Unchanged"
|
|
33
|
+
messages.append(f"[claude] {verb} .claude/skills/{skill.name}/SKILL.md")
|
|
34
|
+
return messages
|
|
35
|
+
|
|
36
|
+
def prune(self, skills: Sequence[Skill]) -> list[str]:
|
|
37
|
+
"""Remove ``.claude/skills/<name>/`` dirs not represented in *skills*."""
|
|
38
|
+
messages: list[str] = []
|
|
39
|
+
known_names = {s.name for s in skills}
|
|
40
|
+
skills_root = self.base_path / ".claude" / "skills"
|
|
41
|
+
if not skills_root.is_dir():
|
|
42
|
+
return messages
|
|
43
|
+
|
|
44
|
+
for child in sorted(skills_root.iterdir()):
|
|
45
|
+
if child.is_dir() and child.name not in known_names:
|
|
46
|
+
import shutil
|
|
47
|
+
|
|
48
|
+
shutil.rmtree(child)
|
|
49
|
+
messages.append(f"[claude] Pruned .claude/skills/{child.name}/")
|
|
50
|
+
return messages
|
|
51
|
+
|
|
52
|
+
# ------------------------------------------------------------------
|
|
53
|
+
# Internal helpers
|
|
54
|
+
# ------------------------------------------------------------------
|
|
55
|
+
|
|
56
|
+
def _skill_path(self, skill_name: str) -> Path:
|
|
57
|
+
return self.base_path / ".claude" / "skills" / skill_name / "SKILL.md"
|
|
58
|
+
|
|
59
|
+
@staticmethod
|
|
60
|
+
def _build_content(skill: Skill) -> str:
|
|
61
|
+
"""Render the SKILL.md content for *skill*."""
|
|
62
|
+
lines = ["---", f"name: {skill.name}", f"description: {skill.description}", "---"]
|
|
63
|
+
if skill.body:
|
|
64
|
+
lines.append("")
|
|
65
|
+
lines.append(skill.body)
|
|
66
|
+
lines.append("")
|
|
67
|
+
return "\n".join(lines)
|
|
68
|
+
|
|
69
|
+
@staticmethod
|
|
70
|
+
def _write_idempotent(path: Path, content: str) -> bool:
|
|
71
|
+
"""Write *content* to *path* only if it differs.
|
|
72
|
+
|
|
73
|
+
Returns *True* when the file was (re)written, *False* when unchanged.
|
|
74
|
+
"""
|
|
75
|
+
if path.exists():
|
|
76
|
+
existing = path.read_text(encoding="utf-8")
|
|
77
|
+
if existing == content:
|
|
78
|
+
return False
|
|
79
|
+
|
|
80
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
81
|
+
path.write_text(content, encoding="utf-8")
|
|
82
|
+
return True
|
|
@@ -0,0 +1,102 @@
|
|
|
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 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(self, skills: Sequence[Skill]) -> list[str]:
|
|
36
|
+
gemini_md = self.base_path / "GEMINI.md"
|
|
37
|
+
new_section = self._build_section(skills)
|
|
38
|
+
changed = self._update_file(gemini_md, new_section)
|
|
39
|
+
verb = "Synced" if changed else "Unchanged"
|
|
40
|
+
return [f"[gemini] {verb} GEMINI.md ({len(skills)} skill(s))"]
|
|
41
|
+
|
|
42
|
+
def prune(self, skills: Sequence[Skill]) -> list[str]:
|
|
43
|
+
"""For Gemini, pruning just re-renders with the current skill list.
|
|
44
|
+
|
|
45
|
+
Since everything lives in a single file within a marked block,
|
|
46
|
+
rendering the new (shorter) list is equivalent to pruning.
|
|
47
|
+
"""
|
|
48
|
+
return self.render(skills)
|
|
49
|
+
|
|
50
|
+
# ------------------------------------------------------------------
|
|
51
|
+
# Internal helpers
|
|
52
|
+
# ------------------------------------------------------------------
|
|
53
|
+
|
|
54
|
+
def _build_section(self, skills: Sequence[Skill]) -> str:
|
|
55
|
+
"""Return the full marker block to inject into GEMINI.md."""
|
|
56
|
+
parts = [_MARKER_START]
|
|
57
|
+
for skill in skills:
|
|
58
|
+
parts.append(f"\n## {skill.name}\n")
|
|
59
|
+
if skill.description:
|
|
60
|
+
parts.append(f"{skill.description}\n")
|
|
61
|
+
if skill.body:
|
|
62
|
+
parts.append(f"\n{skill.body}\n")
|
|
63
|
+
parts.append(_MARKER_END)
|
|
64
|
+
return "\n".join(parts)
|
|
65
|
+
|
|
66
|
+
def _update_file(self, path: Path, section: str) -> bool:
|
|
67
|
+
"""Inject *section* into *path*, preserving content outside markers.
|
|
68
|
+
|
|
69
|
+
Returns *True* when the file was (re)written, *False* when unchanged.
|
|
70
|
+
"""
|
|
71
|
+
if path.exists():
|
|
72
|
+
original = path.read_text(encoding="utf-8")
|
|
73
|
+
else:
|
|
74
|
+
original = ""
|
|
75
|
+
|
|
76
|
+
new_content = self._splice(original, section)
|
|
77
|
+
|
|
78
|
+
if original == new_content:
|
|
79
|
+
return False
|
|
80
|
+
|
|
81
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
82
|
+
path.write_text(new_content, encoding="utf-8")
|
|
83
|
+
return True
|
|
84
|
+
|
|
85
|
+
@staticmethod
|
|
86
|
+
def _splice(original: str, section: str) -> str:
|
|
87
|
+
"""Replace the skills block inside *original* with *section*.
|
|
88
|
+
|
|
89
|
+
If the markers do not exist yet the section is appended to the file
|
|
90
|
+
(separated by a blank line).
|
|
91
|
+
"""
|
|
92
|
+
start_idx = original.find(_MARKER_START)
|
|
93
|
+
end_idx = original.find(_MARKER_END)
|
|
94
|
+
|
|
95
|
+
if start_idx != -1 and end_idx != -1 and end_idx > start_idx:
|
|
96
|
+
before = original[:start_idx]
|
|
97
|
+
after = original[end_idx + len(_MARKER_END) :]
|
|
98
|
+
return before + section + after
|
|
99
|
+
else:
|
|
100
|
+
# No markers yet — append
|
|
101
|
+
separator = "\n\n" if original and not original.endswith("\n\n") else ""
|
|
102
|
+
return original + separator + section + "\n"
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"""skills:list — list skills available from registered providers."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from fastapi_startkit.console import Command
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class SkillsListCommand(Command):
|
|
11
|
+
"""List all skills declared by the registered providers.
|
|
12
|
+
|
|
13
|
+
For each skill the command shows:
|
|
14
|
+
|
|
15
|
+
* provider key
|
|
16
|
+
* skill name
|
|
17
|
+
* description
|
|
18
|
+
* sync status for Claude Code and Gemini CLI
|
|
19
|
+
|
|
20
|
+
Example usage::
|
|
21
|
+
|
|
22
|
+
artisan skills:list
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
name = "skills:list"
|
|
26
|
+
description = "List skills declared by registered providers and their sync status."
|
|
27
|
+
|
|
28
|
+
def handle(self) -> int:
|
|
29
|
+
from fastapi_startkit.skills.registry import SkillRegistry
|
|
30
|
+
|
|
31
|
+
registry: SkillRegistry = self.container.make("skills.registry")
|
|
32
|
+
skills = registry.discover()
|
|
33
|
+
|
|
34
|
+
if not skills:
|
|
35
|
+
self.line("<comment>No skills found in any registered provider.</comment>")
|
|
36
|
+
return 0
|
|
37
|
+
|
|
38
|
+
base_path: Path = self.container.base_path
|
|
39
|
+
|
|
40
|
+
self.line("")
|
|
41
|
+
self.line(f" <info>Found {len(skills)} skill(s):</info>")
|
|
42
|
+
self.line("")
|
|
43
|
+
|
|
44
|
+
header = f" {'PROVIDER':<20} {'NAME':<25} {'CLAUDE':<10} {'GEMINI':<10} DESCRIPTION"
|
|
45
|
+
self.line(header)
|
|
46
|
+
self.line(" " + "-" * (len(header) - 2))
|
|
47
|
+
|
|
48
|
+
for skill in skills:
|
|
49
|
+
claude_status = self._claude_status(skill.name, base_path)
|
|
50
|
+
gemini_status = self._gemini_status(base_path)
|
|
51
|
+
|
|
52
|
+
desc = skill.description[:50] + "…" if len(skill.description) > 50 else skill.description
|
|
53
|
+
self.line(f" {skill.provider_key:<20} {skill.name:<25} {claude_status:<10} {gemini_status:<10} {desc}")
|
|
54
|
+
|
|
55
|
+
self.line("")
|
|
56
|
+
return 0
|
|
57
|
+
|
|
58
|
+
# ------------------------------------------------------------------
|
|
59
|
+
# Sync-status helpers
|
|
60
|
+
# ------------------------------------------------------------------
|
|
61
|
+
|
|
62
|
+
@staticmethod
|
|
63
|
+
def _claude_status(skill_name: str, base_path: Path) -> str:
|
|
64
|
+
skill_file = base_path / ".claude" / "skills" / skill_name / "SKILL.md"
|
|
65
|
+
return "synced" if skill_file.exists() else "pending"
|
|
66
|
+
|
|
67
|
+
@staticmethod
|
|
68
|
+
def _gemini_status(base_path: Path) -> str:
|
|
69
|
+
gemini_md = base_path / "GEMINI.md"
|
|
70
|
+
if not gemini_md.exists():
|
|
71
|
+
return "pending"
|
|
72
|
+
content = gemini_md.read_text(encoding="utf-8")
|
|
73
|
+
return "synced" if "<!-- skills:start -->" in content else "pending"
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"""skills:sync — sync provider skills to one or more agent targets."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from cleo.helpers import option
|
|
6
|
+
|
|
7
|
+
from fastapi_startkit.console import Command
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class SkillsSyncCommand(Command):
|
|
11
|
+
"""Sync provider skills into Claude Code / Gemini CLI skill files.
|
|
12
|
+
|
|
13
|
+
Example usage::
|
|
14
|
+
|
|
15
|
+
artisan skills:sync
|
|
16
|
+
artisan skills:sync --target=claude
|
|
17
|
+
artisan skills:sync --target=gemini --prune
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
name = "skills:sync"
|
|
21
|
+
description = "Sync provider-declared skills to AI agent skill files."
|
|
22
|
+
|
|
23
|
+
options = [
|
|
24
|
+
option(
|
|
25
|
+
"target",
|
|
26
|
+
"t",
|
|
27
|
+
flag=False,
|
|
28
|
+
default="all",
|
|
29
|
+
description="Target adapter: claude | gemini | all (default: all)",
|
|
30
|
+
),
|
|
31
|
+
option(
|
|
32
|
+
"prune",
|
|
33
|
+
None,
|
|
34
|
+
flag=True,
|
|
35
|
+
description="Remove skill files that are no longer declared by any provider.",
|
|
36
|
+
),
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
def handle(self) -> int:
|
|
40
|
+
from fastapi_startkit.skills.registry import SkillRegistry
|
|
41
|
+
|
|
42
|
+
registry: SkillRegistry = self.container.make("skills.registry")
|
|
43
|
+
skills = registry.discover()
|
|
44
|
+
|
|
45
|
+
target = (self.option("target") or "all").lower()
|
|
46
|
+
do_prune = bool(self.option("prune"))
|
|
47
|
+
base_path = self.container.base_path
|
|
48
|
+
|
|
49
|
+
adapters = self._resolve_adapters(target, base_path)
|
|
50
|
+
|
|
51
|
+
if not adapters:
|
|
52
|
+
self.line(f"<error>Unknown target '{target}'. Use: claude, gemini, all.</error>")
|
|
53
|
+
return 1
|
|
54
|
+
|
|
55
|
+
if not skills:
|
|
56
|
+
self.line(
|
|
57
|
+
"<comment>No skills found. Publish stubs first: artisan provider:publish --provider=skills</comment>"
|
|
58
|
+
)
|
|
59
|
+
return 0
|
|
60
|
+
|
|
61
|
+
self.line(f"<info>Found {len(skills)} skill(s). Syncing to: {target}…</info>")
|
|
62
|
+
self.line("")
|
|
63
|
+
|
|
64
|
+
for adapter in adapters:
|
|
65
|
+
messages = adapter.render(skills)
|
|
66
|
+
for msg in messages:
|
|
67
|
+
self.line(f" {msg}")
|
|
68
|
+
|
|
69
|
+
if do_prune:
|
|
70
|
+
prune_messages = adapter.prune(skills)
|
|
71
|
+
for msg in prune_messages:
|
|
72
|
+
self.line(f" {msg}")
|
|
73
|
+
|
|
74
|
+
self.line("")
|
|
75
|
+
self.line("<info>Done.</info>")
|
|
76
|
+
return 0
|
|
77
|
+
|
|
78
|
+
@staticmethod
|
|
79
|
+
def _resolve_adapters(target: str, base_path) -> list:
|
|
80
|
+
from fastapi_startkit.skills.adapters import ClaudeAdapter, GeminiAdapter
|
|
81
|
+
|
|
82
|
+
all_adapters = {
|
|
83
|
+
"claude": ClaudeAdapter,
|
|
84
|
+
"gemini": GeminiAdapter,
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if target == "all":
|
|
88
|
+
return [cls(base_path) for cls in all_adapters.values()]
|
|
89
|
+
|
|
90
|
+
cls = all_adapters.get(target)
|
|
91
|
+
return [cls(base_path)] if cls else []
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""SkillsServiceProvider — registers skills and rules into the application."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from fastapi_startkit.providers import Provider
|
|
8
|
+
|
|
9
|
+
_STUBS_DIR = Path(__file__).parent / "stubs"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class SkillsServiceProvider(Provider):
|
|
13
|
+
"""Service provider that bootstraps the skills and rules modules.
|
|
14
|
+
|
|
15
|
+
Publish starter files with::
|
|
16
|
+
|
|
17
|
+
artisan provider:publish --provider=skills
|
|
18
|
+
|
|
19
|
+
This copies:
|
|
20
|
+
- .ai/fastapi-startkit/fastapi-startkit/SKILL.md
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
provider_key = "skills"
|
|
24
|
+
|
|
25
|
+
def register(self) -> None:
|
|
26
|
+
from fastapi_startkit.skills.registry import SkillRegistry
|
|
27
|
+
from fastapi_startkit.skills.rules.registry import RulesRegistry
|
|
28
|
+
|
|
29
|
+
self.app.bind("skills.registry", SkillRegistry(self.app))
|
|
30
|
+
self.app.bind("rules.registry", RulesRegistry(self.app))
|
|
31
|
+
|
|
32
|
+
def boot(self) -> None:
|
|
33
|
+
from fastapi_startkit.skills.commands import SkillsSyncCommand, SkillsListCommand
|
|
34
|
+
from fastapi_startkit.skills.rules.commands import RulesSyncCommand, RulesListCommand
|
|
35
|
+
|
|
36
|
+
self.commands(
|
|
37
|
+
[
|
|
38
|
+
SkillsSyncCommand,
|
|
39
|
+
SkillsListCommand,
|
|
40
|
+
RulesSyncCommand,
|
|
41
|
+
RulesListCommand,
|
|
42
|
+
]
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
_skill_stub = _STUBS_DIR / ".ai" / "fastapi-startkit" / "fastapi-startkit"
|
|
46
|
+
self.publishes(
|
|
47
|
+
{
|
|
48
|
+
str(_skill_stub / "SKILL.md"): ".ai/fastapi-startkit/fastapi-startkit/SKILL.md",
|
|
49
|
+
},
|
|
50
|
+
tag="skills",
|
|
51
|
+
)
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"""SkillRegistry — discovers canonical skills from ``.ai/fastapi-startkit/``.
|
|
2
|
+
|
|
3
|
+
Each skill lives in a named subdirectory (or a ``SKILL.md`` directly under the
|
|
4
|
+
base) and carries a YAML front-matter block::
|
|
5
|
+
|
|
6
|
+
.ai/fastapi-startkit/
|
|
7
|
+
fastapi-startkit/
|
|
8
|
+
SKILL.md <- YAML frontmatter (name, description) + markdown body
|
|
9
|
+
rules/
|
|
10
|
+
http-client.md
|
|
11
|
+
|
|
12
|
+
Running ``artisan skills:sync`` deploys skills to every configured AI agent target.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
from dataclasses import dataclass, field
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
from typing import TYPE_CHECKING
|
|
20
|
+
|
|
21
|
+
if TYPE_CHECKING:
|
|
22
|
+
from fastapi_startkit.application import Application
|
|
23
|
+
|
|
24
|
+
#: Base directory for framework skills (relative to project root).
|
|
25
|
+
SKILLS_BASE_PATH = Path(".ai") / "fastapi-startkit"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@dataclass
|
|
29
|
+
class Skill:
|
|
30
|
+
"""Canonical skill metadata parsed from a SKILL.md file."""
|
|
31
|
+
|
|
32
|
+
name: str
|
|
33
|
+
description: str
|
|
34
|
+
path: Path
|
|
35
|
+
provider_key: str = "fastapi-startkit"
|
|
36
|
+
body: str = field(default="", repr=False)
|
|
37
|
+
metadata: dict = field(default_factory=dict, repr=False)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _parse_frontmatter(text: str) -> tuple[dict, str]:
|
|
41
|
+
"""Parse YAML front-matter. Returns (meta_dict, body_str)."""
|
|
42
|
+
lines = text.splitlines(keepends=True)
|
|
43
|
+
if not lines or lines[0].strip() != "---":
|
|
44
|
+
return {}, text
|
|
45
|
+
|
|
46
|
+
end_idx = None
|
|
47
|
+
for i, line in enumerate(lines[1:], start=1):
|
|
48
|
+
if line.strip() == "---":
|
|
49
|
+
end_idx = i
|
|
50
|
+
break
|
|
51
|
+
|
|
52
|
+
if end_idx is None:
|
|
53
|
+
return {}, text
|
|
54
|
+
|
|
55
|
+
fm_text = "".join(lines[1:end_idx])
|
|
56
|
+
body = "".join(lines[end_idx + 1 :])
|
|
57
|
+
|
|
58
|
+
try:
|
|
59
|
+
import yaml
|
|
60
|
+
|
|
61
|
+
meta = yaml.safe_load(fm_text) or {}
|
|
62
|
+
except ModuleNotFoundError:
|
|
63
|
+
meta = {}
|
|
64
|
+
for line in lines[1:end_idx]:
|
|
65
|
+
if ":" in line:
|
|
66
|
+
k, _, v = line.partition(":")
|
|
67
|
+
meta[k.strip()] = v.strip()
|
|
68
|
+
|
|
69
|
+
return meta, body
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class SkillRegistry:
|
|
73
|
+
"""Loads Skill objects from .ai/fastapi-startkit/*/SKILL.md."""
|
|
74
|
+
|
|
75
|
+
def __init__(self, app: "Application") -> None:
|
|
76
|
+
self._app = app
|
|
77
|
+
self._skills: list[Skill] | None = None
|
|
78
|
+
|
|
79
|
+
@property
|
|
80
|
+
def skills_base_path(self) -> Path:
|
|
81
|
+
return Path(self._app.base_path) / SKILLS_BASE_PATH
|
|
82
|
+
|
|
83
|
+
def discover(self) -> list[Skill]:
|
|
84
|
+
if self._skills is not None:
|
|
85
|
+
return self._skills
|
|
86
|
+
|
|
87
|
+
base = self.skills_base_path
|
|
88
|
+
if not base.is_dir():
|
|
89
|
+
self._skills = []
|
|
90
|
+
return self._skills
|
|
91
|
+
|
|
92
|
+
self._skills = []
|
|
93
|
+
for skill_md in sorted(base.rglob("SKILL.md")):
|
|
94
|
+
skill = self._load(skill_md)
|
|
95
|
+
if skill is not None:
|
|
96
|
+
self._skills.append(skill)
|
|
97
|
+
|
|
98
|
+
return self._skills
|
|
99
|
+
|
|
100
|
+
def get(self, name: str) -> "Skill | None":
|
|
101
|
+
return next((s for s in self.discover() if s.name == name), None)
|
|
102
|
+
|
|
103
|
+
def reset(self) -> None:
|
|
104
|
+
self._skills = None
|
|
105
|
+
|
|
106
|
+
@staticmethod
|
|
107
|
+
def _load(skill_md: Path) -> "Skill | None":
|
|
108
|
+
try:
|
|
109
|
+
text = skill_md.read_text(encoding="utf-8")
|
|
110
|
+
except OSError:
|
|
111
|
+
return None
|
|
112
|
+
|
|
113
|
+
meta, body = _parse_frontmatter(text)
|
|
114
|
+
name = (meta.get("name") or skill_md.parent.name or "").strip()
|
|
115
|
+
if not name:
|
|
116
|
+
return None
|
|
117
|
+
|
|
118
|
+
description = (meta.get("description") or "").strip()
|
|
119
|
+
extra = {k: v for k, v in meta.items() if k not in ("name", "description")}
|
|
120
|
+
return Skill(
|
|
121
|
+
name=name,
|
|
122
|
+
description=description,
|
|
123
|
+
path=skill_md,
|
|
124
|
+
body=body.strip(),
|
|
125
|
+
metadata=extra,
|
|
126
|
+
)
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"""Rules sub-system — per-topic rule files nested inside each skill directory.
|
|
2
|
+
|
|
3
|
+
Layout: .ai/fastapi-startkit/skill/<skill-name>/rules/<rule-name>.md
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from .registry import Rule, RulesRegistry, SKILLS_BASE_PATH
|
|
7
|
+
|
|
8
|
+
__all__ = ["Rule", "RulesRegistry", "SKILLS_BASE_PATH"]
|