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.
- {karni_cli-0.4.0 → karni_cli-0.5.0}/.gitignore +7 -2
- {karni_cli-0.4.0 → karni_cli-0.5.0}/PKG-INFO +55 -9
- {karni_cli-0.4.0 → karni_cli-0.5.0}/README.md +51 -6
- {karni_cli-0.4.0 → karni_cli-0.5.0}/hatch_build.py +27 -2
- karni_cli-0.5.0/karni_cli/__init__.py +8 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_agent/__init__.py +4 -1
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_agent/check.py +65 -19
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_agent/overrides.py +1 -1
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_agent/rules.py +472 -43
- karni_cli-0.5.0/karni_cli/_catalog/__init__.py +576 -0
- karni_cli-0.5.0/karni_cli/_catalog/__main__.py +30 -0
- karni_cli-0.5.0/karni_cli/_catalog/features/api_cache.toml +19 -0
- karni_cli-0.5.0/karni_cli/_catalog/features/email_code_login.toml +25 -0
- karni_cli-0.5.0/karni_cli/_catalog/features/social_login.toml +27 -0
- karni_cli-0.5.0/karni_cli/_catalog/features/terms.toml +28 -0
- karni_cli-0.5.0/karni_cli/_catalog/features/two_factor.toml +20 -0
- karni_cli-0.5.0/karni_cli/_catalog/features/user_grants.toml +21 -0
- karni_cli-0.5.0/karni_cli/_catalog/modules/karni-ai.toml +61 -0
- karni_cli-0.5.0/karni_cli/_catalog/modules/karni-approvals.toml +50 -0
- karni_cli-0.5.0/karni_cli/_catalog/modules/karni-charts.toml +34 -0
- karni_cli-0.5.0/karni_cli/_catalog/modules/karni-impersonation.toml +59 -0
- karni_cli-0.5.0/karni_cli/_catalog/modules/karni-payments.toml +56 -0
- karni_cli-0.5.0/karni_cli/_catalog/modules/karni-reports.toml +53 -0
- karni_cli-0.5.0/karni_cli/_catalog/modules/karni-site.toml +84 -0
- karni_cli-0.5.0/karni_cli/_catalog/modules/karni-storage.toml +67 -0
- karni_cli-0.5.0/karni_cli/_changelog/0.5.0.toml +819 -0
- karni_cli-0.5.0/karni_cli/_errorcodes/__init__.py +3202 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_errorcodes/failures.py +2 -2
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_errorcodes/links.py +3 -1
- karni_cli-0.5.0/karni_cli/_settings/base.py +796 -0
- karni_cli-0.5.0/karni_cli/_settings/reference.py +491 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/cookiecutter.json +4 -2
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/.dockerignore +1 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/.env.example +62 -3
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/.gitignore +5 -0
- karni_cli-0.5.0/karni_cli/_templates/project/{{cookiecutter.project_slug}}/Dockerfile +112 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/Makefile +1 -1
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/README.md +70 -26
- karni_cli-0.5.0/karni_cli/_templates/project/{{cookiecutter.project_slug}}/config/settings.py +69 -0
- karni_cli-0.5.0/karni_cli/_templates/project/{{cookiecutter.project_slug}}/config/urls.py +45 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/docker-compose.yml +9 -4
- karni_cli-0.5.0/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/.npmrc +15 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/index.html +1 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/package.json +10 -3
- karni_cli-0.5.0/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/src/layout.tsx +88 -0
- karni_cli-0.5.0/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/src/pages/home.tsx +31 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/src/routes.tsx +6 -1
- karni_cli-0.5.0/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/vite.config.ts +28 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/pyproject.toml +5 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/tests/test_smoke.py +5 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_ui/styles.css +16 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/adapters.py +160 -18
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/agent_adapters.toml +23 -6
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/agent_data.py +10 -0
- karni_cli-0.5.0/karni_cli/agent_tools.py +505 -0
- karni_cli-0.5.0/karni_cli/builder/__init__.py +21 -0
- karni_cli-0.5.0/karni_cli/builder/layout.py +83 -0
- karni_cli-0.5.0/karni_cli/builder/output.py +134 -0
- karni_cli-0.5.0/karni_cli/builder/record.py +215 -0
- karni_cli-0.5.0/karni_cli/builder/render.py +1155 -0
- karni_cli-0.5.0/karni_cli/builder/run.py +1111 -0
- karni_cli-0.5.0/karni_cli/catalog.py +274 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/clidoc.py +7 -5
- karni_cli-0.5.0/karni_cli/commands/add.py +463 -0
- karni_cli-0.5.0/karni_cli/commands/build.py +131 -0
- karni_cli-0.5.0/karni_cli/commands/check.py +430 -0
- karni_cli-0.5.0/karni_cli/commands/context.py +445 -0
- karni_cli-0.5.0/karni_cli/commands/design.py +246 -0
- karni_cli-0.5.0/karni_cli/commands/doctor.py +286 -0
- karni_cli-0.5.0/karni_cli/commands/explain.py +220 -0
- karni_cli-0.5.0/karni_cli/commands/import_design.py +608 -0
- karni_cli-0.5.0/karni_cli/commands/load.py +45 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/migrate.py +1 -1
- karni_cli-0.5.0/karni_cli/commands/modules.py +182 -0
- karni_cli-0.5.0/karni_cli/commands/new.py +697 -0
- karni_cli-0.5.0/karni_cli/commands/plan.py +155 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/queries.py +9 -2
- karni_cli-0.5.0/karni_cli/commands/recipes.py +196 -0
- karni_cli-0.5.0/karni_cli/commands/remove.py +402 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/rules.py +51 -5
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/seed.py +13 -1
- karni_cli-0.5.0/karni_cli/commands/serve.py +164 -0
- karni_cli-0.5.0/karni_cli/commands/spec.py +191 -0
- karni_cli-0.5.0/karni_cli/commands/suggest.py +60 -0
- karni_cli-0.5.0/karni_cli/commands/types.py +142 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/ui.py +223 -10
- karni_cli-0.5.0/karni_cli/commands/worker.py +113 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/debugging.py +1 -1
- karni_cli-0.5.0/karni_cli/design/__init__.py +30 -0
- karni_cli-0.5.0/karni_cli/design/analyze.py +361 -0
- karni_cli-0.5.0/karni_cli/design/builder.py +2058 -0
- karni_cli-0.5.0/karni_cli/design/compare.py +603 -0
- karni_cli-0.5.0/karni_cli/design/editable.py +1717 -0
- karni_cli-0.5.0/karni_cli/design/extract.py +813 -0
- karni_cli-0.5.0/karni_cli/design/forms.py +602 -0
- karni_cli-0.5.0/karni_cli/design/hours.py +281 -0
- karni_cli-0.5.0/karni_cli/design/images.py +388 -0
- karni_cli-0.5.0/karni_cli/design/mapref.py +369 -0
- karni_cli-0.5.0/karni_cli/design/parse.py +411 -0
- karni_cli-0.5.0/karni_cli/design/proposal.py +708 -0
- karni_cli-0.5.0/karni_cli/design/regions.py +156 -0
- karni_cli-0.5.0/karni_cli/design/rewrite.py +534 -0
- karni_cli-0.5.0/karni_cli/design/scan.py +442 -0
- karni_cli-0.5.0/karni_cli/design/select.py +471 -0
- karni_cli-0.5.0/karni_cli/design/seo.py +70 -0
- karni_cli-0.5.0/karni_cli/design/site.py +1013 -0
- karni_cli-0.5.0/karni_cli/design/sources.py +712 -0
- karni_cli-0.5.0/karni_cli/design/values.py +475 -0
- karni_cli-0.5.0/karni_cli/envfile.py +69 -0
- karni_cli-0.5.0/karni_cli/errorcodes.py +1614 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/errordoc.py +74 -15
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/__init__.py +8 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/apitest.py +140 -25
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/app.py +4 -3
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/core.py +19 -0
- karni_cli-0.5.0/karni_cli/generators/deploy.py +880 -0
- karni_cli-0.5.0/karni_cli/generators/external.py +234 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/fields.py +305 -69
- karni_cli-0.5.0/karni_cli/generators/form.py +1089 -0
- karni_cli-0.5.0/karni_cli/generators/introspect.py +493 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/model.py +218 -11
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/module.py +36 -6
- karni_cli-0.5.0/karni_cli/generators/naming.py +225 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/page.py +256 -20
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/serializer.py +3 -2
- karni_cli-0.5.0/karni_cli/generators/site.py +677 -0
- karni_cli-0.5.0/karni_cli/generators/view.py +219 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/viewset.py +76 -9
- karni_cli-0.5.0/karni_cli/kinds.py +253 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/local_state.py +13 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/main.py +35 -5
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/mcp_server.py +71 -4
- karni_cli-0.5.0/karni_cli/module_codes.json +762 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/project.py +78 -18
- karni_cli-0.5.0/karni_cli/pyproject_edit.py +121 -0
- karni_cli-0.5.0/karni_cli/recipes/__init__.py +506 -0
- karni_cli-0.5.0/karni_cli/recipes/__main__.py +9 -0
- karni_cli-0.5.0/karni_cli/recipes/apply.py +114 -0
- karni_cli-0.5.0/karni_cli/recipes/booking/files/bookings/models.py +63 -0
- karni_cli-0.5.0/karni_cli/recipes/booking/files/bookings/tests/test_capacity.py +45 -0
- karni_cli-0.5.0/karni_cli/recipes/booking/files/bookings/viewsets.py +45 -0
- karni_cli-0.5.0/karni_cli/recipes/booking/karni.yaml +52 -0
- karni_cli-0.5.0/karni_cli/recipes/booking/recipe.toml +17 -0
- karni_cli-0.5.0/karni_cli/recipes/crm/files/crm/tests/test_pipeline.py +57 -0
- karni_cli-0.5.0/karni_cli/recipes/crm/files/crm/viewsets.py +39 -0
- karni_cli-0.5.0/karni_cli/recipes/crm/karni.yaml +80 -0
- karni_cli-0.5.0/karni_cli/recipes/crm/recipe.toml +18 -0
- karni_cli-0.5.0/karni_cli/recipes/data-portal/files/portal/seeds.py +157 -0
- karni_cli-0.5.0/karni_cli/recipes/data-portal/files/portal/tests/conftest.py +10 -0
- karni_cli-0.5.0/karni_cli/recipes/data-portal/files/portal/tests/test_portal.py +240 -0
- karni_cli-0.5.0/karni_cli/recipes/data-portal/karni.yaml +120 -0
- karni_cli-0.5.0/karni_cli/recipes/data-portal/recipe.toml +19 -0
- karni_cli-0.5.0/karni_cli/recipes/lms/files/courses/models.py +41 -0
- karni_cli-0.5.0/karni_cli/recipes/lms/files/courses/seeds.py +42 -0
- karni_cli-0.5.0/karni_cli/recipes/lms/files/courses/tests/test_completion.py +45 -0
- karni_cli-0.5.0/karni_cli/recipes/lms/files/courses/viewsets.py +30 -0
- karni_cli-0.5.0/karni_cli/recipes/lms/karni.yaml +73 -0
- karni_cli-0.5.0/karni_cli/recipes/lms/recipe.toml +16 -0
- karni_cli-0.5.0/karni_cli/recipes/marketplace/files/market/models.py +70 -0
- karni_cli-0.5.0/karni_cli/recipes/marketplace/files/market/tests/test_payouts.py +47 -0
- karni_cli-0.5.0/karni_cli/recipes/marketplace/files/market/viewsets.py +42 -0
- karni_cli-0.5.0/karni_cli/recipes/marketplace/karni.yaml +89 -0
- karni_cli-0.5.0/karni_cli/recipes/marketplace/recipe.toml +17 -0
- karni_cli-0.5.0/karni_cli/recipes/output.py +193 -0
- karni_cli-0.5.0/karni_cli/recipes/shop/files/shop/models.py +83 -0
- karni_cli-0.5.0/karni_cli/recipes/shop/files/shop/seeds.py +42 -0
- karni_cli-0.5.0/karni_cli/recipes/shop/files/shop/tests/test_checkout.py +55 -0
- karni_cli-0.5.0/karni_cli/recipes/shop/files/shop/viewsets.py +51 -0
- karni_cli-0.5.0/karni_cli/recipes/shop/karni.yaml +72 -0
- karni_cli-0.5.0/karni_cli/recipes/shop/recipe.toml +18 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/rules_render.py +18 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/scaffold.py +32 -1
- karni_cli-0.5.0/karni_cli/services.py +157 -0
- karni_cli-0.5.0/karni_cli/settingref.py +150 -0
- karni_cli-0.5.0/karni_cli/settings_edit.py +248 -0
- karni_cli-0.5.0/karni_cli/spec/__init__.py +17 -0
- karni_cli-0.5.0/karni_cli/spec/catalog.py +159 -0
- karni_cli-0.5.0/karni_cli/spec/edit.py +215 -0
- karni_cli-0.5.0/karni_cli/spec/emit.py +121 -0
- karni_cli-0.5.0/karni_cli/spec/export.py +1096 -0
- karni_cli-0.5.0/karni_cli/spec/navigation.py +283 -0
- karni_cli-0.5.0/karni_cli/spec/normal.py +277 -0
- karni_cli-0.5.0/karni_cli/spec/plan.py +1480 -0
- karni_cli-0.5.0/karni_cli/spec/questions.py +733 -0
- karni_cli-0.5.0/karni_cli/spec/schema.py +722 -0
- karni_cli-0.5.0/karni_cli/spec/source.py +102 -0
- karni_cli-0.5.0/karni_cli/spec/validate.py +2184 -0
- karni_cli-0.5.0/karni_cli/suggest.py +433 -0
- karni_cli-0.5.0/karni_cli/templateref.py +113 -0
- karni_cli-0.5.0/karni_cli/toolchain.py +87 -0
- karni_cli-0.5.0/karni_cli/typegen.py +201 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/uitheme/__init__.py +12 -3
- karni_cli-0.5.0/karni_cli/uitheme/colour.py +221 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/uitheme/css.py +41 -9
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/uitheme/defaults.py +21 -1
- karni_cli-0.5.0/karni_cli/uitheme/plaincss.py +1192 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/uitheme/render.py +15 -5
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/upgrades/v0_2/agent_guidance.py +6 -1
- karni_cli-0.5.0/karni_cli/upgrades/v0_5/urls_marker.py +61 -0
- karni_cli-0.5.0/karni_cli/urls_edit.py +120 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/pyproject.toml +12 -6
- karni_cli-0.5.0/tests/__init__.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/conftest.py +39 -1
- karni_cli-0.5.0/tests/fixtures/designs/academy/admissions.html +60 -0
- karni_cli-0.5.0/tests/fixtures/designs/academy/css/bootstrap.css +12 -0
- karni_cli-0.5.0/tests/fixtures/designs/academy/css/school.css +2 -0
- karni_cli-0.5.0/tests/fixtures/designs/academy/img/garden.svg +1 -0
- karni_cli-0.5.0/tests/fixtures/designs/academy/index.html +33 -0
- karni_cli-0.5.0/tests/fixtures/designs/bakery/about.html +37 -0
- karni_cli-0.5.0/tests/fixtures/designs/bakery/contact.html +40 -0
- karni_cli-0.5.0/tests/fixtures/designs/bakery/css/site.css +2 -0
- karni_cli-0.5.0/tests/fixtures/designs/bakery/img/hero.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/bakery/img/logo.svg +1 -0
- karni_cli-0.5.0/tests/fixtures/designs/bakery/img/oven.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/bakery/img/pattern.png +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/bakery/img/unused.png +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/bakery/index.html +42 -0
- karni_cli-0.5.0/tests/fixtures/designs/bakery/js/app.js +1 -0
- karni_cli-0.5.0/tests/fixtures/designs/bakery/menu.html +40 -0
- karni_cli-0.5.0/tests/fixtures/designs/bakery/specials.html +9 -0
- karni_cli-0.5.0/tests/fixtures/designs/clinic/404.html +36 -0
- karni_cli-0.5.0/tests/fixtures/designs/clinic/css/bootstrap.min.css +1 -0
- karni_cli-0.5.0/tests/fixtures/designs/clinic/css/clinic.css +2 -0
- karni_cli-0.5.0/tests/fixtures/designs/clinic/css/fonts.css +1 -0
- karni_cli-0.5.0/tests/fixtures/designs/clinic/fonts/clinic.woff2 +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/clinic/img/clinic.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/clinic/img/old-logo.png +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/clinic/index.html +37 -0
- karni_cli-0.5.0/tests/fixtures/designs/clinic/js/bootstrap.bundle.min.js +1 -0
- karni_cli-0.5.0/tests/fixtures/designs/clinic/services/dental.html +36 -0
- karni_cli-0.5.0/tests/fixtures/designs/clinic/services/eyes.html +36 -0
- karni_cli-0.5.0/tests/fixtures/designs/clinic/services/index.html +36 -0
- karni_cli-0.5.0/tests/fixtures/designs/clinic/team.html +29 -0
- karni_cli-0.5.0/tests/fixtures/designs/college/courses.html +27 -0
- karni_cli-0.5.0/tests/fixtures/designs/college/css/school.css +5 -0
- karni_cli-0.5.0/tests/fixtures/designs/college/img/badge.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/college/img/campus.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/college/img/campus.webp +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/college/img/course-art.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/college/img/course-music.png +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/college/img/hero.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/college/img/logo.svg +1 -0
- karni_cli-0.5.0/tests/fixtures/designs/college/img/share.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/college/img/teacher.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/college/index.html +32 -0
- karni_cli-0.5.0/tests/fixtures/designs/patisserie/contact.html +37 -0
- karni_cli-0.5.0/tests/fixtures/designs/patisserie/css/bootstrap.min.css +2 -0
- karni_cli-0.5.0/tests/fixtures/designs/patisserie/css/shop.css +2 -0
- karni_cli-0.5.0/tests/fixtures/designs/patisserie/img/baguette.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/patisserie/img/carrot-cake.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/patisserie/img/eclair.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/patisserie/img/flat-white.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/patisserie/img/lemon-tart.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/patisserie/img/lemonade.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/patisserie/img/rye.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/patisserie/img/shop.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/patisserie/img/sourdough.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/patisserie/index.html +82 -0
- karni_cli-0.5.0/tests/fixtures/designs/patisserie/menu.html +157 -0
- karni_cli-0.5.0/tests/fixtures/designs/portfolio/img/bg.png +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/portfolio/img/hero.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/portfolio/img/hero.webp +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/portfolio/img/shot-1x.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/portfolio/img/shot-2x.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/portfolio/index.html +40 -0
- karni_cli-0.5.0/tests/fixtures/designs/portfolio/scripts/reveal.js +1 -0
- karni_cli-0.5.0/tests/fixtures/designs/portfolio/styles/main.css +1 -0
- karni_cli-0.5.0/tests/fixtures/designs/practice/about.html +29 -0
- karni_cli-0.5.0/tests/fixtures/designs/practice/css/practice.css +3 -0
- karni_cli-0.5.0/tests/fixtures/designs/practice/doctors/ada-okoro.html +54 -0
- karni_cli-0.5.0/tests/fixtures/designs/practice/doctors/ben-lim.html +55 -0
- karni_cli-0.5.0/tests/fixtures/designs/practice/doctors/cara-diaz.html +54 -0
- karni_cli-0.5.0/tests/fixtures/designs/practice/img/ada.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/practice/img/ben.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/practice/img/cara.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/practice/img/logo.png +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/practice/img/waiting-room.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/practice/index.html +61 -0
- karni_cli-0.5.0/tests/fixtures/designs/practice/treatments.html +54 -0
- karni_cli-0.5.0/tests/fixtures/designs/salon/css/salon.css +12 -0
- karni_cli-0.5.0/tests/fixtures/designs/salon/index.html +41 -0
- karni_cli-0.5.0/tests/fixtures/designs/school/courses/drawing.html +55 -0
- karni_cli-0.5.0/tests/fixtures/designs/school/courses/pottery.html +56 -0
- karni_cli-0.5.0/tests/fixtures/designs/school/courses/printing.html +53 -0
- karni_cli-0.5.0/tests/fixtures/designs/school/courses/weaving.html +54 -0
- karni_cli-0.5.0/tests/fixtures/designs/school/courses.html +65 -0
- karni_cli-0.5.0/tests/fixtures/designs/school/css/school.css +2 -0
- karni_cli-0.5.0/tests/fixtures/designs/school/img/drawing-1.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/school/img/drawing-2.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/school/img/drawing.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/school/img/lena.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/school/img/mia.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/school/img/omar.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/school/img/pottery-1.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/school/img/pottery-2.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/school/img/pottery-3.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/school/img/pottery.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/school/img/printing-1.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/school/img/printing.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/school/img/studio.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/school/img/weaving-1.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/school/img/weaving-2.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/school/img/weaving.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/school/index.html +56 -0
- karni_cli-0.5.0/tests/fixtures/designs/school/teachers.html +45 -0
- karni_cli-0.5.0/tests/fixtures/designs/studio/about.html +63 -0
- karni_cli-0.5.0/tests/fixtures/designs/studio/css/studio.css +2 -0
- karni_cli-0.5.0/tests/fixtures/designs/studio/img/about-1.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/studio/img/about-2.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/studio/img/ines.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/studio/img/kiosk-2.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/studio/img/kiosk.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/studio/img/lakehouse-2.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/studio/img/lakehouse-3.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/studio/img/lakehouse.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/studio/img/library-2.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/studio/img/library-3.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/studio/img/library.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/studio/img/loft-2.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/studio/img/loft.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/studio/img/ola.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/studio/img/slide-1.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/studio/img/slide-2.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/studio/img/slide-3.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/studio/img/theo.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/studio/img/yara.jpg +0 -0
- karni_cli-0.5.0/tests/fixtures/designs/studio/index.html +119 -0
- karni_cli-0.5.0/tests/fixtures/designs/studio/js/studio.js +1 -0
- karni_cli-0.5.0/tests/fixtures/spec/harbour-yoga.build.json +448 -0
- karni_cli-0.5.0/tests/fixtures/spec/harbour-yoga.plan.json +287 -0
- karni_cli-0.5.0/tests/fixtures/spec/harbour-yoga.yaml +60 -0
- karni_cli-0.5.0/tests/fixtures/ui/css/bakery/menu.css +36 -0
- karni_cli-0.5.0/tests/fixtures/ui/css/bootstrap/theme.css +39 -0
- karni_cli-0.5.0/tests/fixtures/ui/css/clinic/style.css +57 -0
- karni_cli-0.5.0/tests/fixtures/ui/css/night/theme.css +20 -0
- karni_cli-0.5.0/tests/fixtures/ui/css/portfolio/about.html +9 -0
- karni_cli-0.5.0/tests/fixtures/ui/css/portfolio/css/about.css +2 -0
- karni_cli-0.5.0/tests/fixtures/ui/css/portfolio/css/site.css +17 -0
- karni_cli-0.5.0/tests/fixtures/ui/css/portfolio/css/tokens.css +8 -0
- karni_cli-0.5.0/tests/fixtures/ui/css/portfolio/css/unused.css +2 -0
- karni_cli-0.5.0/tests/fixtures/ui/css/portfolio/index.html +14 -0
- karni_cli-0.5.0/tests/fixtures/ui/css/portfolio/vendor/normalize.css +4 -0
- karni_cli-0.5.0/tests/fixtures/ui/css/switching/app.css +27 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_adapters.py +142 -25
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_add.py +47 -9
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_agent_upgrade.py +6 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_audit_fixes.py +59 -2
- karni_cli-0.5.0/tests/test_bench_tokens.py +668 -0
- karni_cli-0.5.0/tests/test_benchmark.py +98 -0
- karni_cli-0.5.0/tests/test_build.py +1289 -0
- karni_cli-0.5.0/tests/test_catalog.py +567 -0
- karni_cli-0.5.0/tests/test_check.py +366 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_command_states.py +2 -1
- karni_cli-0.5.0/tests/test_context.py +366 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_database.py +3 -2
- karni_cli-0.5.0/tests/test_design_address.py +121 -0
- karni_cli-0.5.0/tests/test_design_analyze.py +658 -0
- karni_cli-0.5.0/tests/test_design_content.py +174 -0
- karni_cli-0.5.0/tests/test_design_extract.py +431 -0
- karni_cli-0.5.0/tests/test_design_hours.py +69 -0
- karni_cli-0.5.0/tests/test_design_terms.py +106 -0
- karni_cli-0.5.0/tests/test_docs_links.py +181 -0
- karni_cli-0.5.0/tests/test_docs_roadmap.py +60 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_doctor.py +93 -6
- karni_cli-0.5.0/tests/test_envfile.py +51 -0
- karni_cli-0.5.0/tests/test_errorcodes_cli.py +297 -0
- karni_cli-0.5.0/tests/test_explain_tags_and_map.py +123 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_history.py +3 -1
- karni_cli-0.5.0/tests/test_import_design.py +1004 -0
- karni_cli-0.5.0/tests/test_import_design_menu_rows.py +127 -0
- karni_cli-0.5.0/tests/test_import_design_seo.py +240 -0
- karni_cli-0.5.0/tests/test_kinds.py +518 -0
- karni_cli-0.5.0/tests/test_make.py +1317 -0
- karni_cli-0.5.0/tests/test_make_deploy.py +564 -0
- karni_cli-0.5.0/tests/test_make_external.py +216 -0
- karni_cli-0.5.0/tests/test_make_form.py +833 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_make_gate.py +346 -2
- karni_cli-0.5.0/tests/test_make_model_order_key.py +49 -0
- karni_cli-0.5.0/tests/test_make_model_pk.py +65 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_make_units.py +44 -2
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_mcp.py +21 -2
- karni_cli-0.5.0/tests/test_model_plural.py +85 -0
- karni_cli-0.5.0/tests/test_module_migrations.py +55 -0
- karni_cli-0.5.0/tests/test_new.py +587 -0
- karni_cli-0.5.0/tests/test_new_app.py +320 -0
- karni_cli-0.5.0/tests/test_new_recipe.py +376 -0
- karni_cli-0.5.0/tests/test_plan.py +1232 -0
- karni_cli-0.5.0/tests/test_questions.py +612 -0
- karni_cli-0.5.0/tests/test_recipe_builds.py +74 -0
- karni_cli-0.5.0/tests/test_recipes.py +405 -0
- karni_cli-0.5.0/tests/test_release.py +537 -0
- karni_cli-0.5.0/tests/test_rules.py +278 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_runners.py +183 -7
- karni_cli-0.5.0/tests/test_services.py +254 -0
- karni_cli-0.5.0/tests/test_spec.py +1281 -0
- karni_cli-0.5.0/tests/test_spec_navigation.py +194 -0
- karni_cli-0.5.0/tests/test_speed.py +83 -0
- karni_cli-0.5.0/tests/test_suggest.py +474 -0
- karni_cli-0.5.0/tests/test_tool_names.py +101 -0
- karni_cli-0.5.0/tests/test_types.py +210 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_ui_detect.py +18 -0
- karni_cli-0.5.0/tests/test_ui_detect_css.py +458 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_upgrade.py +143 -5
- karni_cli-0.4.0/karni_cli/__init__.py +0 -3
- karni_cli-0.4.0/karni_cli/_errorcodes/__init__.py +0 -1635
- karni_cli-0.4.0/karni_cli/_templates/project/{{cookiecutter.project_slug}}/Caddyfile +0 -22
- karni_cli-0.4.0/karni_cli/_templates/project/{{cookiecutter.project_slug}}/Dockerfile +0 -53
- karni_cli-0.4.0/karni_cli/_templates/project/{{cookiecutter.project_slug}}/config/settings.py +0 -28
- karni_cli-0.4.0/karni_cli/_templates/project/{{cookiecutter.project_slug}}/config/urls.py +0 -31
- karni_cli-0.4.0/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/.npmrc +0 -7
- karni_cli-0.4.0/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/src/api/health.ts +0 -21
- karni_cli-0.4.0/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/src/layout.tsx +0 -52
- karni_cli-0.4.0/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/src/pages/home.tsx +0 -28
- karni_cli-0.4.0/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/vite.config.ts +0 -21
- karni_cli-0.4.0/karni_cli/commands/add.py +0 -144
- karni_cli-0.4.0/karni_cli/commands/check.py +0 -108
- karni_cli-0.4.0/karni_cli/commands/context.py +0 -172
- karni_cli-0.4.0/karni_cli/commands/doctor.py +0 -136
- karni_cli-0.4.0/karni_cli/commands/explain.py +0 -119
- karni_cli-0.4.0/karni_cli/commands/new.py +0 -114
- karni_cli-0.4.0/karni_cli/commands/serve.py +0 -53
- karni_cli-0.4.0/karni_cli/commands/types.py +0 -72
- karni_cli-0.4.0/karni_cli/commands/worker.py +0 -64
- karni_cli-0.4.0/karni_cli/errorcodes.py +0 -603
- karni_cli-0.4.0/karni_cli/generators/introspect.py +0 -263
- karni_cli-0.4.0/karni_cli/generators/naming.py +0 -100
- karni_cli-0.4.0/karni_cli/settings_edit.py +0 -128
- karni_cli-0.4.0/karni_cli/typegen.py +0 -101
- karni_cli-0.4.0/tests/test_check.py +0 -88
- karni_cli-0.4.0/tests/test_context.py +0 -134
- karni_cli-0.4.0/tests/test_errorcodes_cli.py +0 -138
- karni_cli-0.4.0/tests/test_make.py +0 -541
- karni_cli-0.4.0/tests/test_new.py +0 -284
- karni_cli-0.4.0/tests/test_rules.py +0 -158
- karni_cli-0.4.0/tests/test_types.py +0 -48
- {karni_cli-0.4.0 → karni_cli-0.5.0}/LICENSE +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_agent/__main__.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_agent/history.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_agent/history_chronicle.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_changelog/0.2.0.toml +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_changelog/0.3.0.toml +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_changelog/0.4.0.toml +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_changelog/__init__.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_errorcodes/__main__.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/config/__init__.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/config/asgi.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/config/celery.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/config/wsgi.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/.dockerignore +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/.jscpd.json +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/Dockerfile.dev +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/eslint.config.js +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/public/favicon.svg +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/src/App.tsx +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/src/index.css +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/src/main.tsx +0 -0
- {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
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/tailwind.config.ts +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/tsconfig.json +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/manage.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/tests/__init__.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/_templates/project/{{cookiecutter.project_slug}}/tests/test_api_schema.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/brand.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/__init__.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/beat.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/config.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/createsuperuser.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/make.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/manage_passthrough.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/mcp.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/replay.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/routes.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/run_tests.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/schedule.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/schema.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/shell.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/sync_roles.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/trace.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/upgrade.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/commands/why.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/config.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/database.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/db_probe.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/environment.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/explain_text.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/command.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/component.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/event.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/factory.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/lifecycle_fields.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/listener.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/middleware.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/migration.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/pysource.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/schedule.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/seeder.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/service.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/generators/task.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/history.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/tips.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/uitheme/designsystems.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/uitheme/frontend.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/uitheme/jsobject.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/uitheme/model.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/uitheme/primitives.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/uitheme/shadcn.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/uitheme/tailwind.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/uitheme/wiring.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/upgrades/__init__.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/upgrades/changelog.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/upgrades/codemod.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/upgrades/engine.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/upgrades/legacy_agent_files.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/upgrades/python.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/upgrades/transforms/rename-export.cjs +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/upgrades/typescript.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/upgrades/v0_2/__init__.py +0 -0
- {karni_cli-0.4.0/tests → karni_cli-0.5.0/karni_cli/upgrades/v0_5}/__init__.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/upgrades/v1_0/__init__.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/upgrades/v1_0/all_objects_to_without.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/upgrades/v1_0/all_with_deleted_to_without.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/upgrades/v1_0/deleted_only_to_without_dead.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/upgrades/v1_0/object_permission_classes_to_access.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/upgrades/v1_0/related_lookups_to_optimize.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/upgrades/v1_0/scoped_related_lookups_to_optimize.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/karni_cli/upgrades/v1_0/soft_delete_manager_mixin_to_scoped.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/schema.fixture.json +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/chakra/package.json +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/chakra/src/main.tsx +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/chakra/src/theme.ts +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/chakra3/package.json +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/chakra3/src/components/ui/theme.ts +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/chakra3/src/main.tsx +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/mantine/package.json +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/mantine/src/main.tsx +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/mantine/src/theme.ts +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/mui/package.json +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/mui/src/main.tsx +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/mui/src/theme/index.ts +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/plain/package.json +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/plain/src/index.css +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/plain/src/main.tsx +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw3/components.json +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw3/package.json +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw3/src/App.tsx +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw3/src/components/ui/button.tsx +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw3/src/components/ui/checkbox.tsx +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw3/src/components/ui/input.tsx +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw3/src/components/ui/label.tsx +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw3/src/components/ui/select.tsx +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw3/src/index.css +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw3/src/main.tsx +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw3/tailwind.config.js +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw3/tsconfig.json +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw4/components.json +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw4/package.json +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw4/src/App.tsx +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw4/src/components/ui/button.tsx +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw4/src/components/ui/select.tsx +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw4/src/components/ui/switch.tsx +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw4/src/components/ui/textarea.tsx +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw4/src/index.css +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw4/src/main.tsx +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/shadcn-tw4/tsconfig.json +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/tailwind3/package.json +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/tailwind3/src/index.css +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/tailwind3/src/main.tsx +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/tailwind3/tailwind.config.ts +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/tailwind4/package.json +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/tailwind4/src/index.css +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/tailwind4/src/main.tsx +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/ui/tailwind4/src/theme.css +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/fixtures/upgrade_changelog/0.9.0.toml +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_brand.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_clidoc.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_debugging.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_docs_tutorial.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_explain_text.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_make_lifecycle.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_project.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_schema_cli.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_upgrade_codemods.py +0 -0
- {karni_cli-0.4.0 → karni_cli-0.5.0}/tests/test_upgrade_typescript.py +0 -0
- {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
|
-
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
|
|
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,
|
|
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
|
|
42
|
-
|
|
42
|
+
The karni command: scaffold, generate, run and upgrade Karni projects.
|
|
43
|
+
|
|
44
|
+
[](https://pypi.org/project/karni-cli/) [](https://pypi.org/project/karni-cli/) [](https://github.com/cbsshekhawat18-lab/karni/blob/main/LICENSE) [](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
|
|
93
|
-
|
|
94
|
-
|
|
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
|
|
4
|
-
|
|
3
|
+
The karni command: scaffold, generate, run and upgrade Karni projects.
|
|
4
|
+
|
|
5
|
+
[](https://pypi.org/project/karni-cli/) [](https://pypi.org/project/karni-cli/) [](https://github.com/cbsshekhawat18-lab/karni/blob/main/LICENSE) [](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
|
|
55
|
-
|
|
56
|
-
|
|
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,
|
|
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
|
|
34
|
+
#: Any of these as a base satisfies model-base (BaseModel, BigIntBaseModel or their mixins).
|
|
35
35
|
KARNI_MODEL_BASES: frozenset[str] = frozenset(
|
|
36
|
-
{
|
|
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
|
|
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
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
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,
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
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
|
|
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": [
|
|
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.
|