karni-cli 0.4.0__tar.gz → 0.5.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 (584) hide show
  1. {karni_cli-0.4.0 → karni_cli-0.5.0}/.gitignore +7 -2
  2. {karni_cli-0.4.0 → karni_cli-0.5.0}/PKG-INFO +55 -9
  3. {karni_cli-0.4.0 → karni_cli-0.5.0}/README.md +51 -6
  4. {karni_cli-0.4.0 → karni_cli-0.5.0}/hatch_build.py +27 -2
  5. karni_cli-0.5.0/karni_cli/__init__.py +8 -0
  6. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_agent/__init__.py +4 -1
  7. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_agent/check.py +65 -19
  8. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_agent/overrides.py +1 -1
  9. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_agent/rules.py +472 -43
  10. karni_cli-0.5.0/karni_cli/_catalog/__init__.py +576 -0
  11. karni_cli-0.5.0/karni_cli/_catalog/__main__.py +30 -0
  12. karni_cli-0.5.0/karni_cli/_catalog/features/api_cache.toml +19 -0
  13. karni_cli-0.5.0/karni_cli/_catalog/features/email_code_login.toml +25 -0
  14. karni_cli-0.5.0/karni_cli/_catalog/features/social_login.toml +27 -0
  15. karni_cli-0.5.0/karni_cli/_catalog/features/terms.toml +28 -0
  16. karni_cli-0.5.0/karni_cli/_catalog/features/two_factor.toml +20 -0
  17. karni_cli-0.5.0/karni_cli/_catalog/features/user_grants.toml +21 -0
  18. karni_cli-0.5.0/karni_cli/_catalog/modules/karni-ai.toml +61 -0
  19. karni_cli-0.5.0/karni_cli/_catalog/modules/karni-approvals.toml +50 -0
  20. karni_cli-0.5.0/karni_cli/_catalog/modules/karni-charts.toml +34 -0
  21. karni_cli-0.5.0/karni_cli/_catalog/modules/karni-impersonation.toml +59 -0
  22. karni_cli-0.5.0/karni_cli/_catalog/modules/karni-payments.toml +56 -0
  23. karni_cli-0.5.0/karni_cli/_catalog/modules/karni-reports.toml +53 -0
  24. karni_cli-0.5.0/karni_cli/_catalog/modules/karni-site.toml +84 -0
  25. karni_cli-0.5.0/karni_cli/_catalog/modules/karni-storage.toml +67 -0
  26. karni_cli-0.5.0/karni_cli/_changelog/0.5.0.toml +819 -0
  27. karni_cli-0.5.0/karni_cli/_errorcodes/__init__.py +3202 -0
  28. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_errorcodes/failures.py +2 -2
  29. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_errorcodes/links.py +3 -1
  30. karni_cli-0.5.0/karni_cli/_settings/base.py +796 -0
  31. karni_cli-0.5.0/karni_cli/_settings/reference.py +491 -0
  32. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/cookiecutter.json +4 -2
  33. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/.dockerignore +1 -0
  34. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/.env.example +62 -3
  35. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/.gitignore +5 -0
  36. karni_cli-0.5.0/karni_cli/_templates/project/{{cookiecutter.project_slug}}/Dockerfile +112 -0
  37. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/Makefile +1 -1
  38. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/README.md +70 -26
  39. karni_cli-0.5.0/karni_cli/_templates/project/{{cookiecutter.project_slug}}/config/settings.py +69 -0
  40. karni_cli-0.5.0/karni_cli/_templates/project/{{cookiecutter.project_slug}}/config/urls.py +45 -0
  41. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/docker-compose.yml +9 -4
  42. karni_cli-0.5.0/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/.npmrc +15 -0
  43. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/index.html +1 -0
  44. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/package.json +10 -3
  45. karni_cli-0.5.0/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/src/layout.tsx +88 -0
  46. karni_cli-0.5.0/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/src/pages/home.tsx +31 -0
  47. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/src/routes.tsx +6 -1
  48. karni_cli-0.5.0/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/vite.config.ts +28 -0
  49. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/pyproject.toml +5 -0
  50. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/tests/test_smoke.py +5 -0
  51. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_ui/styles.css +16 -0
  52. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/adapters.py +160 -18
  53. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/agent_adapters.toml +23 -6
  54. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/agent_data.py +10 -0
  55. karni_cli-0.5.0/karni_cli/agent_tools.py +505 -0
  56. karni_cli-0.5.0/karni_cli/builder/__init__.py +21 -0
  57. karni_cli-0.5.0/karni_cli/builder/layout.py +83 -0
  58. karni_cli-0.5.0/karni_cli/builder/output.py +134 -0
  59. karni_cli-0.5.0/karni_cli/builder/record.py +215 -0
  60. karni_cli-0.5.0/karni_cli/builder/render.py +1155 -0
  61. karni_cli-0.5.0/karni_cli/builder/run.py +1111 -0
  62. karni_cli-0.5.0/karni_cli/catalog.py +274 -0
  63. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/clidoc.py +7 -5
  64. karni_cli-0.5.0/karni_cli/commands/add.py +463 -0
  65. karni_cli-0.5.0/karni_cli/commands/build.py +131 -0
  66. karni_cli-0.5.0/karni_cli/commands/check.py +430 -0
  67. karni_cli-0.5.0/karni_cli/commands/context.py +445 -0
  68. karni_cli-0.5.0/karni_cli/commands/design.py +246 -0
  69. karni_cli-0.5.0/karni_cli/commands/doctor.py +286 -0
  70. karni_cli-0.5.0/karni_cli/commands/explain.py +220 -0
  71. karni_cli-0.5.0/karni_cli/commands/import_design.py +608 -0
  72. karni_cli-0.5.0/karni_cli/commands/load.py +45 -0
  73. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/migrate.py +1 -1
  74. karni_cli-0.5.0/karni_cli/commands/modules.py +182 -0
  75. karni_cli-0.5.0/karni_cli/commands/new.py +697 -0
  76. karni_cli-0.5.0/karni_cli/commands/plan.py +155 -0
  77. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/queries.py +9 -2
  78. karni_cli-0.5.0/karni_cli/commands/recipes.py +196 -0
  79. karni_cli-0.5.0/karni_cli/commands/remove.py +402 -0
  80. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/rules.py +51 -5
  81. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/seed.py +13 -1
  82. karni_cli-0.5.0/karni_cli/commands/serve.py +164 -0
  83. karni_cli-0.5.0/karni_cli/commands/spec.py +191 -0
  84. karni_cli-0.5.0/karni_cli/commands/suggest.py +60 -0
  85. karni_cli-0.5.0/karni_cli/commands/types.py +142 -0
  86. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/ui.py +223 -10
  87. karni_cli-0.5.0/karni_cli/commands/worker.py +113 -0
  88. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/debugging.py +1 -1
  89. karni_cli-0.5.0/karni_cli/design/__init__.py +30 -0
  90. karni_cli-0.5.0/karni_cli/design/analyze.py +361 -0
  91. karni_cli-0.5.0/karni_cli/design/builder.py +2058 -0
  92. karni_cli-0.5.0/karni_cli/design/compare.py +603 -0
  93. karni_cli-0.5.0/karni_cli/design/editable.py +1717 -0
  94. karni_cli-0.5.0/karni_cli/design/extract.py +813 -0
  95. karni_cli-0.5.0/karni_cli/design/forms.py +602 -0
  96. karni_cli-0.5.0/karni_cli/design/hours.py +281 -0
  97. karni_cli-0.5.0/karni_cli/design/images.py +388 -0
  98. karni_cli-0.5.0/karni_cli/design/mapref.py +369 -0
  99. karni_cli-0.5.0/karni_cli/design/parse.py +411 -0
  100. karni_cli-0.5.0/karni_cli/design/proposal.py +708 -0
  101. karni_cli-0.5.0/karni_cli/design/regions.py +156 -0
  102. karni_cli-0.5.0/karni_cli/design/rewrite.py +534 -0
  103. karni_cli-0.5.0/karni_cli/design/scan.py +442 -0
  104. karni_cli-0.5.0/karni_cli/design/select.py +471 -0
  105. karni_cli-0.5.0/karni_cli/design/seo.py +70 -0
  106. karni_cli-0.5.0/karni_cli/design/site.py +1013 -0
  107. karni_cli-0.5.0/karni_cli/design/sources.py +712 -0
  108. karni_cli-0.5.0/karni_cli/design/values.py +475 -0
  109. karni_cli-0.5.0/karni_cli/envfile.py +69 -0
  110. karni_cli-0.5.0/karni_cli/errorcodes.py +1614 -0
  111. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/errordoc.py +74 -15
  112. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/__init__.py +8 -0
  113. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/apitest.py +140 -25
  114. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/app.py +4 -3
  115. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/core.py +19 -0
  116. karni_cli-0.5.0/karni_cli/generators/deploy.py +880 -0
  117. karni_cli-0.5.0/karni_cli/generators/external.py +234 -0
  118. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/fields.py +305 -69
  119. karni_cli-0.5.0/karni_cli/generators/form.py +1089 -0
  120. karni_cli-0.5.0/karni_cli/generators/introspect.py +493 -0
  121. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/model.py +218 -11
  122. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/module.py +36 -6
  123. karni_cli-0.5.0/karni_cli/generators/naming.py +225 -0
  124. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/page.py +256 -20
  125. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/serializer.py +3 -2
  126. karni_cli-0.5.0/karni_cli/generators/site.py +677 -0
  127. karni_cli-0.5.0/karni_cli/generators/view.py +219 -0
  128. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/viewset.py +76 -9
  129. karni_cli-0.5.0/karni_cli/kinds.py +253 -0
  130. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/local_state.py +13 -0
  131. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/main.py +35 -5
  132. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/mcp_server.py +71 -4
  133. karni_cli-0.5.0/karni_cli/module_codes.json +762 -0
  134. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/project.py +78 -18
  135. karni_cli-0.5.0/karni_cli/pyproject_edit.py +121 -0
  136. karni_cli-0.5.0/karni_cli/recipes/__init__.py +506 -0
  137. karni_cli-0.5.0/karni_cli/recipes/__main__.py +9 -0
  138. karni_cli-0.5.0/karni_cli/recipes/apply.py +114 -0
  139. karni_cli-0.5.0/karni_cli/recipes/booking/files/bookings/models.py +63 -0
  140. karni_cli-0.5.0/karni_cli/recipes/booking/files/bookings/tests/test_capacity.py +45 -0
  141. karni_cli-0.5.0/karni_cli/recipes/booking/files/bookings/viewsets.py +45 -0
  142. karni_cli-0.5.0/karni_cli/recipes/booking/karni.yaml +52 -0
  143. karni_cli-0.5.0/karni_cli/recipes/booking/recipe.toml +17 -0
  144. karni_cli-0.5.0/karni_cli/recipes/crm/files/crm/tests/test_pipeline.py +57 -0
  145. karni_cli-0.5.0/karni_cli/recipes/crm/files/crm/viewsets.py +39 -0
  146. karni_cli-0.5.0/karni_cli/recipes/crm/karni.yaml +80 -0
  147. karni_cli-0.5.0/karni_cli/recipes/crm/recipe.toml +18 -0
  148. karni_cli-0.5.0/karni_cli/recipes/data-portal/files/portal/seeds.py +157 -0
  149. karni_cli-0.5.0/karni_cli/recipes/data-portal/files/portal/tests/conftest.py +10 -0
  150. karni_cli-0.5.0/karni_cli/recipes/data-portal/files/portal/tests/test_portal.py +240 -0
  151. karni_cli-0.5.0/karni_cli/recipes/data-portal/karni.yaml +120 -0
  152. karni_cli-0.5.0/karni_cli/recipes/data-portal/recipe.toml +19 -0
  153. karni_cli-0.5.0/karni_cli/recipes/lms/files/courses/models.py +41 -0
  154. karni_cli-0.5.0/karni_cli/recipes/lms/files/courses/seeds.py +42 -0
  155. karni_cli-0.5.0/karni_cli/recipes/lms/files/courses/tests/test_completion.py +45 -0
  156. karni_cli-0.5.0/karni_cli/recipes/lms/files/courses/viewsets.py +30 -0
  157. karni_cli-0.5.0/karni_cli/recipes/lms/karni.yaml +73 -0
  158. karni_cli-0.5.0/karni_cli/recipes/lms/recipe.toml +16 -0
  159. karni_cli-0.5.0/karni_cli/recipes/marketplace/files/market/models.py +70 -0
  160. karni_cli-0.5.0/karni_cli/recipes/marketplace/files/market/tests/test_payouts.py +47 -0
  161. karni_cli-0.5.0/karni_cli/recipes/marketplace/files/market/viewsets.py +42 -0
  162. karni_cli-0.5.0/karni_cli/recipes/marketplace/karni.yaml +89 -0
  163. karni_cli-0.5.0/karni_cli/recipes/marketplace/recipe.toml +17 -0
  164. karni_cli-0.5.0/karni_cli/recipes/output.py +193 -0
  165. karni_cli-0.5.0/karni_cli/recipes/shop/files/shop/models.py +83 -0
  166. karni_cli-0.5.0/karni_cli/recipes/shop/files/shop/seeds.py +42 -0
  167. karni_cli-0.5.0/karni_cli/recipes/shop/files/shop/tests/test_checkout.py +55 -0
  168. karni_cli-0.5.0/karni_cli/recipes/shop/files/shop/viewsets.py +51 -0
  169. karni_cli-0.5.0/karni_cli/recipes/shop/karni.yaml +72 -0
  170. karni_cli-0.5.0/karni_cli/recipes/shop/recipe.toml +18 -0
  171. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/rules_render.py +18 -0
  172. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/scaffold.py +32 -1
  173. karni_cli-0.5.0/karni_cli/services.py +157 -0
  174. karni_cli-0.5.0/karni_cli/settingref.py +150 -0
  175. karni_cli-0.5.0/karni_cli/settings_edit.py +248 -0
  176. karni_cli-0.5.0/karni_cli/spec/__init__.py +17 -0
  177. karni_cli-0.5.0/karni_cli/spec/catalog.py +159 -0
  178. karni_cli-0.5.0/karni_cli/spec/edit.py +215 -0
  179. karni_cli-0.5.0/karni_cli/spec/emit.py +121 -0
  180. karni_cli-0.5.0/karni_cli/spec/export.py +1096 -0
  181. karni_cli-0.5.0/karni_cli/spec/navigation.py +283 -0
  182. karni_cli-0.5.0/karni_cli/spec/normal.py +277 -0
  183. karni_cli-0.5.0/karni_cli/spec/plan.py +1480 -0
  184. karni_cli-0.5.0/karni_cli/spec/questions.py +733 -0
  185. karni_cli-0.5.0/karni_cli/spec/schema.py +722 -0
  186. karni_cli-0.5.0/karni_cli/spec/source.py +102 -0
  187. karni_cli-0.5.0/karni_cli/spec/validate.py +2184 -0
  188. karni_cli-0.5.0/karni_cli/suggest.py +433 -0
  189. karni_cli-0.5.0/karni_cli/templateref.py +113 -0
  190. karni_cli-0.5.0/karni_cli/toolchain.py +87 -0
  191. karni_cli-0.5.0/karni_cli/typegen.py +201 -0
  192. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/uitheme/__init__.py +12 -3
  193. karni_cli-0.5.0/karni_cli/uitheme/colour.py +221 -0
  194. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/uitheme/css.py +41 -9
  195. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/uitheme/defaults.py +21 -1
  196. karni_cli-0.5.0/karni_cli/uitheme/plaincss.py +1192 -0
  197. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/uitheme/render.py +15 -5
  198. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/upgrades/v0_2/agent_guidance.py +6 -1
  199. karni_cli-0.5.0/karni_cli/upgrades/v0_5/urls_marker.py +61 -0
  200. karni_cli-0.5.0/karni_cli/urls_edit.py +120 -0
  201. {karni_cli-0.4.0 → karni_cli-0.5.0}/pyproject.toml +12 -6
  202. karni_cli-0.5.0/tests/__init__.py +0 -0
  203. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/conftest.py +39 -1
  204. karni_cli-0.5.0/tests/fixtures/designs/academy/admissions.html +60 -0
  205. karni_cli-0.5.0/tests/fixtures/designs/academy/css/bootstrap.css +12 -0
  206. karni_cli-0.5.0/tests/fixtures/designs/academy/css/school.css +2 -0
  207. karni_cli-0.5.0/tests/fixtures/designs/academy/img/garden.svg +1 -0
  208. karni_cli-0.5.0/tests/fixtures/designs/academy/index.html +33 -0
  209. karni_cli-0.5.0/tests/fixtures/designs/bakery/about.html +37 -0
  210. karni_cli-0.5.0/tests/fixtures/designs/bakery/contact.html +40 -0
  211. karni_cli-0.5.0/tests/fixtures/designs/bakery/css/site.css +2 -0
  212. karni_cli-0.5.0/tests/fixtures/designs/bakery/img/hero.jpg +0 -0
  213. karni_cli-0.5.0/tests/fixtures/designs/bakery/img/logo.svg +1 -0
  214. karni_cli-0.5.0/tests/fixtures/designs/bakery/img/oven.jpg +0 -0
  215. karni_cli-0.5.0/tests/fixtures/designs/bakery/img/pattern.png +0 -0
  216. karni_cli-0.5.0/tests/fixtures/designs/bakery/img/unused.png +0 -0
  217. karni_cli-0.5.0/tests/fixtures/designs/bakery/index.html +42 -0
  218. karni_cli-0.5.0/tests/fixtures/designs/bakery/js/app.js +1 -0
  219. karni_cli-0.5.0/tests/fixtures/designs/bakery/menu.html +40 -0
  220. karni_cli-0.5.0/tests/fixtures/designs/bakery/specials.html +9 -0
  221. karni_cli-0.5.0/tests/fixtures/designs/clinic/404.html +36 -0
  222. karni_cli-0.5.0/tests/fixtures/designs/clinic/css/bootstrap.min.css +1 -0
  223. karni_cli-0.5.0/tests/fixtures/designs/clinic/css/clinic.css +2 -0
  224. karni_cli-0.5.0/tests/fixtures/designs/clinic/css/fonts.css +1 -0
  225. karni_cli-0.5.0/tests/fixtures/designs/clinic/fonts/clinic.woff2 +0 -0
  226. karni_cli-0.5.0/tests/fixtures/designs/clinic/img/clinic.jpg +0 -0
  227. karni_cli-0.5.0/tests/fixtures/designs/clinic/img/old-logo.png +0 -0
  228. karni_cli-0.5.0/tests/fixtures/designs/clinic/index.html +37 -0
  229. karni_cli-0.5.0/tests/fixtures/designs/clinic/js/bootstrap.bundle.min.js +1 -0
  230. karni_cli-0.5.0/tests/fixtures/designs/clinic/services/dental.html +36 -0
  231. karni_cli-0.5.0/tests/fixtures/designs/clinic/services/eyes.html +36 -0
  232. karni_cli-0.5.0/tests/fixtures/designs/clinic/services/index.html +36 -0
  233. karni_cli-0.5.0/tests/fixtures/designs/clinic/team.html +29 -0
  234. karni_cli-0.5.0/tests/fixtures/designs/college/courses.html +27 -0
  235. karni_cli-0.5.0/tests/fixtures/designs/college/css/school.css +5 -0
  236. karni_cli-0.5.0/tests/fixtures/designs/college/img/badge.jpg +0 -0
  237. karni_cli-0.5.0/tests/fixtures/designs/college/img/campus.jpg +0 -0
  238. karni_cli-0.5.0/tests/fixtures/designs/college/img/campus.webp +0 -0
  239. karni_cli-0.5.0/tests/fixtures/designs/college/img/course-art.jpg +0 -0
  240. karni_cli-0.5.0/tests/fixtures/designs/college/img/course-music.png +0 -0
  241. karni_cli-0.5.0/tests/fixtures/designs/college/img/hero.jpg +0 -0
  242. karni_cli-0.5.0/tests/fixtures/designs/college/img/logo.svg +1 -0
  243. karni_cli-0.5.0/tests/fixtures/designs/college/img/share.jpg +0 -0
  244. karni_cli-0.5.0/tests/fixtures/designs/college/img/teacher.jpg +0 -0
  245. karni_cli-0.5.0/tests/fixtures/designs/college/index.html +32 -0
  246. karni_cli-0.5.0/tests/fixtures/designs/patisserie/contact.html +37 -0
  247. karni_cli-0.5.0/tests/fixtures/designs/patisserie/css/bootstrap.min.css +2 -0
  248. karni_cli-0.5.0/tests/fixtures/designs/patisserie/css/shop.css +2 -0
  249. karni_cli-0.5.0/tests/fixtures/designs/patisserie/img/baguette.jpg +0 -0
  250. karni_cli-0.5.0/tests/fixtures/designs/patisserie/img/carrot-cake.jpg +0 -0
  251. karni_cli-0.5.0/tests/fixtures/designs/patisserie/img/eclair.jpg +0 -0
  252. karni_cli-0.5.0/tests/fixtures/designs/patisserie/img/flat-white.jpg +0 -0
  253. karni_cli-0.5.0/tests/fixtures/designs/patisserie/img/lemon-tart.jpg +0 -0
  254. karni_cli-0.5.0/tests/fixtures/designs/patisserie/img/lemonade.jpg +0 -0
  255. karni_cli-0.5.0/tests/fixtures/designs/patisserie/img/rye.jpg +0 -0
  256. karni_cli-0.5.0/tests/fixtures/designs/patisserie/img/shop.jpg +0 -0
  257. karni_cli-0.5.0/tests/fixtures/designs/patisserie/img/sourdough.jpg +0 -0
  258. karni_cli-0.5.0/tests/fixtures/designs/patisserie/index.html +82 -0
  259. karni_cli-0.5.0/tests/fixtures/designs/patisserie/menu.html +157 -0
  260. karni_cli-0.5.0/tests/fixtures/designs/portfolio/img/bg.png +0 -0
  261. karni_cli-0.5.0/tests/fixtures/designs/portfolio/img/hero.jpg +0 -0
  262. karni_cli-0.5.0/tests/fixtures/designs/portfolio/img/hero.webp +0 -0
  263. karni_cli-0.5.0/tests/fixtures/designs/portfolio/img/shot-1x.jpg +0 -0
  264. karni_cli-0.5.0/tests/fixtures/designs/portfolio/img/shot-2x.jpg +0 -0
  265. karni_cli-0.5.0/tests/fixtures/designs/portfolio/index.html +40 -0
  266. karni_cli-0.5.0/tests/fixtures/designs/portfolio/scripts/reveal.js +1 -0
  267. karni_cli-0.5.0/tests/fixtures/designs/portfolio/styles/main.css +1 -0
  268. karni_cli-0.5.0/tests/fixtures/designs/practice/about.html +29 -0
  269. karni_cli-0.5.0/tests/fixtures/designs/practice/css/practice.css +3 -0
  270. karni_cli-0.5.0/tests/fixtures/designs/practice/doctors/ada-okoro.html +54 -0
  271. karni_cli-0.5.0/tests/fixtures/designs/practice/doctors/ben-lim.html +55 -0
  272. karni_cli-0.5.0/tests/fixtures/designs/practice/doctors/cara-diaz.html +54 -0
  273. karni_cli-0.5.0/tests/fixtures/designs/practice/img/ada.jpg +0 -0
  274. karni_cli-0.5.0/tests/fixtures/designs/practice/img/ben.jpg +0 -0
  275. karni_cli-0.5.0/tests/fixtures/designs/practice/img/cara.jpg +0 -0
  276. karni_cli-0.5.0/tests/fixtures/designs/practice/img/logo.png +0 -0
  277. karni_cli-0.5.0/tests/fixtures/designs/practice/img/waiting-room.jpg +0 -0
  278. karni_cli-0.5.0/tests/fixtures/designs/practice/index.html +61 -0
  279. karni_cli-0.5.0/tests/fixtures/designs/practice/treatments.html +54 -0
  280. karni_cli-0.5.0/tests/fixtures/designs/salon/css/salon.css +12 -0
  281. karni_cli-0.5.0/tests/fixtures/designs/salon/index.html +41 -0
  282. karni_cli-0.5.0/tests/fixtures/designs/school/courses/drawing.html +55 -0
  283. karni_cli-0.5.0/tests/fixtures/designs/school/courses/pottery.html +56 -0
  284. karni_cli-0.5.0/tests/fixtures/designs/school/courses/printing.html +53 -0
  285. karni_cli-0.5.0/tests/fixtures/designs/school/courses/weaving.html +54 -0
  286. karni_cli-0.5.0/tests/fixtures/designs/school/courses.html +65 -0
  287. karni_cli-0.5.0/tests/fixtures/designs/school/css/school.css +2 -0
  288. karni_cli-0.5.0/tests/fixtures/designs/school/img/drawing-1.jpg +0 -0
  289. karni_cli-0.5.0/tests/fixtures/designs/school/img/drawing-2.jpg +0 -0
  290. karni_cli-0.5.0/tests/fixtures/designs/school/img/drawing.jpg +0 -0
  291. karni_cli-0.5.0/tests/fixtures/designs/school/img/lena.jpg +0 -0
  292. karni_cli-0.5.0/tests/fixtures/designs/school/img/mia.jpg +0 -0
  293. karni_cli-0.5.0/tests/fixtures/designs/school/img/omar.jpg +0 -0
  294. karni_cli-0.5.0/tests/fixtures/designs/school/img/pottery-1.jpg +0 -0
  295. karni_cli-0.5.0/tests/fixtures/designs/school/img/pottery-2.jpg +0 -0
  296. karni_cli-0.5.0/tests/fixtures/designs/school/img/pottery-3.jpg +0 -0
  297. karni_cli-0.5.0/tests/fixtures/designs/school/img/pottery.jpg +0 -0
  298. karni_cli-0.5.0/tests/fixtures/designs/school/img/printing-1.jpg +0 -0
  299. karni_cli-0.5.0/tests/fixtures/designs/school/img/printing.jpg +0 -0
  300. karni_cli-0.5.0/tests/fixtures/designs/school/img/studio.jpg +0 -0
  301. karni_cli-0.5.0/tests/fixtures/designs/school/img/weaving-1.jpg +0 -0
  302. karni_cli-0.5.0/tests/fixtures/designs/school/img/weaving-2.jpg +0 -0
  303. karni_cli-0.5.0/tests/fixtures/designs/school/img/weaving.jpg +0 -0
  304. karni_cli-0.5.0/tests/fixtures/designs/school/index.html +56 -0
  305. karni_cli-0.5.0/tests/fixtures/designs/school/teachers.html +45 -0
  306. karni_cli-0.5.0/tests/fixtures/designs/studio/about.html +63 -0
  307. karni_cli-0.5.0/tests/fixtures/designs/studio/css/studio.css +2 -0
  308. karni_cli-0.5.0/tests/fixtures/designs/studio/img/about-1.jpg +0 -0
  309. karni_cli-0.5.0/tests/fixtures/designs/studio/img/about-2.jpg +0 -0
  310. karni_cli-0.5.0/tests/fixtures/designs/studio/img/ines.jpg +0 -0
  311. karni_cli-0.5.0/tests/fixtures/designs/studio/img/kiosk-2.jpg +0 -0
  312. karni_cli-0.5.0/tests/fixtures/designs/studio/img/kiosk.jpg +0 -0
  313. karni_cli-0.5.0/tests/fixtures/designs/studio/img/lakehouse-2.jpg +0 -0
  314. karni_cli-0.5.0/tests/fixtures/designs/studio/img/lakehouse-3.jpg +0 -0
  315. karni_cli-0.5.0/tests/fixtures/designs/studio/img/lakehouse.jpg +0 -0
  316. karni_cli-0.5.0/tests/fixtures/designs/studio/img/library-2.jpg +0 -0
  317. karni_cli-0.5.0/tests/fixtures/designs/studio/img/library-3.jpg +0 -0
  318. karni_cli-0.5.0/tests/fixtures/designs/studio/img/library.jpg +0 -0
  319. karni_cli-0.5.0/tests/fixtures/designs/studio/img/loft-2.jpg +0 -0
  320. karni_cli-0.5.0/tests/fixtures/designs/studio/img/loft.jpg +0 -0
  321. karni_cli-0.5.0/tests/fixtures/designs/studio/img/ola.jpg +0 -0
  322. karni_cli-0.5.0/tests/fixtures/designs/studio/img/slide-1.jpg +0 -0
  323. karni_cli-0.5.0/tests/fixtures/designs/studio/img/slide-2.jpg +0 -0
  324. karni_cli-0.5.0/tests/fixtures/designs/studio/img/slide-3.jpg +0 -0
  325. karni_cli-0.5.0/tests/fixtures/designs/studio/img/theo.jpg +0 -0
  326. karni_cli-0.5.0/tests/fixtures/designs/studio/img/yara.jpg +0 -0
  327. karni_cli-0.5.0/tests/fixtures/designs/studio/index.html +119 -0
  328. karni_cli-0.5.0/tests/fixtures/designs/studio/js/studio.js +1 -0
  329. karni_cli-0.5.0/tests/fixtures/spec/harbour-yoga.build.json +448 -0
  330. karni_cli-0.5.0/tests/fixtures/spec/harbour-yoga.plan.json +287 -0
  331. karni_cli-0.5.0/tests/fixtures/spec/harbour-yoga.yaml +60 -0
  332. karni_cli-0.5.0/tests/fixtures/ui/css/bakery/menu.css +36 -0
  333. karni_cli-0.5.0/tests/fixtures/ui/css/bootstrap/theme.css +39 -0
  334. karni_cli-0.5.0/tests/fixtures/ui/css/clinic/style.css +57 -0
  335. karni_cli-0.5.0/tests/fixtures/ui/css/night/theme.css +20 -0
  336. karni_cli-0.5.0/tests/fixtures/ui/css/portfolio/about.html +9 -0
  337. karni_cli-0.5.0/tests/fixtures/ui/css/portfolio/css/about.css +2 -0
  338. karni_cli-0.5.0/tests/fixtures/ui/css/portfolio/css/site.css +17 -0
  339. karni_cli-0.5.0/tests/fixtures/ui/css/portfolio/css/tokens.css +8 -0
  340. karni_cli-0.5.0/tests/fixtures/ui/css/portfolio/css/unused.css +2 -0
  341. karni_cli-0.5.0/tests/fixtures/ui/css/portfolio/index.html +14 -0
  342. karni_cli-0.5.0/tests/fixtures/ui/css/portfolio/vendor/normalize.css +4 -0
  343. karni_cli-0.5.0/tests/fixtures/ui/css/switching/app.css +27 -0
  344. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_adapters.py +142 -25
  345. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_add.py +47 -9
  346. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_agent_upgrade.py +6 -0
  347. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_audit_fixes.py +59 -2
  348. karni_cli-0.5.0/tests/test_bench_tokens.py +668 -0
  349. karni_cli-0.5.0/tests/test_benchmark.py +98 -0
  350. karni_cli-0.5.0/tests/test_build.py +1289 -0
  351. karni_cli-0.5.0/tests/test_catalog.py +567 -0
  352. karni_cli-0.5.0/tests/test_check.py +366 -0
  353. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_command_states.py +2 -1
  354. karni_cli-0.5.0/tests/test_context.py +366 -0
  355. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_database.py +3 -2
  356. karni_cli-0.5.0/tests/test_design_address.py +121 -0
  357. karni_cli-0.5.0/tests/test_design_analyze.py +658 -0
  358. karni_cli-0.5.0/tests/test_design_content.py +174 -0
  359. karni_cli-0.5.0/tests/test_design_extract.py +431 -0
  360. karni_cli-0.5.0/tests/test_design_hours.py +69 -0
  361. karni_cli-0.5.0/tests/test_design_terms.py +106 -0
  362. karni_cli-0.5.0/tests/test_docs_links.py +181 -0
  363. karni_cli-0.5.0/tests/test_docs_roadmap.py +60 -0
  364. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_doctor.py +93 -6
  365. karni_cli-0.5.0/tests/test_envfile.py +51 -0
  366. karni_cli-0.5.0/tests/test_errorcodes_cli.py +297 -0
  367. karni_cli-0.5.0/tests/test_explain_tags_and_map.py +123 -0
  368. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_history.py +3 -1
  369. karni_cli-0.5.0/tests/test_import_design.py +1004 -0
  370. karni_cli-0.5.0/tests/test_import_design_menu_rows.py +127 -0
  371. karni_cli-0.5.0/tests/test_import_design_seo.py +240 -0
  372. karni_cli-0.5.0/tests/test_kinds.py +518 -0
  373. karni_cli-0.5.0/tests/test_make.py +1317 -0
  374. karni_cli-0.5.0/tests/test_make_deploy.py +564 -0
  375. karni_cli-0.5.0/tests/test_make_external.py +216 -0
  376. karni_cli-0.5.0/tests/test_make_form.py +833 -0
  377. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_make_gate.py +346 -2
  378. karni_cli-0.5.0/tests/test_make_model_order_key.py +49 -0
  379. karni_cli-0.5.0/tests/test_make_model_pk.py +65 -0
  380. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_make_units.py +44 -2
  381. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_mcp.py +21 -2
  382. karni_cli-0.5.0/tests/test_model_plural.py +85 -0
  383. karni_cli-0.5.0/tests/test_module_migrations.py +55 -0
  384. karni_cli-0.5.0/tests/test_new.py +587 -0
  385. karni_cli-0.5.0/tests/test_new_app.py +320 -0
  386. karni_cli-0.5.0/tests/test_new_recipe.py +376 -0
  387. karni_cli-0.5.0/tests/test_plan.py +1232 -0
  388. karni_cli-0.5.0/tests/test_questions.py +612 -0
  389. karni_cli-0.5.0/tests/test_recipe_builds.py +74 -0
  390. karni_cli-0.5.0/tests/test_recipes.py +405 -0
  391. karni_cli-0.5.0/tests/test_release.py +537 -0
  392. karni_cli-0.5.0/tests/test_rules.py +278 -0
  393. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_runners.py +183 -7
  394. karni_cli-0.5.0/tests/test_services.py +254 -0
  395. karni_cli-0.5.0/tests/test_spec.py +1281 -0
  396. karni_cli-0.5.0/tests/test_spec_navigation.py +194 -0
  397. karni_cli-0.5.0/tests/test_speed.py +83 -0
  398. karni_cli-0.5.0/tests/test_suggest.py +474 -0
  399. karni_cli-0.5.0/tests/test_tool_names.py +101 -0
  400. karni_cli-0.5.0/tests/test_types.py +210 -0
  401. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_ui_detect.py +18 -0
  402. karni_cli-0.5.0/tests/test_ui_detect_css.py +458 -0
  403. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_upgrade.py +143 -5
  404. karni_cli-0.4.0/karni_cli/__init__.py +0 -3
  405. karni_cli-0.4.0/karni_cli/_errorcodes/__init__.py +0 -1635
  406. karni_cli-0.4.0/karni_cli/_templates/project/{{cookiecutter.project_slug}}/Caddyfile +0 -22
  407. karni_cli-0.4.0/karni_cli/_templates/project/{{cookiecutter.project_slug}}/Dockerfile +0 -53
  408. karni_cli-0.4.0/karni_cli/_templates/project/{{cookiecutter.project_slug}}/config/settings.py +0 -28
  409. karni_cli-0.4.0/karni_cli/_templates/project/{{cookiecutter.project_slug}}/config/urls.py +0 -31
  410. karni_cli-0.4.0/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/.npmrc +0 -7
  411. karni_cli-0.4.0/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/src/api/health.ts +0 -21
  412. karni_cli-0.4.0/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/src/layout.tsx +0 -52
  413. karni_cli-0.4.0/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/src/pages/home.tsx +0 -28
  414. karni_cli-0.4.0/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/vite.config.ts +0 -21
  415. karni_cli-0.4.0/karni_cli/commands/add.py +0 -144
  416. karni_cli-0.4.0/karni_cli/commands/check.py +0 -108
  417. karni_cli-0.4.0/karni_cli/commands/context.py +0 -172
  418. karni_cli-0.4.0/karni_cli/commands/doctor.py +0 -136
  419. karni_cli-0.4.0/karni_cli/commands/explain.py +0 -119
  420. karni_cli-0.4.0/karni_cli/commands/new.py +0 -114
  421. karni_cli-0.4.0/karni_cli/commands/serve.py +0 -53
  422. karni_cli-0.4.0/karni_cli/commands/types.py +0 -72
  423. karni_cli-0.4.0/karni_cli/commands/worker.py +0 -64
  424. karni_cli-0.4.0/karni_cli/errorcodes.py +0 -603
  425. karni_cli-0.4.0/karni_cli/generators/introspect.py +0 -263
  426. karni_cli-0.4.0/karni_cli/generators/naming.py +0 -100
  427. karni_cli-0.4.0/karni_cli/settings_edit.py +0 -128
  428. karni_cli-0.4.0/karni_cli/typegen.py +0 -101
  429. karni_cli-0.4.0/tests/test_check.py +0 -88
  430. karni_cli-0.4.0/tests/test_context.py +0 -134
  431. karni_cli-0.4.0/tests/test_errorcodes_cli.py +0 -138
  432. karni_cli-0.4.0/tests/test_make.py +0 -541
  433. karni_cli-0.4.0/tests/test_new.py +0 -284
  434. karni_cli-0.4.0/tests/test_rules.py +0 -158
  435. karni_cli-0.4.0/tests/test_types.py +0 -48
  436. {karni_cli-0.4.0 → karni_cli-0.5.0}/LICENSE +0 -0
  437. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_agent/__main__.py +0 -0
  438. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_agent/history.py +0 -0
  439. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_agent/history_chronicle.py +0 -0
  440. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_changelog/0.2.0.toml +0 -0
  441. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_changelog/0.3.0.toml +0 -0
  442. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_changelog/0.4.0.toml +0 -0
  443. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_changelog/__init__.py +0 -0
  444. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_errorcodes/__main__.py +0 -0
  445. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/config/__init__.py +0 -0
  446. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/config/asgi.py +0 -0
  447. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/config/celery.py +0 -0
  448. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/config/wsgi.py +0 -0
  449. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/.dockerignore +0 -0
  450. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/.jscpd.json +0 -0
  451. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/Dockerfile.dev +0 -0
  452. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/eslint.config.js +0 -0
  453. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/public/favicon.svg +0 -0
  454. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/src/App.tsx +0 -0
  455. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/src/index.css +0 -0
  456. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/src/main.tsx +0 -0
  457. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/src/vite-env.d.ts +0 -0
  458. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/tailwind.config.ts +0 -0
  459. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/tsconfig.json +0 -0
  460. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/manage.py +0 -0
  461. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/tests/__init__.py +0 -0
  462. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/tests/test_api_schema.py +0 -0
  463. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/brand.py +0 -0
  464. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/__init__.py +0 -0
  465. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/beat.py +0 -0
  466. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/config.py +0 -0
  467. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/createsuperuser.py +0 -0
  468. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/make.py +0 -0
  469. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/manage_passthrough.py +0 -0
  470. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/mcp.py +0 -0
  471. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/replay.py +0 -0
  472. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/routes.py +0 -0
  473. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/run_tests.py +0 -0
  474. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/schedule.py +0 -0
  475. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/schema.py +0 -0
  476. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/shell.py +0 -0
  477. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/sync_roles.py +0 -0
  478. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/trace.py +0 -0
  479. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/upgrade.py +0 -0
  480. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/why.py +0 -0
  481. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/config.py +0 -0
  482. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/database.py +0 -0
  483. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/db_probe.py +0 -0
  484. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/environment.py +0 -0
  485. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/explain_text.py +0 -0
  486. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/command.py +0 -0
  487. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/component.py +0 -0
  488. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/event.py +0 -0
  489. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/factory.py +0 -0
  490. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/lifecycle_fields.py +0 -0
  491. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/listener.py +0 -0
  492. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/middleware.py +0 -0
  493. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/migration.py +0 -0
  494. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/pysource.py +0 -0
  495. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/schedule.py +0 -0
  496. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/seeder.py +0 -0
  497. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/service.py +0 -0
  498. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/task.py +0 -0
  499. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/history.py +0 -0
  500. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/tips.py +0 -0
  501. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/uitheme/designsystems.py +0 -0
  502. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/uitheme/frontend.py +0 -0
  503. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/uitheme/jsobject.py +0 -0
  504. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/uitheme/model.py +0 -0
  505. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/uitheme/primitives.py +0 -0
  506. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/uitheme/shadcn.py +0 -0
  507. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/uitheme/tailwind.py +0 -0
  508. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/uitheme/wiring.py +0 -0
  509. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/upgrades/__init__.py +0 -0
  510. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/upgrades/changelog.py +0 -0
  511. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/upgrades/codemod.py +0 -0
  512. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/upgrades/engine.py +0 -0
  513. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/upgrades/legacy_agent_files.py +0 -0
  514. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/upgrades/python.py +0 -0
  515. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/upgrades/transforms/rename-export.cjs +0 -0
  516. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/upgrades/typescript.py +0 -0
  517. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/upgrades/v0_2/__init__.py +0 -0
  518. {karni_cli-0.4.0/tests → karni_cli-0.5.0/karni_cli/upgrades/v0_5}/__init__.py +0 -0
  519. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/upgrades/v1_0/__init__.py +0 -0
  520. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/upgrades/v1_0/all_objects_to_without.py +0 -0
  521. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/upgrades/v1_0/all_with_deleted_to_without.py +0 -0
  522. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/upgrades/v1_0/deleted_only_to_without_dead.py +0 -0
  523. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/upgrades/v1_0/object_permission_classes_to_access.py +0 -0
  524. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/upgrades/v1_0/related_lookups_to_optimize.py +0 -0
  525. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/upgrades/v1_0/scoped_related_lookups_to_optimize.py +0 -0
  526. {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/upgrades/v1_0/soft_delete_manager_mixin_to_scoped.py +0 -0
  527. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/schema.fixture.json +0 -0
  528. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/chakra/package.json +0 -0
  529. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/chakra/src/main.tsx +0 -0
  530. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/chakra/src/theme.ts +0 -0
  531. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/chakra3/package.json +0 -0
  532. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/chakra3/src/components/ui/theme.ts +0 -0
  533. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/chakra3/src/main.tsx +0 -0
  534. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/mantine/package.json +0 -0
  535. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/mantine/src/main.tsx +0 -0
  536. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/mantine/src/theme.ts +0 -0
  537. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/mui/package.json +0 -0
  538. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/mui/src/main.tsx +0 -0
  539. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/mui/src/theme/index.ts +0 -0
  540. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/plain/package.json +0 -0
  541. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/plain/src/index.css +0 -0
  542. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/plain/src/main.tsx +0 -0
  543. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw3/components.json +0 -0
  544. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw3/package.json +0 -0
  545. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw3/src/App.tsx +0 -0
  546. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw3/src/components/ui/button.tsx +0 -0
  547. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw3/src/components/ui/checkbox.tsx +0 -0
  548. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw3/src/components/ui/input.tsx +0 -0
  549. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw3/src/components/ui/label.tsx +0 -0
  550. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw3/src/components/ui/select.tsx +0 -0
  551. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw3/src/index.css +0 -0
  552. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw3/src/main.tsx +0 -0
  553. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw3/tailwind.config.js +0 -0
  554. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw3/tsconfig.json +0 -0
  555. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw4/components.json +0 -0
  556. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw4/package.json +0 -0
  557. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw4/src/App.tsx +0 -0
  558. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw4/src/components/ui/button.tsx +0 -0
  559. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw4/src/components/ui/select.tsx +0 -0
  560. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw4/src/components/ui/switch.tsx +0 -0
  561. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw4/src/components/ui/textarea.tsx +0 -0
  562. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw4/src/index.css +0 -0
  563. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw4/src/main.tsx +0 -0
  564. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw4/tsconfig.json +0 -0
  565. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/tailwind3/package.json +0 -0
  566. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/tailwind3/src/index.css +0 -0
  567. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/tailwind3/src/main.tsx +0 -0
  568. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/tailwind3/tailwind.config.ts +0 -0
  569. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/tailwind4/package.json +0 -0
  570. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/tailwind4/src/index.css +0 -0
  571. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/tailwind4/src/main.tsx +0 -0
  572. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/tailwind4/src/theme.css +0 -0
  573. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/upgrade_changelog/0.9.0.toml +0 -0
  574. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_brand.py +0 -0
  575. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_clidoc.py +0 -0
  576. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_debugging.py +0 -0
  577. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_docs_tutorial.py +0 -0
  578. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_explain_text.py +0 -0
  579. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_make_lifecycle.py +0 -0
  580. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_project.py +0 -0
  581. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_schema_cli.py +0 -0
  582. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_upgrade_codemods.py +0 -0
  583. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_upgrade_typescript.py +0 -0
  584. {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_why.py +0 -0
@@ -19,6 +19,8 @@ packages/karni-cli/karni_cli/_templates/
19
19
  packages/karni-cli/karni_cli/_agent/
20
20
  packages/karni-cli/karni_cli/_changelog/
21
21
  packages/karni-cli/karni_cli/_errorcodes/
22
+ packages/karni-cli/karni_cli/_settings/
23
+ packages/karni-cli/karni_cli/_catalog/
22
24
  packages/karni-cli/karni_cli/_ui/
23
25
 
24
26
  # Node
@@ -32,8 +34,11 @@ storybook-static/
32
34
  !.env.example
33
35
  .DS_Store
34
36
  .idea/
35
- .claude/scheduled_tasks.lock
36
- .claude/settings.local.json
37
37
 
38
38
  # MkDocs build output
39
39
  site/
40
+ .github/ci/prod_e2e/test-results/
41
+
42
+ # Contributors' own agent working files stay on their machines
43
+ /CLAUDE.md
44
+ /.claude/
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: karni-cli
3
- Version: 0.4.0
4
- Summary: The karni command: scaffold, generate, run and upgrade Karni projects. Karni is an open-source Django + React framework for building with AI coding agents. Your agent writes only your domain. The API, admin, permissions and React screens come from a package you upgrade, not code it rewrites in each project. One rule set covers Claude Code, Cursor and Copilot. The build fails when an agent hand-writes what Karni ships.
3
+ Version: 0.5.0
4
+ Summary: The karni command: scaffold, generate, run and upgrade Karni projects. Karni is an open-source Django + React framework for building with AI coding agents. Your agent writes only your domain. The API, admin, permissions and React screens come from a package you upgrade, not code it rewrites in each project. One rule set covers every coding agent. The build fails when an agent hand-writes what Karni ships.
5
5
  Project-URL: Homepage, https://github.com/cbsshekhawat18-lab/karni
6
6
  Project-URL: Documentation, https://cbsshekhawat18-lab.github.io/karni/
7
7
  Project-URL: Repository, https://github.com/cbsshekhawat18-lab/karni
@@ -10,7 +10,7 @@ Project-URL: Changelog, https://github.com/cbsshekhawat18-lab/karni/tree/main/do
10
10
  Author-email: Chandrabhan Shekhawat <cbsshekhawat18@gmail.com>
11
11
  License-Expression: Apache-2.0
12
12
  License-File: LICENSE
13
- Keywords: ai-agents,claude-code,cli,code-generation,cookiecutter,copilot,cursor,django,mcp,project-template,react,scaffolding
13
+ Keywords: ai-agents,cli,code-generation,cookiecutter,django,mcp,project-template,react,scaffolding
14
14
  Classifier: Development Status :: 3 - Alpha
15
15
  Classifier: Environment :: Console
16
16
  Classifier: Framework :: Django
@@ -29,6 +29,7 @@ Requires-Python: >=3.12
29
29
  Requires-Dist: cookiecutter>=2.5
30
30
  Requires-Dist: libcst>=1.4
31
31
  Requires-Dist: packaging>=24.0
32
+ Requires-Dist: pydantic>=2
32
33
  Requires-Dist: pyyaml>=6.0
33
34
  Requires-Dist: tomlkit>=0.12
34
35
  Requires-Dist: typer>=0.12
@@ -38,8 +39,45 @@ Description-Content-Type: text/markdown
38
39
 
39
40
  # karni-cli
40
41
 
41
- The `karni` command. It runs a Karni project's own `manage.py` as a
42
- subprocess, so the CLI itself never imports Django.
42
+ The karni command: scaffold, generate, run and upgrade Karni projects.
43
+
44
+ [![PyPI](https://img.shields.io/pypi/v/karni-cli)](https://pypi.org/project/karni-cli/) [![Python versions](https://img.shields.io/pypi/pyversions/karni-cli)](https://pypi.org/project/karni-cli/) [![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue)](https://github.com/cbsshekhawat18-lab/karni/blob/main/LICENSE) [![Docs](https://img.shields.io/badge/docs-online-FB5D08)](https://cbsshekhawat18-lab.github.io/karni/cli/)
45
+
46
+ It runs a project's own `manage.py` as a subprocess, so the CLI itself never imports Django. Karni's Python core is [`karni`](https://pypi.org/project/karni/) and its React side [`@karni/ui`](https://www.npmjs.com/package/@karni/ui).
47
+
48
+ ## Install
49
+
50
+ ```sh
51
+ pip install karni-cli
52
+ ```
53
+
54
+ ## A minimal example
55
+
56
+ The shop recipe, built on SQLite with no Docker:
57
+
58
+ ```sh
59
+ python3 -m venv .venv && . .venv/bin/activate
60
+ pip install karni karni-cli karni-payments pytest pytest-django
61
+ karni new "Corner Shop" --recipe shop && cd corner_shop
62
+ printf 'DATABASE_URL=sqlite:///data/db.sqlite3\nKARNI_CACHE=locmem\n' > .env
63
+ karni build
64
+ karni serve --local
65
+ ```
66
+
67
+ `karni build` runs the migrations, seeds demo data, generates the TypeScript types, and runs the tests and `karni check`. The [quickstart](https://cbsshekhawat18-lab.github.io/karni/quickstart/) does the same on PostgreSQL.
68
+
69
+ ## Main features
70
+
71
+ - **Start a project.** `karni new` scaffolds a site, an app or both, blank or from one of six [recipes](https://cbsshekhawat18-lab.github.io/karni/recipes/).
72
+ - **Build from a spec.** `karni spec validate`, `karni plan` and `karni build` turn `karni.yaml` into code ([the app spec](https://cbsshekhawat18-lab.github.io/karni/app-spec/)).
73
+ - **Generate.** `karni make app`, `model`, `page`, `schedule`, `task`, `site` and `form` write the files a project owns.
74
+ - **Modules.** `karni add` and `karni remove` wire a module in and out, and `karni modules` lists the catalog.
75
+ - **Run and check.** `karni serve`, `seed`, `migrate`, `test`, `types` and `check`, the last one failing the build when code rebuilds what Karni ships.
76
+ - **For coding agents.** `karni context`, `karni rules`, the procedures in AGENTS.md and `karni mcp`, the MCP server ([Karni for coding agents](https://cbsshekhawat18-lab.github.io/karni/agents/)).
77
+ - **Debugging.** `karni why`, `karni explain`, `karni trace`, `karni replay` and `karni queries` ([debugging](https://cbsshekhawat18-lab.github.io/karni/debugging/why/)).
78
+ - **Upgrades.** `karni upgrade` applies each release's codemods and lists what it could not change.
79
+
80
+ Every command and option is in [the karni command](https://cbsshekhawat18-lab.github.io/karni/cli/). A short list follows.
43
81
 
44
82
  ## Commands
45
83
  - `karni new <name>`: scaffold a project from the bundled cookiecutter
@@ -89,10 +127,9 @@ subprocess, so the CLI itself never imports Django.
89
127
  - `karni rules [--explain CODE | --procedure NAME | --check FILE... | --json]`:
90
128
  Karni's conventions from `karni.agent.rules` (no Django needed), and
91
129
  static single-file checks (exit 1 on violations).
92
- - `karni rules sync [--check] [--force]`: regenerate the thin agent adapters
93
- (AGENTS.md, CLAUDE.md, Cursor, Windsurf, Copilot, Cline, Aider, Junie) and
94
- slash commands from `karni_cli/agent_adapters.toml`. `--check` is the CI
95
- staleness gate.
130
+ - `karni rules sync [--check] [--force]`: regenerate AGENTS.md, the agent
131
+ instructions with the procedures for routine tasks, from
132
+ `karni_cli/agent_adapters.toml`. `--check` is the CI staleness gate.
96
133
  - `karni mcp`: context, rules and check as MCP tools
97
134
  (`pip install 'karni-cli[mcp]'`).
98
135
  - `karni upgrade [--to VERSION] [--from VERSION] [--dry-run] [--allow-dirty] [--list]`
@@ -197,3 +234,12 @@ joined by `|`.
197
234
  Commands that run the project resolve, in order: `--docker/--no-docker` flag →
198
235
  `<project>/.venv` → a running compose service (default `django`, changed with
199
236
  `--service` or `KARNI_COMPOSE_SERVICE`) → an error naming both remedies.
237
+
238
+ ## Links
239
+
240
+ - The karni command: <https://cbsshekhawat18-lab.github.io/karni/cli/>
241
+ - Quickstart: <https://cbsshekhawat18-lab.github.io/karni/quickstart/>
242
+ - Karni, the framework this package is part of: <https://github.com/cbsshekhawat18-lab/karni>
243
+ - Changelog: <https://github.com/cbsshekhawat18-lab/karni/blob/main/CHANGELOG.md>
244
+ - Issues: <https://github.com/cbsshekhawat18-lab/karni/issues>
245
+ - License: Apache-2.0. karni-cli is released with every other Karni package, at one version.
@@ -1,7 +1,44 @@
1
1
  # karni-cli
2
2
 
3
- The `karni` command. It runs a Karni project's own `manage.py` as a
4
- subprocess, so the CLI itself never imports Django.
3
+ The karni command: scaffold, generate, run and upgrade Karni projects.
4
+
5
+ [![PyPI](https://img.shields.io/pypi/v/karni-cli)](https://pypi.org/project/karni-cli/) [![Python versions](https://img.shields.io/pypi/pyversions/karni-cli)](https://pypi.org/project/karni-cli/) [![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue)](https://github.com/cbsshekhawat18-lab/karni/blob/main/LICENSE) [![Docs](https://img.shields.io/badge/docs-online-FB5D08)](https://cbsshekhawat18-lab.github.io/karni/cli/)
6
+
7
+ It runs a project's own `manage.py` as a subprocess, so the CLI itself never imports Django. Karni's Python core is [`karni`](https://pypi.org/project/karni/) and its React side [`@karni/ui`](https://www.npmjs.com/package/@karni/ui).
8
+
9
+ ## Install
10
+
11
+ ```sh
12
+ pip install karni-cli
13
+ ```
14
+
15
+ ## A minimal example
16
+
17
+ The shop recipe, built on SQLite with no Docker:
18
+
19
+ ```sh
20
+ python3 -m venv .venv && . .venv/bin/activate
21
+ pip install karni karni-cli karni-payments pytest pytest-django
22
+ karni new "Corner Shop" --recipe shop && cd corner_shop
23
+ printf 'DATABASE_URL=sqlite:///data/db.sqlite3\nKARNI_CACHE=locmem\n' > .env
24
+ karni build
25
+ karni serve --local
26
+ ```
27
+
28
+ `karni build` runs the migrations, seeds demo data, generates the TypeScript types, and runs the tests and `karni check`. The [quickstart](https://cbsshekhawat18-lab.github.io/karni/quickstart/) does the same on PostgreSQL.
29
+
30
+ ## Main features
31
+
32
+ - **Start a project.** `karni new` scaffolds a site, an app or both, blank or from one of six [recipes](https://cbsshekhawat18-lab.github.io/karni/recipes/).
33
+ - **Build from a spec.** `karni spec validate`, `karni plan` and `karni build` turn `karni.yaml` into code ([the app spec](https://cbsshekhawat18-lab.github.io/karni/app-spec/)).
34
+ - **Generate.** `karni make app`, `model`, `page`, `schedule`, `task`, `site` and `form` write the files a project owns.
35
+ - **Modules.** `karni add` and `karni remove` wire a module in and out, and `karni modules` lists the catalog.
36
+ - **Run and check.** `karni serve`, `seed`, `migrate`, `test`, `types` and `check`, the last one failing the build when code rebuilds what Karni ships.
37
+ - **For coding agents.** `karni context`, `karni rules`, the procedures in AGENTS.md and `karni mcp`, the MCP server ([Karni for coding agents](https://cbsshekhawat18-lab.github.io/karni/agents/)).
38
+ - **Debugging.** `karni why`, `karni explain`, `karni trace`, `karni replay` and `karni queries` ([debugging](https://cbsshekhawat18-lab.github.io/karni/debugging/why/)).
39
+ - **Upgrades.** `karni upgrade` applies each release's codemods and lists what it could not change.
40
+
41
+ Every command and option is in [the karni command](https://cbsshekhawat18-lab.github.io/karni/cli/). A short list follows.
5
42
 
6
43
  ## Commands
7
44
  - `karni new <name>`: scaffold a project from the bundled cookiecutter
@@ -51,10 +88,9 @@ subprocess, so the CLI itself never imports Django.
51
88
  - `karni rules [--explain CODE | --procedure NAME | --check FILE... | --json]`:
52
89
  Karni's conventions from `karni.agent.rules` (no Django needed), and
53
90
  static single-file checks (exit 1 on violations).
54
- - `karni rules sync [--check] [--force]`: regenerate the thin agent adapters
55
- (AGENTS.md, CLAUDE.md, Cursor, Windsurf, Copilot, Cline, Aider, Junie) and
56
- slash commands from `karni_cli/agent_adapters.toml`. `--check` is the CI
57
- staleness gate.
91
+ - `karni rules sync [--check] [--force]`: regenerate AGENTS.md, the agent
92
+ instructions with the procedures for routine tasks, from
93
+ `karni_cli/agent_adapters.toml`. `--check` is the CI staleness gate.
58
94
  - `karni mcp`: context, rules and check as MCP tools
59
95
  (`pip install 'karni-cli[mcp]'`).
60
96
  - `karni upgrade [--to VERSION] [--from VERSION] [--dry-run] [--allow-dirty] [--list]`
@@ -159,3 +195,12 @@ joined by `|`.
159
195
  Commands that run the project resolve, in order: `--docker/--no-docker` flag →
160
196
  `<project>/.venv` → a running compose service (default `django`, changed with
161
197
  `--service` or `KARNI_COMPOSE_SERVICE`) → an error naming both remedies.
198
+
199
+ ## Links
200
+
201
+ - The karni command: <https://cbsshekhawat18-lab.github.io/karni/cli/>
202
+ - Quickstart: <https://cbsshekhawat18-lab.github.io/karni/quickstart/>
203
+ - Karni, the framework this package is part of: <https://github.com/cbsshekhawat18-lab/karni>
204
+ - Changelog: <https://github.com/cbsshekhawat18-lab/karni/blob/main/CHANGELOG.md>
205
+ - Issues: <https://github.com/cbsshekhawat18-lab/karni/issues>
206
+ - License: Apache-2.0. karni-cli is released with every other Karni package, at one version.
@@ -11,10 +11,15 @@ to Karni's machine-readable changelog (packages/karni/karni/changelog ->
11
11
  karni_cli/_changelog), which `karni upgrade` reads: the CLI must know every
12
12
  change up to its own release, whatever karni the project has installed.
13
13
  Likewise Karni's error code registry (packages/karni/karni/errorcodes ->
14
- karni_cli/_errorcodes), which `karni explain` and error messages read, and
14
+ karni_cli/_errorcodes), which `karni explain` and error messages read, the
15
+ settings reference (packages/karni/karni/conf/reference.py and the base.py it
16
+ reads -> karni_cli/_settings), which `karni explain <SETTING>` reads, and
15
17
  @karni/ui's token stylesheet (packages/karni-ui/src/styles.css ->
16
18
  karni_cli/_ui/styles.css), whose defaults `karni ui detect` lists when a
17
- project has neither @karni/ui installed nor a monorepo checkout.
19
+ project has neither @karni/ui installed nor a monorepo checkout. And the
20
+ module catalog (packages/karni/karni/catalog -> karni_cli/_catalog, with a
21
+ copy of each module's karni.module.toml under _catalog/modules/), so
22
+ `karni modules list` shows the modules a project has not installed.
18
23
  """
19
24
 
20
25
  from __future__ import annotations
@@ -52,6 +57,15 @@ class TemplateBundleHook(BuildHookInterface):
52
57
  self._bundle_karni(pkg_root, "agent", "_agent", "agent rules", build_data)
53
58
  self._bundle_karni(pkg_root, "changelog", "_changelog", "changelog", build_data)
54
59
  self._bundle_karni(pkg_root, "errorcodes", "_errorcodes", "error codes", build_data)
60
+ self._bundle_karni(pkg_root, "catalog", "_catalog", "module catalog", build_data)
61
+ manifests = sorted(pkg_root.parent.parent.glob("modules/*/karni_*/karni.module.toml"))
62
+ bundled_modules = pkg_root / "karni_cli" / "_catalog" / "modules"
63
+ if manifests:
64
+ bundled_modules.mkdir(parents=True, exist_ok=True)
65
+ for manifest in manifests:
66
+ shutil.copy2(manifest, bundled_modules / f"{manifest.parent.parent.name}.toml")
67
+ elif not bundled_modules.is_dir():
68
+ raise RuntimeError("No module manifests to bundle into karni_cli/_catalog/modules.")
55
69
  # karni.links (every published URL, stdlib only) rides inside the
56
70
  # errorcodes bundle: the registry loads it by path when karni is absent.
57
71
  links = pkg_root.parent / "karni" / "karni" / "links.py"
@@ -61,6 +75,17 @@ class TemplateBundleHook(BuildHookInterface):
61
75
  elif not bundled_links.is_file():
62
76
  raise RuntimeError("No karni/links.py to bundle into karni_cli/_errorcodes.")
63
77
 
78
+ # The settings reference (stdlib only) and the file it reads: `karni explain <SETTING>`.
79
+ settings_bundle = pkg_root / "karni_cli" / "_settings"
80
+ conf = pkg_root.parent / "karni" / "karni" / "conf"
81
+ if (conf / "reference.py").is_file():
82
+ settings_bundle.mkdir(parents=True, exist_ok=True)
83
+ for name in ("reference.py", "base.py"):
84
+ shutil.copy2(conf / name, settings_bundle / name)
85
+ elif not (settings_bundle / "reference.py").is_file():
86
+ raise RuntimeError("No karni/conf/reference.py to bundle into karni_cli/_settings.")
87
+ build_data["artifacts"].append("karni_cli/_settings/")
88
+
64
89
  styles = pkg_root.parent / "karni-ui" / "src" / "styles.css"
65
90
  bundled_styles = pkg_root / "karni_cli" / "_ui" / "styles.css"
66
91
  if styles.is_file():
@@ -0,0 +1,8 @@
1
+ """karni-cli — the ``karni`` command."""
2
+
3
+ from importlib import metadata as _metadata
4
+
5
+ try:
6
+ __version__ = _metadata.version("karni-cli") # [project] version in pyproject.toml
7
+ except _metadata.PackageNotFoundError: # a source tree on sys.path, never installed
8
+ __version__ = "0+unknown"
@@ -16,7 +16,7 @@ from typing import Any
16
16
  from .check import check_file, check_source, supported
17
17
  from .history import active_conditions
18
18
  from .overrides import OVERRIDE_FILE, OverrideError, read_overrides, resolve_rules
19
- from .rules import CATEGORIES, PROCEDURES, RULES, Procedure, Rule
19
+ from .rules import CATEGORIES, PROCEDURES, RULES, TOPICS, Procedure, Rule, Topic
20
20
 
21
21
  #: Bumped when the shape of :func:`dump` changes incompatibly.
22
22
  SCHEMA_VERSION = 1
@@ -27,9 +27,11 @@ __all__ = [
27
27
  "PROCEDURES",
28
28
  "RULES",
29
29
  "SCHEMA_VERSION",
30
+ "TOPICS",
30
31
  "OverrideError",
31
32
  "Procedure",
32
33
  "Rule",
34
+ "Topic",
33
35
  "check_file",
34
36
  "check_paths",
35
37
  "check_source",
@@ -64,6 +66,7 @@ def dump(root: str | Path | None = None) -> dict[str, Any]:
64
66
  "categories": [c for c in categories if any(r.category == c for r in rules)],
65
67
  "rules": [rule.to_dict() for rule in rules],
66
68
  "procedures": [procedure.to_dict() for procedure in PROCEDURES],
69
+ "topics": [topic.to_dict() for topic in TOPICS],
67
70
  "adapters": overrides.adapters,
68
71
  "overrides_file": str(overrides.path) if overrides.path else None,
69
72
  "conditions": sorted(conditions),
@@ -31,9 +31,17 @@ from .rules import ENFORCEMENT_CODES, rules_by_code
31
31
  SQL_ALLOWED: tuple[str, ...] = ("*/sql/*", "*/migrations/*")
32
32
  HTTP_ALLOWED: tuple[str, ...] = ("*/services/*", "*/providers/*", "*/tests/*", "conftest.py")
33
33
  HTTP_BANNED: frozenset[str] = frozenset({"requests", "httpx", "urllib.request"})
34
- #: Any of these as a base satisfies model-base (BaseModel or its mixins).
34
+ #: Any of these as a base satisfies model-base (BaseModel, BigIntBaseModel or their mixins).
35
35
  KARNI_MODEL_BASES: frozenset[str] = frozenset(
36
- {"BaseModel", "UUIDModel", "TimestampedModel", "SoftDeleteModel", "AuditedModel"}
36
+ {
37
+ "BaseModel",
38
+ "BigIntBaseModel",
39
+ "UUIDModel",
40
+ "IntegerKeyModel",
41
+ "TimestampedModel",
42
+ "SoftDeleteModel",
43
+ "AuditedModel",
44
+ }
37
45
  )
38
46
  _DRF_VIEWSETS = frozenset({"GenericViewSet", "ModelViewSet", "ReadOnlyModelViewSet"})
39
47
 
@@ -42,6 +50,7 @@ TS_SUFFIXES = frozenset({".ts", ".tsx", ".js", ".jsx", ".mts", ".cts", ".mjs", "
42
50
  JSX_SUFFIXES = frozenset({".tsx", ".jsx"})
43
51
  PAGE_MAX_LINES = 50
44
52
 
53
+ _PY_ALLOW_START = re.compile(r"#\s*karni:\s*allow\(")
45
54
  _PY_ALLOW = re.compile(r"#\s*karni:\s*allow\(([^)]*)\)\s*(?::\s*(.*))?$")
46
55
  # ESLint only honours a directive that opens the comment (`// eslint-disable...`
47
56
  # or `/* eslint-disable... */`); prose that merely mentions it is not one.
@@ -125,6 +134,32 @@ def _is_abstract(cls: ast.ClassDef) -> bool:
125
134
  return False
126
135
 
127
136
 
137
+ def _nested_constant(cls: ast.ClassDef, nested: str, name: str) -> object:
138
+ """The constant ``name = <value>`` in ``cls``'s nested class ``nested``, else ``None``."""
139
+ for stmt in cls.body:
140
+ if isinstance(stmt, ast.ClassDef) and stmt.name == nested:
141
+ for item in stmt.body:
142
+ if (
143
+ isinstance(item, ast.Assign)
144
+ and any(isinstance(t, ast.Name) and t.id == name for t in item.targets)
145
+ and isinstance(item.value, ast.Constant)
146
+ ):
147
+ return item.value.value
148
+ return None
149
+
150
+
151
+ def _is_external(cls: ast.ClassDef) -> bool:
152
+ """An external table or view (``karni.db``, experimental): model-base accepts it.
153
+
154
+ Both declarations are needed: ``class Karni: external = True`` and
155
+ ``class Meta: managed = False``.
156
+ """
157
+ return (
158
+ _nested_constant(cls, "Karni", "external") is True
159
+ and _nested_constant(cls, "Meta", "managed") is False
160
+ )
161
+
162
+
128
163
  def _class_lines(cls: ast.ClassDef) -> list[int]:
129
164
  first = min([cls.lineno, *(d.lineno for d in cls.decorator_list)])
130
165
  return sorted({cls.lineno, cls.lineno - 1, first, first - 1})
@@ -255,7 +290,12 @@ def _python(path: str, text: str) -> list[tuple[Finding, list[int]]]:
255
290
  if isinstance(node, ast.ClassDef):
256
291
  bases = {_dotted(b) for b in node.bases}
257
292
  short = {b.rsplit(".", 1)[-1] for b in bases}
258
- if bases & model_names and not short & KARNI_MODEL_BASES and not _is_abstract(node):
293
+ if (
294
+ bases & model_names
295
+ and not short & KARNI_MODEL_BASES
296
+ and not _is_abstract(node)
297
+ and not _is_external(node)
298
+ ):
259
299
  found.append(
260
300
  (
261
301
  _finding(
@@ -387,26 +427,31 @@ def http_client_imports(tree: ast.AST) -> list[tuple[int, str]]:
387
427
 
388
428
 
389
429
  def _python_optouts(lines: list[str], found: list[tuple[Finding, list[int]]]) -> list[Finding]:
390
- markers: dict[int, tuple[set[str], str]] = {}
430
+ markers: dict[int, list[tuple[set[str], str]]] = {}
391
431
  for i, text in enumerate(lines, start=1):
392
- m = _PY_ALLOW.search(text)
393
- if m:
394
- rules = {r.strip() for r in m.group(1).split(",") if r.strip()}
395
- markers[i] = (rules, (m.group(2) or "").strip())
432
+ # A line may carry several markers, each reason running to the next one.
433
+ starts = [m.start() for m in _PY_ALLOW_START.finditer(text)]
434
+ for begin, end in zip(starts, [*starts[1:], len(text)][: len(starts)], strict=True):
435
+ m = _PY_ALLOW.match(text[begin:end].rstrip())
436
+ if m:
437
+ rules = {r.strip() for r in m.group(1).split(",") if r.strip()}
438
+ markers.setdefault(i, []).append((rules, (m.group(2) or "").strip()))
396
439
  result: list[Finding] = []
397
- for i, (rules, reason) in sorted(markers.items()):
398
- if not reason:
399
- result.append(
400
- _finding(
401
- "opt-out-reason",
402
- i,
403
- f"karni: allow({', '.join(sorted(rules))}) requires a non-empty reason",
440
+ for i, entries in sorted(markers.items()):
441
+ for rules, reason in entries:
442
+ if not reason:
443
+ result.append(
444
+ _finding(
445
+ "opt-out-reason",
446
+ i,
447
+ f"karni: allow({', '.join(sorted(rules))}) requires a non-empty reason",
448
+ )
404
449
  )
405
- )
406
450
  for finding, candidates in found:
407
451
  allowed = any(
408
- finding.rule_id in markers.get(line, (set(), ""))[0] and markers[line][1]
452
+ finding.rule_id in rules and reason
409
453
  for line in candidates
454
+ for rules, reason in markers.get(line, [])
410
455
  )
411
456
  if not allowed:
412
457
  result.append(finding)
@@ -415,7 +460,7 @@ def _python_optouts(lines: list[str], found: list[tuple[Finding, list[int]]]) ->
415
460
 
416
461
  # TypeScript / JavaScript
417
462
 
418
- _RAW_ELEMENT = re.compile(r"<(table|form|input|select|textarea)(?=[\s/>])")
463
+ _RAW_ELEMENT = re.compile(r"<(table|form|input|select|textarea|details)(?=[\s/>])")
419
464
  _DEEP_IMPORT = re.compile(
420
465
  r"""(?:from\s+|import\s*\(\s*|require\s*\(\s*|import\s+)["']@karni/ui/(?:dist|src)(?:/[^"']*)?["']"""
421
466
  )
@@ -426,7 +471,8 @@ _NEW_TRANSPORT = re.compile(
426
471
  r"(?<![\w$.])new\s+(?:(?:window|globalThis|self)\.)?(XMLHttpRequest|WebSocket)\b"
427
472
  )
428
473
  _REPLACEMENTS = {
429
- "table": "ResourceTable",
474
+ "table": "ResourceTable (a resource), DataTable (computed rows) or ComparisonTable",
475
+ "details": "Accordion",
430
476
  "form": "ResourceForm",
431
477
  "input": "Input (or ResourceForm)",
432
478
  "select": "Select / ResourceSelect",
@@ -14,7 +14,7 @@ Schema (every name optional)::
14
14
  ]
15
15
  OVERRIDE = {"K202": {"summary": "Page files stay at 80 lines or fewer."}}
16
16
  DISABLE = ["K304"]
17
- ADAPTERS = {"disable": ["copilot"], "paths": {"windsurf": ".devin/rules/karni.md"}}
17
+ ADAPTERS = {"disable": [...], "paths": {"agents-md": "AGENTS.md"}} # ids: agent_adapters.toml
18
18
 
19
19
  ``ADD += [...]`` and ``DISABLE += [...]`` are accepted (the upgrade codemod
20
20
  appends that way). Anything else at top level is an error that names the line.