karni-cli 0.3.1__py3-none-any.whl

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 (145) hide show
  1. karni_cli/__init__.py +3 -0
  2. karni_cli/_agent/__init__.py +82 -0
  3. karni_cli/_agent/__main__.py +44 -0
  4. karni_cli/_agent/check.py +658 -0
  5. karni_cli/_agent/history.py +328 -0
  6. karni_cli/_agent/history_chronicle.py +246 -0
  7. karni_cli/_agent/overrides.py +194 -0
  8. karni_cli/_agent/rules.py +673 -0
  9. karni_cli/_changelog/0.2.0.toml +304 -0
  10. karni_cli/_changelog/0.3.0.toml +25 -0
  11. karni_cli/_changelog/__init__.py +248 -0
  12. karni_cli/_errorcodes/__init__.py +1171 -0
  13. karni_cli/_errorcodes/__main__.py +34 -0
  14. karni_cli/_errorcodes/links.py +217 -0
  15. karni_cli/_templates/project/cookiecutter.json +8 -0
  16. karni_cli/_templates/project/{{cookiecutter.project_slug}}/.dockerignore +7 -0
  17. karni_cli/_templates/project/{{cookiecutter.project_slug}}/.env.example +85 -0
  18. karni_cli/_templates/project/{{cookiecutter.project_slug}}/.gitignore +10 -0
  19. karni_cli/_templates/project/{{cookiecutter.project_slug}}/Caddyfile +22 -0
  20. karni_cli/_templates/project/{{cookiecutter.project_slug}}/Dockerfile +53 -0
  21. karni_cli/_templates/project/{{cookiecutter.project_slug}}/Makefile +52 -0
  22. karni_cli/_templates/project/{{cookiecutter.project_slug}}/README.md +169 -0
  23. karni_cli/_templates/project/{{cookiecutter.project_slug}}/config/__init__.py +16 -0
  24. karni_cli/_templates/project/{{cookiecutter.project_slug}}/config/asgi.py +14 -0
  25. karni_cli/_templates/project/{{cookiecutter.project_slug}}/config/celery.py +17 -0
  26. karni_cli/_templates/project/{{cookiecutter.project_slug}}/config/settings.py +28 -0
  27. karni_cli/_templates/project/{{cookiecutter.project_slug}}/config/urls.py +31 -0
  28. karni_cli/_templates/project/{{cookiecutter.project_slug}}/config/wsgi.py +14 -0
  29. karni_cli/_templates/project/{{cookiecutter.project_slug}}/docker-compose.yml +126 -0
  30. karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/.dockerignore +2 -0
  31. karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/.jscpd.json +9 -0
  32. karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/.npmrc +7 -0
  33. karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/Dockerfile.dev +17 -0
  34. karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/eslint.config.js +32 -0
  35. karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/index.html +14 -0
  36. karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/package.json +43 -0
  37. karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/postcss.config.js +6 -0
  38. karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/public/favicon.svg +6 -0
  39. karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/src/App.tsx +18 -0
  40. karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/src/api/health.ts +21 -0
  41. karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/src/index.css +11 -0
  42. karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/src/layout.tsx +51 -0
  43. karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/src/main.tsx +11 -0
  44. karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/src/pages/home.tsx +28 -0
  45. karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/src/routes.tsx +24 -0
  46. karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/src/vite-env.d.ts +1 -0
  47. karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/tailwind.config.ts +13 -0
  48. karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/tsconfig.json +19 -0
  49. karni_cli/_templates/project/{{cookiecutter.project_slug}}/frontend/vite.config.ts +18 -0
  50. karni_cli/_templates/project/{{cookiecutter.project_slug}}/manage.py +23 -0
  51. karni_cli/_templates/project/{{cookiecutter.project_slug}}/pyproject.toml +31 -0
  52. karni_cli/_templates/project/{{cookiecutter.project_slug}}/tests/__init__.py +0 -0
  53. karni_cli/_templates/project/{{cookiecutter.project_slug}}/tests/test_api_schema.py +17 -0
  54. karni_cli/_templates/project/{{cookiecutter.project_slug}}/tests/test_smoke.py +11 -0
  55. karni_cli/adapters.py +373 -0
  56. karni_cli/agent_adapters.toml +160 -0
  57. karni_cli/agent_data.py +260 -0
  58. karni_cli/brand.py +55 -0
  59. karni_cli/clidoc.py +254 -0
  60. karni_cli/commands/__init__.py +0 -0
  61. karni_cli/commands/add.py +144 -0
  62. karni_cli/commands/beat.py +36 -0
  63. karni_cli/commands/check.py +101 -0
  64. karni_cli/commands/config.py +81 -0
  65. karni_cli/commands/context.py +171 -0
  66. karni_cli/commands/createsuperuser.py +28 -0
  67. karni_cli/commands/doctor.py +136 -0
  68. karni_cli/commands/explain.py +60 -0
  69. karni_cli/commands/make.py +55 -0
  70. karni_cli/commands/manage_passthrough.py +28 -0
  71. karni_cli/commands/mcp.py +20 -0
  72. karni_cli/commands/migrate.py +23 -0
  73. karni_cli/commands/new.py +106 -0
  74. karni_cli/commands/routes.py +20 -0
  75. karni_cli/commands/rules.py +139 -0
  76. karni_cli/commands/run_tests.py +38 -0
  77. karni_cli/commands/schedule.py +40 -0
  78. karni_cli/commands/seed.py +34 -0
  79. karni_cli/commands/serve.py +50 -0
  80. karni_cli/commands/shell.py +28 -0
  81. karni_cli/commands/sync_roles.py +32 -0
  82. karni_cli/commands/types.py +72 -0
  83. karni_cli/commands/upgrade.py +231 -0
  84. karni_cli/commands/worker.py +63 -0
  85. karni_cli/config.py +142 -0
  86. karni_cli/environment.py +29 -0
  87. karni_cli/errorcodes.py +377 -0
  88. karni_cli/errordoc.py +227 -0
  89. karni_cli/generators/__init__.py +67 -0
  90. karni_cli/generators/apitest.py +206 -0
  91. karni_cli/generators/app.py +103 -0
  92. karni_cli/generators/command.py +98 -0
  93. karni_cli/generators/component.py +115 -0
  94. karni_cli/generators/core.py +319 -0
  95. karni_cli/generators/event.py +57 -0
  96. karni_cli/generators/factory.py +88 -0
  97. karni_cli/generators/fields.py +343 -0
  98. karni_cli/generators/introspect.py +263 -0
  99. karni_cli/generators/listener.py +168 -0
  100. karni_cli/generators/middleware.py +95 -0
  101. karni_cli/generators/migration.py +82 -0
  102. karni_cli/generators/model.py +235 -0
  103. karni_cli/generators/module.py +255 -0
  104. karni_cli/generators/naming.py +100 -0
  105. karni_cli/generators/page.py +373 -0
  106. karni_cli/generators/pysource.py +304 -0
  107. karni_cli/generators/schedule.py +174 -0
  108. karni_cli/generators/seeder.py +86 -0
  109. karni_cli/generators/serializer.py +165 -0
  110. karni_cli/generators/service.py +68 -0
  111. karni_cli/generators/task.py +84 -0
  112. karni_cli/generators/viewset.py +179 -0
  113. karni_cli/history.py +59 -0
  114. karni_cli/local_state.py +73 -0
  115. karni_cli/main.py +104 -0
  116. karni_cli/mcp_server.py +103 -0
  117. karni_cli/project.py +248 -0
  118. karni_cli/rules_render.py +86 -0
  119. karni_cli/scaffold.py +197 -0
  120. karni_cli/settings_edit.py +128 -0
  121. karni_cli/tips.py +53 -0
  122. karni_cli/typegen.py +101 -0
  123. karni_cli/upgrades/__init__.py +28 -0
  124. karni_cli/upgrades/changelog.py +123 -0
  125. karni_cli/upgrades/codemod.py +125 -0
  126. karni_cli/upgrades/engine.py +224 -0
  127. karni_cli/upgrades/legacy_agent_files.py +138 -0
  128. karni_cli/upgrades/python.py +670 -0
  129. karni_cli/upgrades/transforms/rename-export.cjs +96 -0
  130. karni_cli/upgrades/typescript.py +160 -0
  131. karni_cli/upgrades/v0_2/__init__.py +1 -0
  132. karni_cli/upgrades/v0_2/agent_guidance.py +269 -0
  133. karni_cli/upgrades/v1_0/__init__.py +5 -0
  134. karni_cli/upgrades/v1_0/all_objects_to_without.py +18 -0
  135. karni_cli/upgrades/v1_0/all_with_deleted_to_without.py +13 -0
  136. karni_cli/upgrades/v1_0/deleted_only_to_without_dead.py +13 -0
  137. karni_cli/upgrades/v1_0/object_permission_classes_to_access.py +16 -0
  138. karni_cli/upgrades/v1_0/related_lookups_to_optimize.py +15 -0
  139. karni_cli/upgrades/v1_0/scoped_related_lookups_to_optimize.py +15 -0
  140. karni_cli/upgrades/v1_0/soft_delete_manager_mixin_to_scoped.py +14 -0
  141. karni_cli-0.3.1.dist-info/METADATA +191 -0
  142. karni_cli-0.3.1.dist-info/RECORD +145 -0
  143. karni_cli-0.3.1.dist-info/WHEEL +4 -0
  144. karni_cli-0.3.1.dist-info/entry_points.txt +2 -0
  145. karni_cli-0.3.1.dist-info/licenses/LICENSE +201 -0
