winterforge 0.1.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 (392) hide show
  1. winterforge-0.1.0/PKG-INFO +19 -0
  2. winterforge-0.1.0/README.md +201 -0
  3. winterforge-0.1.0/pyproject.toml +96 -0
  4. winterforge-0.1.0/setup.cfg +4 -0
  5. winterforge-0.1.0/tests/test_acceptance.py +331 -0
  6. winterforge-0.1.0/tests/test_canonical_resolution.py +310 -0
  7. winterforge-0.1.0/tests/test_e2e_integration.py +287 -0
  8. winterforge-0.1.0/tests/test_initialization.py +215 -0
  9. winterforge-0.1.0/tests/test_user_system_integration.py +321 -0
  10. winterforge-0.1.0/winterforge/__init__.py +144 -0
  11. winterforge-0.1.0/winterforge/frags/__init__.py +35 -0
  12. winterforge-0.1.0/winterforge/frags/base.py +810 -0
  13. winterforge-0.1.0/winterforge/frags/composition.py +322 -0
  14. winterforge-0.1.0/winterforge/frags/field_helpers.py +194 -0
  15. winterforge-0.1.0/winterforge/frags/injectable.py +180 -0
  16. winterforge-0.1.0/winterforge/frags/manifest.py +636 -0
  17. winterforge-0.1.0/winterforge/frags/materialization.py +124 -0
  18. winterforge-0.1.0/winterforge/frags/mixins/__init__.py +5 -0
  19. winterforge-0.1.0/winterforge/frags/mixins/trait_mixin.py +112 -0
  20. winterforge-0.1.0/winterforge/frags/primitives/__init__.py +10 -0
  21. winterforge-0.1.0/winterforge/frags/primitives/_base.py +158 -0
  22. winterforge-0.1.0/winterforge/frags/primitives/affinity.py +108 -0
  23. winterforge-0.1.0/winterforge/frags/primitives/manager.py +88 -0
  24. winterforge-0.1.0/winterforge/frags/primitives/trait.py +96 -0
  25. winterforge-0.1.0/winterforge/frags/registries/__init__.py +5 -0
  26. winterforge-0.1.0/winterforge/frags/registries/affinity_registry.py +96 -0
  27. winterforge-0.1.0/winterforge/frags/registries/application_registry.py +56 -0
  28. winterforge-0.1.0/winterforge/frags/registries/config_registry.py +316 -0
  29. winterforge-0.1.0/winterforge/frags/registries/field_registry.py +218 -0
  30. winterforge-0.1.0/winterforge/frags/registries/frag_registry.py +592 -0
  31. winterforge-0.1.0/winterforge/frags/registries/permission_registry.py +170 -0
  32. winterforge-0.1.0/winterforge/frags/registries/profile_registry.py +153 -0
  33. winterforge-0.1.0/winterforge/frags/registries/role_registry.py +324 -0
  34. winterforge-0.1.0/winterforge/frags/registries/session_registry.py +198 -0
  35. winterforge-0.1.0/winterforge/frags/registries/trait_registry.py +96 -0
  36. winterforge-0.1.0/winterforge/frags/registries/user_registry.py +542 -0
  37. winterforge-0.1.0/winterforge/frags/scope.py +379 -0
  38. winterforge-0.1.0/winterforge/frags/traits/__init__.py +21 -0
  39. winterforge-0.1.0/winterforge/frags/traits/_field_info.py +130 -0
  40. winterforge-0.1.0/winterforge/frags/traits/_manager.py +413 -0
  41. winterforge-0.1.0/winterforge/frags/traits/api_builder.py +288 -0
  42. winterforge-0.1.0/winterforge/frags/traits/authenticatable.py +156 -0
  43. winterforge-0.1.0/winterforge/frags/traits/authorizable.py +230 -0
  44. winterforge-0.1.0/winterforge/frags/traits/budget_aware.py +107 -0
  45. winterforge-0.1.0/winterforge/frags/traits/cache_aware.py +116 -0
  46. winterforge-0.1.0/winterforge/frags/traits/clearable.py +22 -0
  47. winterforge-0.1.0/winterforge/frags/traits/cli_result.py +82 -0
  48. winterforge-0.1.0/winterforge/frags/traits/composable.py +237 -0
  49. winterforge-0.1.0/winterforge/frags/traits/emits_events.py +209 -0
  50. winterforge-0.1.0/winterforge/frags/traits/fieldable.py +623 -0
  51. winterforge-0.1.0/winterforge/frags/traits/has_data_source.py +111 -0
  52. winterforge-0.1.0/winterforge/frags/traits/has_data_target.py +140 -0
  53. winterforge-0.1.0/winterforge/frags/traits/has_permission.py +174 -0
  54. winterforge-0.1.0/winterforge/frags/traits/has_result.py +103 -0
  55. winterforge-0.1.0/winterforge/frags/traits/has_roles.py +239 -0
  56. winterforge-0.1.0/winterforge/frags/traits/http_request.py +112 -0
  57. winterforge-0.1.0/winterforge/frags/traits/http_response.py +86 -0
  58. winterforge-0.1.0/winterforge/frags/traits/index_generator.py +407 -0
  59. winterforge-0.1.0/winterforge/frags/traits/injectable.py +49 -0
  60. winterforge-0.1.0/winterforge/frags/traits/is_application.py +109 -0
  61. winterforge-0.1.0/winterforge/frags/traits/is_dirty.py +126 -0
  62. winterforge-0.1.0/winterforge/frags/traits/last_match.py +57 -0
  63. winterforge-0.1.0/winterforge/frags/traits/manifest.py +22 -0
  64. winterforge-0.1.0/winterforge/frags/traits/ownable.py +110 -0
  65. winterforge-0.1.0/winterforge/frags/traits/permissioned.py +155 -0
  66. winterforge-0.1.0/winterforge/frags/traits/persistable.py +442 -0
  67. winterforge-0.1.0/winterforge/frags/traits/profileable.py +211 -0
  68. winterforge-0.1.0/winterforge/frags/traits/queryable.py +101 -0
  69. winterforge-0.1.0/winterforge/frags/traits/registry.py +27 -0
  70. winterforge-0.1.0/winterforge/frags/traits/sessionable.py +188 -0
  71. winterforge-0.1.0/winterforge/frags/traits/sluggable.py +162 -0
  72. winterforge-0.1.0/winterforge/frags/traits/timestamped.py +162 -0
  73. winterforge-0.1.0/winterforge/frags/traits/titled.py +150 -0
  74. winterforge-0.1.0/winterforge/frags/traits/tokenable.py +88 -0
  75. winterforge-0.1.0/winterforge/frags/traits/typed.py +195 -0
  76. winterforge-0.1.0/winterforge/frags/traits/userable.py +126 -0
  77. winterforge-0.1.0/winterforge/frags/traits/with_history.py +282 -0
  78. winterforge-0.1.0/winterforge/installer/__init__.py +9 -0
  79. winterforge-0.1.0/winterforge/installer/bootstrap_config.py +86 -0
  80. winterforge-0.1.0/winterforge/installer/commands.py +858 -0
  81. winterforge-0.1.0/winterforge/installer/init_command.py +71 -0
  82. winterforge-0.1.0/winterforge/installer/profile_installer.py +319 -0
  83. winterforge-0.1.0/winterforge/installer/profiles.py +243 -0
  84. winterforge-0.1.0/winterforge/plugins/__init__.py +133 -0
  85. winterforge-0.1.0/winterforge/plugins/_base.py +483 -0
  86. winterforge-0.1.0/winterforge/plugins/_discovery.py +278 -0
  87. winterforge-0.1.0/winterforge/plugins/_manager_manager.py +109 -0
  88. winterforge-0.1.0/winterforge/plugins/_matchable.py +61 -0
  89. winterforge-0.1.0/winterforge/plugins/_protocols/__init__.py +143 -0
  90. winterforge-0.1.0/winterforge/plugins/_protocols/authentication.py +52 -0
  91. winterforge-0.1.0/winterforge/plugins/_protocols/bootstrapper.py +41 -0
  92. winterforge-0.1.0/winterforge/plugins/_protocols/counter.py +60 -0
  93. winterforge-0.1.0/winterforge/plugins/_protocols/email_provider.py +63 -0
  94. winterforge-0.1.0/winterforge/plugins/_protocols/hashing.py +55 -0
  95. winterforge-0.1.0/winterforge/plugins/_protocols/http.py +298 -0
  96. winterforge-0.1.0/winterforge/plugins/_protocols/identity.py +72 -0
  97. winterforge-0.1.0/winterforge/plugins/_protocols/output_redirect.py +29 -0
  98. winterforge-0.1.0/winterforge/plugins/_protocols/query_execution.py +142 -0
  99. winterforge-0.1.0/winterforge/plugins/_protocols/resolver.py +74 -0
  100. winterforge-0.1.0/winterforge/plugins/_protocols/session.py +78 -0
  101. winterforge-0.1.0/winterforge/plugins/_protocols/status_printer.py +57 -0
  102. winterforge-0.1.0/winterforge/plugins/_protocols/storage.py +198 -0
  103. winterforge-0.1.0/winterforge/plugins/_protocols/token_provider.py +80 -0
  104. winterforge-0.1.0/winterforge/plugins/_protocols/validator.py +32 -0
  105. winterforge-0.1.0/winterforge/plugins/auditors/__init__.py +9 -0
  106. winterforge-0.1.0/winterforge/plugins/auditors/_manager.py +24 -0
  107. winterforge-0.1.0/winterforge/plugins/auditors/orphaned_fields/__init__.py +224 -0
  108. winterforge-0.1.0/winterforge/plugins/authentication/__init__.py +9 -0
  109. winterforge-0.1.0/winterforge/plugins/authentication/manager.py +64 -0
  110. winterforge-0.1.0/winterforge/plugins/authentication/password_provider.py +107 -0
  111. winterforge-0.1.0/winterforge/plugins/bootstrap/__init__.py +8 -0
  112. winterforge-0.1.0/winterforge/plugins/bootstrap/application.py +127 -0
  113. winterforge-0.1.0/winterforge/plugins/bootstrap/bootstrap.py +28 -0
  114. winterforge-0.1.0/winterforge/plugins/bootstrap/bootstrapper_manager.py +42 -0
  115. winterforge-0.1.0/winterforge/plugins/bootstrap/database.py +97 -0
  116. winterforge-0.1.0/winterforge/plugins/bootstrap/env_var.py +97 -0
  117. winterforge-0.1.0/winterforge/plugins/bootstrap/framework_configuration.py +83 -0
  118. winterforge-0.1.0/winterforge/plugins/bootstrap/manager.py +139 -0
  119. winterforge-0.1.0/winterforge/plugins/bootstrap/materialization.py +60 -0
  120. winterforge-0.1.0/winterforge/plugins/bootstrap/plugin_configuration.py +66 -0
  121. winterforge-0.1.0/winterforge/plugins/bootstrap/yaml.py +63 -0
  122. winterforge-0.1.0/winterforge/plugins/cache/__init__.py +6 -0
  123. winterforge-0.1.0/winterforge/plugins/cache/_backend.py +126 -0
  124. winterforge-0.1.0/winterforge/plugins/cache/_listeners.py +49 -0
  125. winterforge-0.1.0/winterforge/plugins/cache/_manager.py +182 -0
  126. winterforge-0.1.0/winterforge/plugins/cache/lru/__init__.py +195 -0
  127. winterforge-0.1.0/winterforge/plugins/cache_warmers/__init__.py +13 -0
  128. winterforge-0.1.0/winterforge/plugins/cache_warmers/lazy.py +52 -0
  129. winterforge-0.1.0/winterforge/plugins/cache_warmers/manager.py +92 -0
  130. winterforge-0.1.0/winterforge/plugins/cache_warmers/none.py +48 -0
  131. winterforge-0.1.0/winterforge/plugins/cache_warmers/protocol.py +39 -0
  132. winterforge-0.1.0/winterforge/plugins/cache_warmers/scheduled.py +79 -0
  133. winterforge-0.1.0/winterforge/plugins/cli/__init__.py +5 -0
  134. winterforge-0.1.0/winterforge/plugins/cli/__main__.py +6 -0
  135. winterforge-0.1.0/winterforge/plugins/cli/_cli_commands.py +248 -0
  136. winterforge-0.1.0/winterforge/plugins/cli/_context.py +92 -0
  137. winterforge-0.1.0/winterforge/plugins/cli/_manager.py +466 -0
  138. winterforge-0.1.0/winterforge/plugins/cli/_validation.py +116 -0
  139. winterforge-0.1.0/winterforge/plugins/cli/main.py +175 -0
  140. winterforge-0.1.0/winterforge/plugins/counter/__init__.py +11 -0
  141. winterforge-0.1.0/winterforge/plugins/counter/database_synced.py +68 -0
  142. winterforge-0.1.0/winterforge/plugins/counter/fresh.py +49 -0
  143. winterforge-0.1.0/winterforge/plugins/counter/manager.py +56 -0
  144. winterforge-0.1.0/winterforge/plugins/data/__init__.py +8 -0
  145. winterforge-0.1.0/winterforge/plugins/data/_manager.py +24 -0
  146. winterforge-0.1.0/winterforge/plugins/data/yaml/__init__.py +664 -0
  147. winterforge-0.1.0/winterforge/plugins/decorators/__init__.py +928 -0
  148. winterforge-0.1.0/winterforge/plugins/decorators/_configs.py +163 -0
  149. winterforge-0.1.0/winterforge/plugins/decorators/_decorator_base.py +224 -0
  150. winterforge-0.1.0/winterforge/plugins/decorators/_http_endpoint_config.py +96 -0
  151. winterforge-0.1.0/winterforge/plugins/decorators/_manager.py +83 -0
  152. winterforge-0.1.0/winterforge/plugins/decorators/_provider.py +115 -0
  153. winterforge-0.1.0/winterforge/plugins/decorators/bootstrapper.py +54 -0
  154. winterforge-0.1.0/winterforge/plugins/decorators/cli_command.py +251 -0
  155. winterforge-0.1.0/winterforge/plugins/decorators/counter_provider.py +69 -0
  156. winterforge-0.1.0/winterforge/plugins/decorators/emits.py +225 -0
  157. winterforge-0.1.0/winterforge/plugins/decorators/http_endpoint.py +200 -0
  158. winterforge-0.1.0/winterforge/plugins/decorators/openapi.py +265 -0
  159. winterforge-0.1.0/winterforge/plugins/decorators/output_redirect.py +38 -0
  160. winterforge-0.1.0/winterforge/plugins/decorators/provider_type.py +275 -0
  161. winterforge-0.1.0/winterforge/plugins/decorators/root.py +172 -0
  162. winterforge-0.1.0/winterforge/plugins/decorators/scope.py +41 -0
  163. winterforge-0.1.0/winterforge/plugins/decorators/status_printer.py +46 -0
  164. winterforge-0.1.0/winterforge/plugins/decorators/version_root.py +94 -0
  165. winterforge-0.1.0/winterforge/plugins/email/__init__.py +11 -0
  166. winterforge-0.1.0/winterforge/plugins/email/console_provider.py +63 -0
  167. winterforge-0.1.0/winterforge/plugins/email/manager.py +67 -0
  168. winterforge-0.1.0/winterforge/plugins/email/smtp_provider.py +107 -0
  169. winterforge-0.1.0/winterforge/plugins/envoy/__init__.py +6 -0
  170. winterforge-0.1.0/winterforge/plugins/envoy/_manager.py +30 -0
  171. winterforge-0.1.0/winterforge/plugins/envoy/_protocol.py +178 -0
  172. winterforge-0.1.0/winterforge/plugins/envoy/claude.py +295 -0
  173. winterforge-0.1.0/winterforge/plugins/envoy/local_ollama.py +259 -0
  174. winterforge-0.1.0/winterforge/plugins/events/__init__.py +13 -0
  175. winterforge-0.1.0/winterforge/plugins/events/dispatcher_manager.py +65 -0
  176. winterforge-0.1.0/winterforge/plugins/events/dispatchers/__init__.py +5 -0
  177. winterforge-0.1.0/winterforge/plugins/events/dispatchers/event.py +60 -0
  178. winterforge-0.1.0/winterforge/plugins/events/listener_manager.py +143 -0
  179. winterforge-0.1.0/winterforge/plugins/events/provider_manager.py +44 -0
  180. winterforge-0.1.0/winterforge/plugins/exporters/__init__.py +5 -0
  181. winterforge-0.1.0/winterforge/plugins/exporters/manager.py +38 -0
  182. winterforge-0.1.0/winterforge/plugins/exporters/yaml_file.py +120 -0
  183. winterforge-0.1.0/winterforge/plugins/extensions/__init__.py +8 -0
  184. winterforge-0.1.0/winterforge/plugins/extensions/_installer.py +182 -0
  185. winterforge-0.1.0/winterforge/plugins/extensions/_manager.py +25 -0
  186. winterforge-0.1.0/winterforge/plugins/hashing/__init__.py +11 -0
  187. winterforge-0.1.0/winterforge/plugins/hashing/argon2_provider.py +77 -0
  188. winterforge-0.1.0/winterforge/plugins/hashing/bcrypt_provider.py +69 -0
  189. winterforge-0.1.0/winterforge/plugins/hashing/manager.py +75 -0
  190. winterforge-0.1.0/winterforge/plugins/http_app/__init__.py +10 -0
  191. winterforge-0.1.0/winterforge/plugins/http_app/fastapi_provider.py +532 -0
  192. winterforge-0.1.0/winterforge/plugins/http_app/manager.py +62 -0
  193. winterforge-0.1.0/winterforge/plugins/http_authenticator/__init__.py +17 -0
  194. winterforge-0.1.0/winterforge/plugins/http_authenticator/basic_authenticator.py +78 -0
  195. winterforge-0.1.0/winterforge/plugins/http_authenticator/bearer_authenticator.py +78 -0
  196. winterforge-0.1.0/winterforge/plugins/http_authenticator/manager.py +76 -0
  197. winterforge-0.1.0/winterforge/plugins/http_request/__init__.py +17 -0
  198. winterforge-0.1.0/winterforge/plugins/http_request/form_handler.py +95 -0
  199. winterforge-0.1.0/winterforge/plugins/http_request/json_handler.py +105 -0
  200. winterforge-0.1.0/winterforge/plugins/http_request/manager.py +68 -0
  201. winterforge-0.1.0/winterforge/plugins/http_response/__init__.py +17 -0
  202. winterforge-0.1.0/winterforge/plugins/http_response/json_handler.py +91 -0
  203. winterforge-0.1.0/winterforge/plugins/http_response/manager.py +73 -0
  204. winterforge-0.1.0/winterforge/plugins/http_response/xml_handler.py +146 -0
  205. winterforge-0.1.0/winterforge/plugins/identity/__init__.py +21 -0
  206. winterforge-0.1.0/winterforge/plugins/identity/email_resolver.py +37 -0
  207. winterforge-0.1.0/winterforge/plugins/identity/frag_id_resolver.py +58 -0
  208. winterforge-0.1.0/winterforge/plugins/identity/frag_resolver.py +66 -0
  209. winterforge-0.1.0/winterforge/plugins/identity/manager.py +134 -0
  210. winterforge-0.1.0/winterforge/plugins/identity/slug_resolver.py +78 -0
  211. winterforge-0.1.0/winterforge/plugins/identity/title_resolver.py +54 -0
  212. winterforge-0.1.0/winterforge/plugins/identity/username_resolver.py +41 -0
  213. winterforge-0.1.0/winterforge/plugins/identity/uuid_resolver.py +92 -0
  214. winterforge-0.1.0/winterforge/plugins/importers/__init__.py +5 -0
  215. winterforge-0.1.0/winterforge/plugins/importers/manager.py +37 -0
  216. winterforge-0.1.0/winterforge/plugins/importers/yaml_file.py +82 -0
  217. winterforge-0.1.0/winterforge/plugins/indexes/__init__.py +6 -0
  218. winterforge-0.1.0/winterforge/plugins/indexes/_backend.py +144 -0
  219. winterforge-0.1.0/winterforge/plugins/indexes/_manager.py +124 -0
  220. winterforge-0.1.0/winterforge/plugins/indexes/composite/__init__.py +223 -0
  221. winterforge-0.1.0/winterforge/plugins/indexes/hash/__init__.py +160 -0
  222. winterforge-0.1.0/winterforge/plugins/initializers/__init__.py +5 -0
  223. winterforge-0.1.0/winterforge/plugins/initializers/application.py +91 -0
  224. winterforge-0.1.0/winterforge/plugins/initializers/manager.py +67 -0
  225. winterforge-0.1.0/winterforge/plugins/input_prompts/__init__.py +31 -0
  226. winterforge-0.1.0/winterforge/plugins/input_prompts/interactive_cli.py +262 -0
  227. winterforge-0.1.0/winterforge/plugins/input_prompts/manager.py +66 -0
  228. winterforge-0.1.0/winterforge/plugins/input_prompts/protocols.py +88 -0
  229. winterforge-0.1.0/winterforge/plugins/input_prompts/silent.py +173 -0
  230. winterforge-0.1.0/winterforge/plugins/lifecycle.py +143 -0
  231. winterforge-0.1.0/winterforge/plugins/output_formatters/__init__.py +5 -0
  232. winterforge-0.1.0/winterforge/plugins/output_formatters/bootstrap.py +23 -0
  233. winterforge-0.1.0/winterforge/plugins/output_formatters/debug.py +74 -0
  234. winterforge-0.1.0/winterforge/plugins/output_formatters/default.py +84 -0
  235. winterforge-0.1.0/winterforge/plugins/output_formatters/json_formatter.py +77 -0
  236. winterforge-0.1.0/winterforge/plugins/output_formatters/manager.py +120 -0
  237. winterforge-0.1.0/winterforge/plugins/output_formatters/quiet.py +61 -0
  238. winterforge-0.1.0/winterforge/plugins/output_formatters/source/__init__.py +7 -0
  239. winterforge-0.1.0/winterforge/plugins/output_formatters/source/formatter_source.py +25 -0
  240. winterforge-0.1.0/winterforge/plugins/output_redirects/__init__.py +5 -0
  241. winterforge-0.1.0/winterforge/plugins/output_redirects/cli_output_redirect.py +27 -0
  242. winterforge-0.1.0/winterforge/plugins/output_redirects/manager.py +88 -0
  243. winterforge-0.1.0/winterforge/plugins/output_redirects/null_output_redirect.py +34 -0
  244. winterforge-0.1.0/winterforge/plugins/permissions/__init__.py +7 -0
  245. winterforge-0.1.0/winterforge/plugins/permissions/provider_manager.py +45 -0
  246. winterforge-0.1.0/winterforge/plugins/query/__init__.py +9 -0
  247. winterforge-0.1.0/winterforge/plugins/query/_manager.py +23 -0
  248. winterforge-0.1.0/winterforge/plugins/query/_operators.py +52 -0
  249. winterforge-0.1.0/winterforge/plugins/query/_repository.py +510 -0
  250. winterforge-0.1.0/winterforge/plugins/query/affinity.py +45 -0
  251. winterforge-0.1.0/winterforge/plugins/query/composition.py +57 -0
  252. winterforge-0.1.0/winterforge/plugins/query/condition/__init__.py +65 -0
  253. winterforge-0.1.0/winterforge/plugins/query/condition_group/__init__.py +118 -0
  254. winterforge-0.1.0/winterforge/plugins/query/execution/__init__.py +5 -0
  255. winterforge-0.1.0/winterforge/plugins/query/execution/_manager.py +45 -0
  256. winterforge-0.1.0/winterforge/plugins/query/execution/index/__init__.py +168 -0
  257. winterforge-0.1.0/winterforge/plugins/query/execution/memory/__init__.py +211 -0
  258. winterforge-0.1.0/winterforge/plugins/query/execution/storage/__init__.py +183 -0
  259. winterforge-0.1.0/winterforge/plugins/query/executor/__init__.py +135 -0
  260. winterforge-0.1.0/winterforge/plugins/query/join/__init__.py +71 -0
  261. winterforge-0.1.0/winterforge/plugins/query/limit/__init__.py +45 -0
  262. winterforge-0.1.0/winterforge/plugins/query/offset/__init__.py +45 -0
  263. winterforge-0.1.0/winterforge/plugins/query/orphaned/__init__.py +46 -0
  264. winterforge-0.1.0/winterforge/plugins/query/scope.py +73 -0
  265. winterforge-0.1.0/winterforge/plugins/query/sort/__init__.py +52 -0
  266. winterforge-0.1.0/winterforge/plugins/query/trait.py +45 -0
  267. winterforge-0.1.0/winterforge/plugins/repository.py +572 -0
  268. winterforge-0.1.0/winterforge/plugins/resolvers/__init__.py +5 -0
  269. winterforge-0.1.0/winterforge/plugins/resolvers/manager.py +41 -0
  270. winterforge-0.1.0/winterforge/plugins/session/__init__.py +11 -0
  271. winterforge-0.1.0/winterforge/plugins/session/frag_provider.py +151 -0
  272. winterforge-0.1.0/winterforge/plugins/session/jwt_provider.py +125 -0
  273. winterforge-0.1.0/winterforge/plugins/session/manager.py +132 -0
  274. winterforge-0.1.0/winterforge/plugins/slug_convertors/__init__.py +13 -0
  275. winterforge-0.1.0/winterforge/plugins/slug_convertors/bootstrap.py +20 -0
  276. winterforge-0.1.0/winterforge/plugins/slug_convertors/manager.py +115 -0
  277. winterforge-0.1.0/winterforge/plugins/slug_convertors/python_slug.py +42 -0
  278. winterforge-0.1.0/winterforge/plugins/slug_convertors/sql_slug.py +49 -0
  279. winterforge-0.1.0/winterforge/plugins/status_printers/__init__.py +10 -0
  280. winterforge-0.1.0/winterforge/plugins/status_printers/boolean_result_printer.py +138 -0
  281. winterforge-0.1.0/winterforge/plugins/status_printers/detailed_user_printer.py +85 -0
  282. winterforge-0.1.0/winterforge/plugins/status_printers/list_frag_printer.py +74 -0
  283. winterforge-0.1.0/winterforge/plugins/status_printers/manager.py +122 -0
  284. winterforge-0.1.0/winterforge/plugins/status_printers/none_result_printer.py +77 -0
  285. winterforge-0.1.0/winterforge/plugins/status_printers/single_frag_printer.py +134 -0
  286. winterforge-0.1.0/winterforge/plugins/status_printers/string_result_printer.py +107 -0
  287. winterforge-0.1.0/winterforge/plugins/storage/__init__.py +18 -0
  288. winterforge-0.1.0/winterforge/plugins/storage/_sql_base.py +327 -0
  289. winterforge-0.1.0/winterforge/plugins/storage/env.py +330 -0
  290. winterforge-0.1.0/winterforge/plugins/storage/manager.py +24 -0
  291. winterforge-0.1.0/winterforge/plugins/storage/postgresql.py +751 -0
  292. winterforge-0.1.0/winterforge/plugins/storage/sqlite.py +1081 -0
  293. winterforge-0.1.0/winterforge/plugins/storage/sqlite_old.py +999 -0
  294. winterforge-0.1.0/winterforge/plugins/storage/yaml.py +475 -0
  295. winterforge-0.1.0/winterforge/plugins/token/__init__.py +11 -0
  296. winterforge-0.1.0/winterforge/plugins/token/frag_provider.py +113 -0
  297. winterforge-0.1.0/winterforge/plugins/token/jwt_provider.py +123 -0
  298. winterforge-0.1.0/winterforge/plugins/token/manager.py +113 -0
  299. winterforge-0.1.0/winterforge/plugins/validators/__init__.py +13 -0
  300. winterforge-0.1.0/winterforge/plugins/validators/bootstrap.py +12 -0
  301. winterforge-0.1.0/winterforge/plugins/validators/email.py +70 -0
  302. winterforge-0.1.0/winterforge/plugins/validators/manager.py +103 -0
  303. winterforge-0.1.0/winterforge/plugins/validators/password_validators/__init__.py +19 -0
  304. winterforge-0.1.0/winterforge/plugins/validators/password_validators/simple.py +38 -0
  305. winterforge-0.1.0/winterforge/plugins/validators/password_validators/strong.py +61 -0
  306. winterforge-0.1.0/winterforge/plugins/validators/required.py +37 -0
  307. winterforge-0.1.0/winterforge/plugins/validators/username.py +192 -0
  308. winterforge-0.1.0/winterforge/protocols/__init__.py +26 -0
  309. winterforge-0.1.0/winterforge/protocols/collections.py +51 -0
  310. winterforge-0.1.0/winterforge/protocols/resolvable.py +72 -0
  311. winterforge-0.1.0/winterforge/testing/__init__.py +9 -0
  312. winterforge-0.1.0/winterforge/testing/cli.py +325 -0
  313. winterforge-0.1.0/winterforge/utils/__init__.py +5 -0
  314. winterforge-0.1.0/winterforge/utils/dependency_resolver.py +164 -0
  315. winterforge-0.1.0/winterforge/utils/naming.py +137 -0
  316. winterforge-0.1.0/winterforge/utils/signature.py +122 -0
  317. winterforge-0.1.0/winterforge/utils/sync.py +86 -0
  318. winterforge-0.1.0/winterforge.egg-info/PKG-INFO +19 -0
  319. winterforge-0.1.0/winterforge.egg-info/SOURCES.txt +390 -0
  320. winterforge-0.1.0/winterforge.egg-info/dependency_links.txt +1 -0
  321. winterforge-0.1.0/winterforge.egg-info/entry_points.txt +36 -0
  322. winterforge-0.1.0/winterforge.egg-info/requires.txt +14 -0
  323. winterforge-0.1.0/winterforge.egg-info/top_level.txt +3 -0
  324. winterforge-0.1.0/winterforge_channels/__init__.py +18 -0
  325. winterforge-0.1.0/winterforge_channels/cli/__init__.py +5 -0
  326. winterforge-0.1.0/winterforge_channels/cli/channel_commands.py +175 -0
  327. winterforge-0.1.0/winterforge_channels/frags/traits/__init__.py +19 -0
  328. winterforge-0.1.0/winterforge_channels/frags/traits/conversable.py +59 -0
  329. winterforge-0.1.0/winterforge_channels/frags/traits/messageable.py +75 -0
  330. winterforge-0.1.0/winterforge_channels/frags/traits/routable.py +54 -0
  331. winterforge-0.1.0/winterforge_channels/frags/traits/subscribable.py +90 -0
  332. winterforge-0.1.0/winterforge_channels/frags/traits/transportable.py +57 -0
  333. winterforge-0.1.0/winterforge_channels/plugins/transports/__init__.py +38 -0
  334. winterforge-0.1.0/winterforge_channels/plugins/transports/http_egress.py +163 -0
  335. winterforge-0.1.0/winterforge_channels/plugins/transports/http_ingress.py +122 -0
  336. winterforge-0.1.0/winterforge_channels/plugins/transports/managers.py +145 -0
  337. winterforge-0.1.0/winterforge_channels/plugins/transports/protocols.py +127 -0
  338. winterforge-0.1.0/winterforge_channels/plugins/transports/websocket_egress.py +202 -0
  339. winterforge-0.1.0/winterforge_channels/primitives/__init__.py +11 -0
  340. winterforge-0.1.0/winterforge_channels/primitives/channel.py +164 -0
  341. winterforge-0.1.0/winterforge_channels/primitives/message.py +162 -0
  342. winterforge-0.1.0/winterforge_channels/primitives/subscription.py +73 -0
  343. winterforge-0.1.0/winterforge_channels/py.typed +1 -0
  344. winterforge-0.1.0/winterforge_channels/registries/__init__.py +17 -0
  345. winterforge-0.1.0/winterforge_channels/registries/channel_registry.py +98 -0
  346. winterforge-0.1.0/winterforge_channels/registries/message_registry.py +138 -0
  347. winterforge-0.1.0/winterforge_channels/registries/subscription_registry.py +104 -0
  348. winterforge-0.1.0/winterforge_dx_tools/__init__.py +17 -0
  349. winterforge-0.1.0/winterforge_dx_tools/builder.py +154 -0
  350. winterforge-0.1.0/winterforge_dx_tools/cli/__init__.py +4 -0
  351. winterforge-0.1.0/winterforge_dx_tools/cli/commands.py +350 -0
  352. winterforge-0.1.0/winterforge_dx_tools/elements/__init__.py +15 -0
  353. winterforge-0.1.0/winterforge_dx_tools/elements/builder_panel.py +74 -0
  354. winterforge-0.1.0/winterforge_dx_tools/elements/builder_progress.py +81 -0
  355. winterforge-0.1.0/winterforge_dx_tools/elements/builder_table.py +100 -0
  356. winterforge-0.1.0/winterforge_dx_tools/elements/builder_tree.py +102 -0
  357. winterforge-0.1.0/winterforge_dx_tools/elements/manager.py +23 -0
  358. winterforge-0.1.0/winterforge_dx_tools/elements/panel.py +60 -0
  359. winterforge-0.1.0/winterforge_dx_tools/elements/progress.py +54 -0
  360. winterforge-0.1.0/winterforge_dx_tools/elements/table.py +76 -0
  361. winterforge-0.1.0/winterforge_dx_tools/elements/tree.py +79 -0
  362. winterforge-0.1.0/winterforge_dx_tools/formatters/__init__.py +9 -0
  363. winterforge-0.1.0/winterforge_dx_tools/formatters/manager.py +24 -0
  364. winterforge-0.1.0/winterforge_dx_tools/formatters/prettier.py +84 -0
  365. winterforge-0.1.0/winterforge_dx_tools/generators/__init__.py +1 -0
  366. winterforge-0.1.0/winterforge_dx_tools/generators/generator.py +132 -0
  367. winterforge-0.1.0/winterforge_dx_tools/generators/templates.py +54 -0
  368. winterforge-0.1.0/winterforge_dx_tools/graphql/__init__.py +1 -0
  369. winterforge-0.1.0/winterforge_dx_tools/graphql/resolver_factory.py +97 -0
  370. winterforge-0.1.0/winterforge_dx_tools/graphql/schema_generator.py +111 -0
  371. winterforge-0.1.0/winterforge_dx_tools/graphql/server.py +108 -0
  372. winterforge-0.1.0/winterforge_dx_tools/graphql/type_mapper.py +108 -0
  373. winterforge-0.1.0/winterforge_dx_tools/migrations/__init__.py +6 -0
  374. winterforge-0.1.0/winterforge_dx_tools/migrations/executor.py +189 -0
  375. winterforge-0.1.0/winterforge_dx_tools/migrations/generator.py +112 -0
  376. winterforge-0.1.0/winterforge_dx_tools/migrations/template.py +31 -0
  377. winterforge-0.1.0/winterforge_dx_tools/migrations/tracker.py +132 -0
  378. winterforge-0.1.0/winterforge_dx_tools/openapi/__init__.py +13 -0
  379. winterforge-0.1.0/winterforge_dx_tools/openapi/generator.py +168 -0
  380. winterforge-0.1.0/winterforge_dx_tools/openapi/schemas.py +135 -0
  381. winterforge-0.1.0/winterforge_dx_tools/server/__init__.py +7 -0
  382. winterforge-0.1.0/winterforge_dx_tools/server/app.py +78 -0
  383. winterforge-0.1.0/winterforge_dx_tools/server/endpoint_generator.py +144 -0
  384. winterforge-0.1.0/winterforge_dx_tools/server/request_handler.py +99 -0
  385. winterforge-0.1.0/winterforge_dx_tools/server/response_handler.py +89 -0
  386. winterforge-0.1.0/winterforge_dx_tools/testing/__init__.py +32 -0
  387. winterforge-0.1.0/winterforge_dx_tools/testing/assertions.py +169 -0
  388. winterforge-0.1.0/winterforge_dx_tools/testing/builders.py +221 -0
  389. winterforge-0.1.0/winterforge_dx_tools/testing/factories.py +189 -0
  390. winterforge-0.1.0/winterforge_dx_tools/utils/__init__.py +6 -0
  391. winterforge-0.1.0/winterforge_dx_tools/utils/http_method_detector.py +107 -0
  392. winterforge-0.1.0/winterforge_dx_tools/utils/introspection.py +80 -0