karni_cli/__init__.py ADDED
@@ -0,0 +1,3 @@
1
+ """karni-cli — the ``karni`` command."""
2
+
3
+ __version__ = "0.3.1"
@@ -0,0 +1,82 @@
1
+ """Karni's agent guidance: rules, procedures, project overrides and file checks.
2
+
3
+ Stdlib-only and Django-free so the ``karni`` CLI can use it without a project
4
+ (in-process when karni is importable, otherwise via
5
+ ``python -m karni.agent`` in the project's interpreter, otherwise from the
6
+ snapshot bundled into karni-cli). :func:`dump` and :func:`check_paths` return
7
+ plain JSON-able data — the one contract all three paths share.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ from collections.abc import Iterable
13
+ from pathlib import Path
14
+ from typing import Any
15
+
16
+ from .check import check_file, check_source, supported
17
+ from .history import active_conditions
18
+ from .overrides import OVERRIDE_FILE, OverrideError, read_overrides, resolve_rules
19
+ from .rules import CATEGORIES, PROCEDURES, RULES, Procedure, Rule
20
+
21
+ #: Bumped when the shape of :func:`dump` changes incompatibly.
22
+ SCHEMA_VERSION = 1
23
+
24
+ __all__ = [
25
+ "CATEGORIES",
26
+ "OVERRIDE_FILE",
27
+ "PROCEDURES",
28
+ "RULES",
29
+ "SCHEMA_VERSION",
30
+ "OverrideError",
31
+ "Procedure",
32
+ "Rule",
33
+ "check_file",
34
+ "check_paths",
35
+ "check_source",
36
+ "dump",
37
+ "supported",
38
+ ]
39
+
40
+
41
+ def _karni_version() -> str:
42
+ try:
43
+ from importlib.metadata import PackageNotFoundError, version
44
+
45
+ return version("karni")
46
+ except PackageNotFoundError:
47
+ return "unknown"
48
+
49
+
50
+ def dump(root: str | Path | None = None) -> dict[str, Any]:
51
+ """Rules (with ``<root>/karni.rules.py`` applied), procedures and adapter overrides.
52
+
53
+ A rule with ``when`` set is included only while that condition holds for
54
+ ``root`` (``conditions`` lists the active ones; see
55
+ :func:`karni.agent.history.active_conditions`).
56
+ """
57
+ overrides = read_overrides(root)
58
+ conditions = active_conditions(root)
59
+ rules = [r for r in resolve_rules(overrides) if not r.when or r.when in conditions]
60
+ categories = list(dict.fromkeys([*CATEGORIES, *(r.category for r in rules)]))
61
+ return {
62
+ "schema": SCHEMA_VERSION,
63
+ "karni_version": _karni_version(),
64
+ "categories": [c for c in categories if any(r.category == c for r in rules)],
65
+ "rules": [rule.to_dict() for rule in rules],
66
+ "procedures": [procedure.to_dict() for procedure in PROCEDURES],
67
+ "adapters": overrides.adapters,
68
+ "overrides_file": str(overrides.path) if overrides.path else None,
69
+ "conditions": sorted(conditions),
70
+ }
71
+
72
+
73
+ def check_paths(
74
+ paths: Iterable[str | Path], root: str | Path | None = None
75
+ ) -> list[dict[str, Any]]:
76
+ """Findings for each path as dicts (``path`` added), honouring DISABLE in overrides."""
77
+ enabled = {rule.code for rule in resolve_rules(read_overrides(root))}
78
+ results: list[dict[str, Any]] = []
79
+ for path in paths:
80
+ for finding in check_file(path, enabled, root):
81
+ results.append({"path": str(path), **finding.to_dict()})
82
+ return results
@@ -0,0 +1,44 @@
1
+ """``python -m karni.agent`` — JSON bridge for the karni CLI.
2
+
3
+ The CLI uses this when karni is not importable in its own environment: it
4
+ runs the project's interpreter, so the project's karni version answers.
5
+
6
+ python -m karni.agent dump [--root DIR]
7
+ python -m karni.agent check [--root DIR] FILE [FILE ...]
8
+
9
+ Exit status: 0 on success (``check`` prints ``[]`` when clean), 2 on bad
10
+ input (malformed karni.rules.py, unreadable or unparsable file).
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ import argparse
16
+ import json
17
+ import sys
18
+
19
+ from . import OverrideError, check_paths, dump
20
+
21
+
22
+ def main(argv: list[str] | None = None) -> int:
23
+ parser = argparse.ArgumentParser(prog="python -m karni.agent")
24
+ sub = parser.add_subparsers(dest="command", required=True)
25
+ dump_cmd = sub.add_parser("dump")
26
+ dump_cmd.add_argument("--root", default=None)
27
+ check_cmd = sub.add_parser("check")
28
+ check_cmd.add_argument("--root", default=None)
29
+ check_cmd.add_argument("files", nargs="+")
30
+ args = parser.parse_args(argv)
31
+ try:
32
+ if args.command == "dump":
33
+ payload: object = dump(args.root)
34
+ else:
35
+ payload = check_paths(args.files, args.root)
36
+ except (OverrideError, OSError, ValueError) as exc:
37
+ sys.stderr.write(f"{exc}\n")
38
+ return 2
39
+ sys.stdout.write(json.dumps(payload))
40
+ return 0
41
+
42
+
43
+ if __name__ == "__main__":
44
+ raise SystemExit(main())