@@ -0,0 +1,19 @@
1
+ Metadata-Version: 2.4
2
+ Name: winterforge
3
+ Version: 0.1.0
4
+ Summary: AI-native framework with composable primitives
5
+ Author: Beau Simensen
6
+ Requires-Python: >=3.10
7
+ Requires-Dist: typing-extensions>=4.0.0
8
+ Requires-Dist: asyncpg>=0.29.0
9
+ Requires-Dist: pydantic>=2.0.0
10
+ Requires-Dist: pyyaml>=6.0
11
+ Requires-Dist: click>=8.1.7
12
+ Requires-Dist: argon2-cffi>=23.1.0
13
+ Requires-Dist: bcrypt>=4.1.2
14
+ Requires-Dist: PyJWT>=2.8.0
15
+ Provides-Extra: dev
16
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
17
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
18
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
19
+ Requires-Dist: mypy>=1.0.0; extra == "dev"
@@ -0,0 +1,201 @@
1
+ # WinterForge
2
+
3
+ **Async-first framework for composable data primitives.**
4
+
5
+ ---
6
+
7
+ ## Quick Start
8
+
9
+ ```python
10
+ from winterforge.frags import Frag
11
+ from winterforge.frags.registries import UserRegistry
12
+ from winterforge.plugins import discover_plugins, StorageManager
13
+
14
+ # Initialize
15
+ discover_plugins()
16
+ StorageManager.load_bootstrap()
17
+
18
+ # Create user
19
+ users = UserRegistry()
20
+ user = await users.create(
21
+ username='alice',
22
+ email='alice@example.com',
23
+ password='secure123'
24
+ )
25
+
26
+ # Query
27
+ user = await users.get('alice@example.com') # Email resolution
28
+ active = await users.verified_only().all() # Filter
29
+
30
+ # Create Frag
31
+ post = Frag(
32
+ affinities=['post', 'published'],
33
+ traits=['titled', 'timestamped', 'sluggable']
34
+ )
35
+
36
+ post.set_title("Hello World") \
37
+ .generate_slug("Hello World")
38
+
39
+ await post.save()
40
+ ```
41
+
42
+ ---
43
+
44
+ ## Core Concepts
45
+
46
+ ### Frags
47
+ Composable data primitives built from:
48
+ - **Affinities** - What it IS (tags: `['user', 'admin']`)
49
+ - **Traits** - What it CAN DO (behavior: `['titled', 'persistable']`)
50
+ - **Aliases** - Flexible metadata (relations: `{'employee_id': '12345'}`)
51
+
52
+ ### Registries
53
+ Query collections of Frags by composition.
54
+
55
+ ```python
56
+ users = UserRegistry()
57
+ admins = await users.with_role('admin').all()
58
+ ```
59
+
60
+ ### Storage
61
+ **SQLite**, **PostgreSQL**, **YAML**, **Env** backends.
62
+
63
+ ```python
64
+ storage = StorageManager.get('sqlite', db_path='app.db')
65
+ await storage.save(frag)
66
+ ```
67
+
68
+ ---
69
+
70
+ ## Installation
71
+
72
+ ```bash
73
+ pip install -e .
74
+ ```
75
+
76
+ ---
77
+
78
+ ## Testing
79
+
80
+ ```bash
81
+ # All tests
82
+ pytest
83
+
84
+ # Core tests (no PostgreSQL)
85
+ pytest --ignore=tests/frags/storage/test_postgresql_integration.py
86
+ ```
87
+
88
+ **Expected:** 581 passing, 1 warning (JWT dev secret)
89
+
90
+ ---
91
+
92
+ ## Documentation
93
+
94
+ - **Quick Start:** `QUICKSTART.md` - 5-minute introduction
95
+ - **Glossary:** `GLOSSARY.md` - Complete terminology reference
96
+ - **Handoff:** `HANDOFF.md` - Recent changes and architecture
97
+ - **Examples:** `examples/pkm/` - Personal knowledge management app
98
+
99
+ ---
100
+
101
+ ## Project Structure
102
+
103
+ ```
104
+ winterforge/
105
+ ├── frags/ # Frag core
106
+ │ ├── base.py # Frag class
107
+ │ ├── registry.py # FragRegistry
108
+ │ ├── traits/ # Built-in traits
109
+ │ └── registries/ # Specialized registries
110
+ ├── plugins/ # Plugin system
111
+ │ ├── storage/ # Storage backends
112
+ │ ├── identity/ # Identity resolvers
113
+ │ └── managers/ # Plugin managers
114
+ └── cli/ # CLI commands
115
+ ```
116
+
117
+ ---
118
+
119
+ ## Built-in Traits
120
+
121
+ - **titled** - title, subtitle
122
+ - **sluggable** - URL slugs
123
+ - **timestamped** - created_on, updated_on
124
+ - **persistable** - save(), delete(), is_new()
125
+ - **userable** - username, email, email_verified
126
+ - **authenticatable** - password hashing
127
+ - **authorizable** - roles, permissions
128
+ - **sessionable** - session management
129
+
130
+ ---
131
+
132
+ ## CLI
133
+
134
+ ```bash
135
+ # User management
136
+ winterforge user create alice alice@example.com
137
+ winterforge user add-role alice admin
138
+
139
+ # Session management
140
+ winterforge session create alice
141
+ winterforge session verify <token>
142
+
143
+ # Role/permission management
144
+ winterforge role create admin "Admin role"
145
+ winterforge permission create posts.create
146
+ ```
147
+
148
+ ---
149
+
150
+ ## Async-First
151
+
152
+ **All I/O operations are async:**
153
+
154
+ ```python
155
+ # Storage
156
+ await storage.save(frag)
157
+ frag = await storage.load(id)
158
+
159
+ # Frags
160
+ await frag.save()
161
+ await frag.delete()
162
+
163
+ # Registry
164
+ frag = await registry.get(identity)
165
+ all_frags = await registry.all()
166
+ ```
167
+
168
+ **Sync wrapper (rare):**
169
+
170
+ ```python
171
+ from winterforge.utils.sync import to_sync
172
+
173
+ @to_sync
174
+ async def create_user_sync(username, email):
175
+ users = UserRegistry()
176
+ return await users.create(username, email, 'password')
177
+
178
+ user = create_user_sync('alice', 'alice@example.com')
179
+ ```
180
+
181
+ ---
182
+
183
+ ## Architecture
184
+
185
+ - **Composition over inheritance** - Frags compose capabilities
186
+ - **Plugin-based** - Extensible via decorators
187
+ - **Async-first** - Modern Python standards
188
+ - **Everything is a Frag** - Even CLI output
189
+
190
+ ---
191
+
192
+ ## Status
193
+
194
+ **Version:** Pre-release (Phase 4 complete)
195
+ **Tests:** 581 passing
196
+ **Warnings:** 1 (expected)
197
+ **Ready for:** Feature development
198
+
199
+ ---
200
+
201
+ **WinterForge is async-first, composition-driven, and ready for production.**
@@ -0,0 +1,96 @@
1
+ [project]
2
+ name = "winterforge"
3
+ version = "0.1.0"
4
+ description = "AI-native framework with composable primitives"
5
+ authors = [{name = "Beau Simensen"}]
6
+ requires-python = ">=3.10"
7
+ dependencies = [
8
+ "typing-extensions>=4.0.0",
9
+ "asyncpg>=0.29.0",
10
+ "pydantic>=2.0.0",
11
+ "pyyaml>=6.0",
12
+ "click>=8.1.7",
13
+ "argon2-cffi>=23.1.0",
14
+ "bcrypt>=4.1.2",
15
+ "PyJWT>=2.8.0",
16
+ ]
17
+
18
+ [project.optional-dependencies]
19
+ dev = [
20
+ "pytest>=7.0.0",
21
+ "pytest-cov>=4.0.0",
22
+ "pytest-asyncio>=0.21.0",
23
+ "mypy>=1.0.0",
24
+ ]
25
+
26
+ [project.entry-points."winterforge.storage_backends"]
27
+ yaml = "winterforge.plugins.storage.yaml:YamlStorageBackend"
28
+ sqlite = "winterforge.plugins.storage.sqlite:SQLiteStorageBackend"
29
+ postgresql = "winterforge.plugins.storage.postgresql:PostgreSQLStorageBackend"
30
+
31
+ [project.entry-points."winterforge.identity_resolvers"]
32
+ frag_id = "winterforge.plugins.identity.frag_id_resolver:FragIdResolver"
33
+ slug = "winterforge.plugins.identity.slug_resolver:SlugResolver"
34
+ title = "winterforge.plugins.identity.title_resolver:TitleIdentityResolver"
35
+ uuid = "winterforge.plugins.identity.uuid_resolver:UuidResolver"
36
+ email = "winterforge.plugins.identity.email_resolver:EmailIdentityResolver"
37
+ username = "winterforge.plugins.identity.username_resolver:UsernameIdentityResolver"
38
+
39
+ [project.entry-points."winterforge.frag_traits"]
40
+ fieldable = "winterforge.frags.traits.fieldable:FieldableTrait"
41
+ titled = "winterforge.frags.traits.titled:TitledTrait"
42
+ typed = "winterforge.frags.traits.typed:TypedTrait"
43
+ timestamped = "winterforge.frags.traits.timestamped:TimestampedTrait"
44
+ sluggable = "winterforge.frags.traits.sluggable:SluggableTrait"
45
+ persistable = "winterforge.frags.traits.persistable:PersistableTrait"
46
+ userable = "winterforge.frags.traits.userable:UserableTrait"
47
+ authenticatable = "winterforge.frags.traits.authenticatable:AuthenticatableTrait"
48
+ authorizable = "winterforge.frags.traits.authorizable:AuthorizableTrait"
49
+ sessionable = "winterforge.frags.traits.sessionable:SessionableTrait"
50
+ tokenable = "winterforge.frags.traits.tokenable:TokenableTrait"
51
+ permissioned = "winterforge.frags.traits.permissioned:PermissionedTrait"
52
+ ownable = "winterforge.frags.traits.ownable:OwnableTrait"
53
+
54
+ [project.entry-points."winterforge.dx.elements"]
55
+ panel = "winterforge_dx_tools.elements.builder_panel:PanelElement"
56
+ table = "winterforge_dx_tools.elements.builder_table:TableElement"
57
+ progress = "winterforge_dx_tools.elements.builder_progress:ProgressElement"
58
+ tree = "winterforge_dx_tools.elements.builder_tree:TreeElement"
59
+
60
+ [project.scripts]
61
+ winterforge = "winterforge.cli:cli"
62
+
63
+ [build-system]
64
+ requires = ["setuptools>=65.0"]
65
+ build-backend = "setuptools.build_meta"
66
+
67
+ [tool.setuptools.packages.find]
68
+ where = ["."]
69
+ include = ["winterforge*"]
70
+ exclude = ["tests*", "mandates*", "winterforge_data*"]
71
+
72
+ [tool.pytest.ini_options]
73
+ testpaths = ["tests"]
74
+ python_files = ["test_*.py"]
75
+ python_classes = ["Test*"]
76
+ python_functions = ["test_*"]
77
+ asyncio_mode = "auto"
78
+
79
+ [tool.mypy]
80
+ python_version = "3.10"
81
+ warn_return_any = true
82
+ warn_unused_configs = true
83
+ disallow_untyped_defs = true
84
+
85
+ [tool.coverage.run]
86
+ source = ["winterforge"]
87
+ omit = ["tests/*"]
88
+
89
+ [tool.coverage.report]
90
+ exclude_lines = [
91
+ "pragma: no cover",
92
+ "def __repr__",
93
+ "raise AssertionError",
94
+ "raise NotImplementedError",
95
+ "if __name__ == .__main__.:",
96
+ ]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,331 @@
1
+ """
2
+ Acceptance criteria validation tests.
3
+
4
+ These tests validate that all acceptance criteria from the spec are met.
5
+ """
6
+
7
+ import pytest
8
+ from winterforge.plugins import (
9
+ storage_backend,
10
+ frag_trait,
11
+ deriver,
12
+ StorageManager,
13
+ FragTraitManager,
14
+ root,
15
+ )
16
+
17
+
18
+ class TestAcceptanceCriteria:
19
+ """Validate acceptance criteria from specification."""
20
+
21
+ def test_public_api_decorator_registration(self) -> None:
22
+ """
23
+ Acceptance: Public API works - decorator registration.
24
+
25
+ from winterforge.plugins import storage_backend, StorageManager
26
+
27
+ @storage_backend('test')
28
+ class TestBackend:
29
+ pass
30
+
31
+ backend = StorageManager.get('test')
32
+ assert backend is not None
33
+ """
34
+ StorageManager.reset()
35
+
36
+ @storage_backend()
37
+ @root('test-ac-1')
38
+ class TestBackend:
39
+ pass
40
+
41
+ backend = StorageManager.get('test-ac-1')
42
+ assert backend is not None
43
+ assert isinstance(backend, TestBackend)
44
+
45
+ def test_public_api_import_structure(self) -> None:
46
+ """
47
+ Acceptance: All components importable from top-level.
48
+ """
49
+ # Should be able to import everything from winterforge.plugins
50
+ from winterforge.plugins import (
51
+ PluginManagerBase,
52
+ plugin,
53
+ deriver,
54
+ storage_backend,
55
+ frag_trait,
56
+ identity_resolver,
57
+ StorageManager,
58
+ FragTraitManager,
59
+ IdentityResolverManager,
60
+ StorageBackend,
61
+ ReadOnlyStorage,
62
+ FragTrait,
63
+ IdentityResolverProvider,
64
+ discover_plugins,
65
+ )
66
+
67
+ # All imports successful
68
+ assert PluginManagerBase is not None
69
+ assert plugin is not None
70
+ assert deriver is not None
71
+ assert StorageManager is not None
72
+ assert ReadOnlyStorage is not None
73
+
74
+ def test_plugin_derivatives_work(self) -> None:
75
+ """
76
+ Acceptance: Plugin derivatives work.
77
+
78
+ from winterforge.plugins import deriver, StorageManager
79
+
80
+ @deriver('winterforge.storage_backends')
81
+ def test_deriver():
82
+ yield {'id': 'derived', 'class': object}
83
+
84
+ StorageManager.derive_plugins()
85
+ assert StorageManager.has('derived')
86
+ """
87
+ StorageManager.reset()
88
+
89
+ class DerivedClass:
90
+ pass
91
+
92
+ @deriver('winterforge.storage_backends')
93
+ def test_deriver_ac():
94
+ yield {'id': 'derived_ac', 'class': DerivedClass}
95
+
96
+ StorageManager.derive_plugins()
97
+ assert StorageManager.has('derived_ac')
98
+
99
+ instance = StorageManager.get('derived_ac')
100
+ assert isinstance(instance, DerivedClass)
101
+
102
+ def test_lazy_instantiation_with_caching(self) -> None:
103
+ """Acceptance: Lazy instantiation with caching works."""
104
+ StorageManager.reset()
105
+
106
+ instantiation_count = 0
107
+
108
+ @storage_backend()
109
+ @root('cached')
110
+ class CachedBackend:
111
+ def __init__(self):
112
+ nonlocal instantiation_count
113
+ instantiation_count += 1
114
+
115
+ # Not instantiated yet
116
+ assert instantiation_count == 0
117
+
118
+ # First access
119
+ instance1 = StorageManager.get('cached')
120
+ assert instantiation_count == 1
121
+
122
+ # Second access - cached
123
+ instance2 = StorageManager.get('cached')
124
+ assert instantiation_count == 1
125
+ assert instance1 is instance2
126
+
127
+ def test_metadata_support(self) -> None:
128
+ """Acceptance: Plugin metadata works."""
129
+ StorageManager.reset()
130
+
131
+ @storage_backend(description='Test', version='1.0')
132
+ @root('with-meta')
133
+ class MetaBackend:
134
+ pass
135
+
136
+ metadata = StorageManager.get_metadata('with-meta')
137
+ assert metadata['description'] == 'Test'
138
+ assert metadata['version'] == '1.0'
139
+
140
+ def test_manager_methods_work(self) -> None:
141
+ """Acceptance: All manager methods work correctly."""
142
+ StorageManager.reset()
143
+
144
+ @storage_backend()
145
+ @root('method-test')
146
+ class MethodTestBackend:
147
+ pass
148
+
149
+ # has()
150
+ assert StorageManager.has('method-test')
151
+
152
+ # get()
153
+ backend = StorageManager.get('method-test')
154
+ assert backend is not None
155
+
156
+ # get_definitions()
157
+ defs = StorageManager.get_definitions()
158
+ assert 'method-test' in defs
159
+
160
+ # get_metadata()
161
+ meta = StorageManager.get_metadata('method-test')
162
+ assert isinstance(meta, dict)
163
+
164
+ # clear_cache()
165
+ instance1 = StorageManager.get('method-test')
166
+ StorageManager.clear_cache()
167
+ instance2 = StorageManager.get('method-test')
168
+ assert instance1 is not instance2
169
+
170
+ # reset()
171
+ StorageManager.reset()
172
+ assert not StorageManager.has('method-test')
173
+
174
+ def test_trait_manager_get_trait_fields(self) -> None:
175
+ """Acceptance: FragTraitManager.get_trait_fields() works."""
176
+ FragTraitManager.reset()
177
+
178
+ class MockField:
179
+ pass
180
+
181
+ @frag_trait()
182
+ @root('fields-test')
183
+ class FieldsTrait:
184
+ # Use private attributes (new convention)
185
+ _field1 = MockField()
186
+ _field2 = MockField()
187
+
188
+ fields = FragTraitManager.get_trait_fields('fields-test')
189
+ assert '_field1' in fields
190
+ assert '_field2' in fields
191
+
192
+ def test_custom_instantiation_args(self) -> None:
193
+ """Acceptance: Custom instantiation args work (not cached)."""
194
+ StorageManager.reset()
195
+
196
+ @storage_backend()
197
+ @root('custom-args')
198
+ class CustomArgsBackend:
199
+ def __init__(self, value=None):
200
+ self.value = value
201
+
202
+ instance1 = StorageManager.get('custom-args', value='a')
203
+ instance2 = StorageManager.get('custom-args', value='b')
204
+
205
+ assert instance1.value == 'a'
206
+ assert instance2.value == 'b'
207
+ assert instance1 is not instance2
208
+
209
+ def test_all_plugin_types(self) -> None:
210
+ """Acceptance: All plugin types work."""
211
+ from winterforge.plugins import (
212
+ storage_backend,
213
+ frag_trait,
214
+ identity_resolver,
215
+ StorageManager,
216
+ FragTraitManager,
217
+ IdentityResolverManager,
218
+ root,
219
+ )
220
+
221
+ StorageManager.reset()
222
+ FragTraitManager.reset()
223
+ IdentityResolverManager.reset()
224
+
225
+ @storage_backend()
226
+ @root('storage-test')
227
+ class StorageTest:
228
+ pass
229
+
230
+ @frag_trait()
231
+ @root('trait-test')
232
+ class TraitTest:
233
+ pass
234
+
235
+ @identity_resolver()
236
+ @root('resolver-test')
237
+ class ResolverTest:
238
+ pass
239
+
240
+ assert StorageManager.has('storage-test')
241
+ assert FragTraitManager.has('trait-test')
242
+ assert IdentityResolverManager.has('resolver-test')
243
+
244
+ def test_error_handling(self) -> None:
245
+ """Acceptance: Proper error handling."""
246
+ StorageManager.reset()
247
+
248
+ # Duplicate registration is now idempotent (silently skips)
249
+ @storage_backend()
250
+ @root('dup-test')
251
+ class DupTest:
252
+ pass
253
+
254
+ # Second registration should silently succeed (idempotent)
255
+ StorageManager.register('dup-test', DupTest)
256
+ assert StorageManager.has('dup-test')
257
+
258
+ # Plugin not found
259
+ with pytest.raises(KeyError, match="not found"):
260
+ StorageManager.get('nonexistent')
261
+
262
+ # Trait not found
263
+ with pytest.raises(KeyError, match="not found"):
264
+ FragTraitManager.get_trait_fields('nonexistent')
265
+
266
+
267
+ class TestIntegrationScenarios:
268
+ """Test real-world integration scenarios."""
269
+
270
+ def test_complete_workflow(self) -> None:
271
+ """Test complete plugin workflow from registration to use."""
272
+ StorageManager.reset()
273
+
274
+ # 1. Register a plugin
275
+ @storage_backend(description='Test workflow')
276
+ @root('workflow-test')
277
+ class WorkflowBackend:
278
+ def __init__(self):
279
+ self.saved_items = []
280
+
281
+ def save(self, item):
282
+ self.saved_items.append(item)
283
+
284
+ # 2. Check registration
285
+ assert StorageManager.has('workflow-test')
286
+
287
+ # 3. Get instance
288
+ backend = StorageManager.get('workflow-test')
289
+
290
+ # 4. Use plugin
291
+ backend.save('item1')
292
+ backend.save('item2')
293
+
294
+ # 5. Verify caching
295
+ backend2 = StorageManager.get('workflow-test')
296
+ assert backend is backend2
297
+ assert len(backend2.saved_items) == 2
298
+
299
+ def test_derivative_workflow(self) -> None:
300
+ """Test complete derivative workflow."""
301
+ StorageManager.reset()
302
+
303
+ # 1. Define base class
304
+ class DatabaseBackend:
305
+ def __init__(self, config=None):
306
+ self.config = config
307
+
308
+ # 2. Register deriver
309
+ @deriver('winterforge.storage_backends')
310
+ def db_deriver():
311
+ configs = {'primary': {'host': 'localhost'}, 'backup': {'host': 'remote'}}
312
+ for name, config in configs.items():
313
+ yield {
314
+ 'id': f'db_{name}',
315
+ 'class': DatabaseBackend,
316
+ 'metadata': {'config': config}
317
+ }
318
+
319
+ # 3. Derive plugins
320
+ StorageManager.derive_plugins()
321
+
322
+ # 4. Verify derived plugins exist
323
+ assert StorageManager.has('db_primary')
324
+ assert StorageManager.has('db_backup')
325
+
326
+ # 5. Use derived plugins
327
+ primary = StorageManager.get('db_primary')
328
+ backup = StorageManager.get('db_backup')
329
+
330
+ assert isinstance(primary, DatabaseBackend)
331
+ assert isinstance(backup, DatabaseBackend)