kctl-react 0.6.2__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 (102) hide show
  1. kctl_react/__init__.py +3 -0
  2. kctl_react/__main__.py +5 -0
  3. kctl_react/cli.py +201 -0
  4. kctl_react/commands/__init__.py +0 -0
  5. kctl_react/commands/a11y.py +78 -0
  6. kctl_react/commands/affected.py +170 -0
  7. kctl_react/commands/apps.py +353 -0
  8. kctl_react/commands/build.py +376 -0
  9. kctl_react/commands/bundle_cmd.py +217 -0
  10. kctl_react/commands/cap.py +1465 -0
  11. kctl_react/commands/clean.py +76 -0
  12. kctl_react/commands/codegen.py +491 -0
  13. kctl_react/commands/compliance.py +587 -0
  14. kctl_react/commands/config_cmd.py +368 -0
  15. kctl_react/commands/dashboard.py +163 -0
  16. kctl_react/commands/deploy.py +318 -0
  17. kctl_react/commands/deps.py +792 -0
  18. kctl_react/commands/dev.py +96 -0
  19. kctl_react/commands/docker_cmd.py +73 -0
  20. kctl_react/commands/doctor.py +170 -0
  21. kctl_react/commands/e2e.py +343 -0
  22. kctl_react/commands/env.py +155 -0
  23. kctl_react/commands/i18n.py +310 -0
  24. kctl_react/commands/lint.py +306 -0
  25. kctl_react/commands/maintenance.py +308 -0
  26. kctl_react/commands/monitor_cmd.py +50 -0
  27. kctl_react/commands/observe.py +34 -0
  28. kctl_react/commands/packages.py +129 -0
  29. kctl_react/commands/perf.py +762 -0
  30. kctl_react/commands/pipeline.py +289 -0
  31. kctl_react/commands/pwa.py +193 -0
  32. kctl_react/commands/scaffold.py +323 -0
  33. kctl_react/commands/security.py +660 -0
  34. kctl_react/commands/skill_cmd.py +54 -0
  35. kctl_react/commands/state.py +254 -0
  36. kctl_react/commands/test_cmd.py +418 -0
  37. kctl_react/commands/ui_audit.py +889 -0
  38. kctl_react/core/__init__.py +0 -0
  39. kctl_react/core/analyzers.py +200 -0
  40. kctl_react/core/callbacks.py +70 -0
  41. kctl_react/core/compliance/__init__.py +3 -0
  42. kctl_react/core/compliance/api_check/__init__.py +3 -0
  43. kctl_react/core/compliance/api_check/checks/__init__.py +18 -0
  44. kctl_react/core/compliance/api_check/checks/endpoints.py +53 -0
  45. kctl_react/core/compliance/api_check/checks/envelope.py +44 -0
  46. kctl_react/core/compliance/api_check/checks/naming.py +60 -0
  47. kctl_react/core/compliance/api_check/checks/params.py +44 -0
  48. kctl_react/core/compliance/api_check/checks/requests.py +57 -0
  49. kctl_react/core/compliance/api_check/checks/types.py +55 -0
  50. kctl_react/core/compliance/api_check/hooks.py +133 -0
  51. kctl_react/core/compliance/api_check/matcher.py +55 -0
  52. kctl_react/core/compliance/api_check/schema.py +151 -0
  53. kctl_react/core/compliance/api_health/__init__.py +35 -0
  54. kctl_react/core/compliance/api_health/checks/__init__.py +9 -0
  55. kctl_react/core/compliance/api_health/checks/auth.py +72 -0
  56. kctl_react/core/compliance/api_health/checks/reachable.py +44 -0
  57. kctl_react/core/compliance/api_health/checks/response.py +55 -0
  58. kctl_react/core/compliance/api_health/checks/timing.py +38 -0
  59. kctl_react/core/compliance/api_health/client.py +99 -0
  60. kctl_react/core/compliance/api_health/sampler.py +16 -0
  61. kctl_react/core/compliance/checks/__init__.py +47 -0
  62. kctl_react/core/compliance/checks/api.py +101 -0
  63. kctl_react/core/compliance/checks/codegen.py +94 -0
  64. kctl_react/core/compliance/checks/darkmode.py +57 -0
  65. kctl_react/core/compliance/checks/errors.py +68 -0
  66. kctl_react/core/compliance/checks/features.py +66 -0
  67. kctl_react/core/compliance/checks/i18n_check.py +105 -0
  68. kctl_react/core/compliance/checks/imports.py +86 -0
  69. kctl_react/core/compliance/checks/navigation.py +62 -0
  70. kctl_react/core/compliance/checks/practices.py +122 -0
  71. kctl_react/core/compliance/checks/providers.py +85 -0
  72. kctl_react/core/compliance/checks/pwa.py +101 -0
  73. kctl_react/core/compliance/checks/responsive.py +47 -0
  74. kctl_react/core/compliance/checks/scripts.py +85 -0
  75. kctl_react/core/compliance/checks/shadcn.py +51 -0
  76. kctl_react/core/compliance/checks/structure.py +76 -0
  77. kctl_react/core/compliance/checks/testing.py +83 -0
  78. kctl_react/core/compliance/checks/theme.py +92 -0
  79. kctl_react/core/compliance/checks/ui_standard.py +185 -0
  80. kctl_react/core/compliance/checks/vite.py +83 -0
  81. kctl_react/core/compliance/engine.py +87 -0
  82. kctl_react/core/compliance/exceptions_map.py +15 -0
  83. kctl_react/core/compliance/fixes/__init__.py +33 -0
  84. kctl_react/core/compliance/fixes/codegen_fix.py +28 -0
  85. kctl_react/core/compliance/fixes/i18n_fix.py +61 -0
  86. kctl_react/core/compliance/fixes/imports_fix.py +36 -0
  87. kctl_react/core/compliance/fixes/structure_fix.py +20 -0
  88. kctl_react/core/compliance/fixes/theme_fix.py +29 -0
  89. kctl_react/core/compliance/models.py +106 -0
  90. kctl_react/core/config.py +201 -0
  91. kctl_react/core/discovery.py +185 -0
  92. kctl_react/core/exceptions.py +17 -0
  93. kctl_react/core/git.py +146 -0
  94. kctl_react/core/history.py +121 -0
  95. kctl_react/core/output.py +5 -0
  96. kctl_react/core/plugins.py +13 -0
  97. kctl_react/core/runner.py +34 -0
  98. kctl_react/py.typed +0 -0
  99. kctl_react-0.6.2.dist-info/METADATA +17 -0
  100. kctl_react-0.6.2.dist-info/RECORD +102 -0
  101. kctl_react-0.6.2.dist-info/WHEEL +4 -0
  102. kctl_react-0.6.2.dist-info/entry_points.txt +2 -0
kctl_react/core/git.py ADDED
@@ -0,0 +1,146 @@
1
+ """Git utilities for change detection and affected app analysis."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import subprocess
6
+ from pathlib import Path
7
+
8
+ from kctl_react.core.discovery import discover_apps, discover_packages, get_app_dir
9
+
10
+
11
+ def get_changed_files(root: Path, base: str = "HEAD~1") -> list[str]:
12
+ """Get list of files changed since base ref."""
13
+ try:
14
+ result = subprocess.run(
15
+ ["git", "diff", "--name-only", base],
16
+ cwd=root,
17
+ capture_output=True,
18
+ text=True,
19
+ timeout=10,
20
+ )
21
+ if result.returncode != 0:
22
+ # Try against main if HEAD~1 fails (first commit)
23
+ result = subprocess.run(
24
+ ["git", "diff", "--name-only", "--cached"],
25
+ cwd=root,
26
+ capture_output=True,
27
+ text=True,
28
+ timeout=10,
29
+ )
30
+ return [f for f in result.stdout.strip().splitlines() if f]
31
+ except Exception:
32
+ return []
33
+
34
+
35
+ def get_uncommitted_files(root: Path) -> list[str]:
36
+ """Get list of uncommitted (staged + unstaged) files."""
37
+ try:
38
+ result = subprocess.run(
39
+ ["git", "status", "--porcelain", "--no-renames"],
40
+ cwd=root,
41
+ capture_output=True,
42
+ text=True,
43
+ timeout=10,
44
+ )
45
+ files = []
46
+ for line in result.stdout.strip().splitlines():
47
+ if line and len(line) > 3:
48
+ files.append(line[3:].strip())
49
+ return files
50
+ except Exception:
51
+ return []
52
+
53
+
54
+ def get_affected_apps(root: Path, base: str = "HEAD~1") -> list[str]:
55
+ """Determine which apps are affected by changes since base ref.
56
+
57
+ Rules:
58
+ - apps/{name}/* changed → that app is affected
59
+ - packages/{name}/* changed → all apps using that package are affected
60
+ - Root config changed (turbo.json, package.json, tsconfig) → all apps
61
+ """
62
+ changed = get_changed_files(root, base) + get_uncommitted_files(root)
63
+ if not changed:
64
+ return []
65
+
66
+ app_registry = discover_apps(root)
67
+ valid_apps = list(app_registry.keys())
68
+ package_list = discover_packages(root)
69
+
70
+ affected: set[str] = set()
71
+ changed_packages: set[str] = set()
72
+
73
+ root_config_files = {
74
+ "turbo.json",
75
+ "package.json",
76
+ "tsconfig.json",
77
+ "tsconfig.base.json",
78
+ "pnpm-lock.yaml",
79
+ }
80
+
81
+ for filepath in changed:
82
+ parts = filepath.split("/")
83
+
84
+ # Root config change → all apps affected
85
+ if filepath in root_config_files:
86
+ return valid_apps
87
+
88
+ # Direct app change: apps/spa/sfa/... or apps/web/corporate/...
89
+ if len(parts) >= 3 and parts[0] == "apps" and parts[1] in ("spa", "web", "api") and parts[2] in app_registry:
90
+ affected.add(parts[2])
91
+ # Legacy flat: apps/sfa/...
92
+ elif len(parts) >= 2 and parts[0] == "apps" and parts[1] in app_registry:
93
+ affected.add(parts[1])
94
+
95
+ # Package change
96
+ if len(parts) >= 2 and parts[0] == "packages" and parts[1] in package_list:
97
+ changed_packages.add(parts[1])
98
+
99
+ # Resolve package → app dependencies
100
+ if changed_packages:
101
+ import json
102
+
103
+ for app_name in valid_apps:
104
+ pkg_file = get_app_dir(root, app_name, app_registry) / "package.json"
105
+ if not pkg_file.exists():
106
+ continue
107
+ try:
108
+ pkg = json.loads(pkg_file.read_text())
109
+ all_deps = {**pkg.get("dependencies", {}), **pkg.get("devDependencies", {})}
110
+ for changed_pkg in changed_packages:
111
+ if f"@kodemeio/{changed_pkg}" in all_deps:
112
+ affected.add(app_name)
113
+ except Exception:
114
+ continue
115
+
116
+ return sorted(affected)
117
+
118
+
119
+ def get_current_branch(root: Path) -> str:
120
+ """Get current git branch name."""
121
+ try:
122
+ result = subprocess.run(
123
+ ["git", "branch", "--show-current"],
124
+ cwd=root,
125
+ capture_output=True,
126
+ text=True,
127
+ timeout=5,
128
+ )
129
+ return result.stdout.strip()
130
+ except Exception:
131
+ return ""
132
+
133
+
134
+ def get_last_commit_hash(root: Path) -> str:
135
+ """Get short hash of last commit."""
136
+ try:
137
+ result = subprocess.run(
138
+ ["git", "rev-parse", "--short", "HEAD"],
139
+ cwd=root,
140
+ capture_output=True,
141
+ text=True,
142
+ timeout=5,
143
+ )
144
+ return result.stdout.strip()
145
+ except Exception:
146
+ return ""
@@ -0,0 +1,121 @@
1
+ """Build history tracking — SQLite-backed via kctl-lib HistoryStore.
2
+
3
+ Provides backward-compatible API: load_history(), save_snapshot(), get_latest_snapshot().
4
+ On first use, migrates any existing .kctl-react/sizes.json to SQLite.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import json
10
+ from pathlib import Path
11
+ from typing import Any
12
+
13
+ from kctl_lib.history import HistoryStore
14
+
15
+ _SCHEMA = [
16
+ """CREATE TABLE IF NOT EXISTS builds (
17
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
18
+ app TEXT,
19
+ total_size INTEGER,
20
+ js_size INTEGER,
21
+ css_size INTEGER,
22
+ asset_size INTEGER,
23
+ page_count INTEGER,
24
+ snapshot TEXT,
25
+ timestamp TEXT NOT NULL
26
+ )""",
27
+ ]
28
+
29
+ _store: HistoryStore | None = None
30
+
31
+
32
+ def _get_store() -> HistoryStore:
33
+ """Get or create the singleton HistoryStore."""
34
+ global _store # noqa: PLW0603
35
+ if _store is None:
36
+ _store = HistoryStore("kctl-react")
37
+ _store.ensure_schema(_SCHEMA)
38
+ return _store
39
+
40
+
41
+ def _migrate_json(root: Path) -> None:
42
+ """One-time migration of .kctl-react/sizes.json to SQLite."""
43
+ json_file = root / ".kctl-react" / "sizes.json"
44
+ if not json_file.exists():
45
+ return
46
+
47
+ try:
48
+ data = json.loads(json_file.read_text())
49
+ except Exception:
50
+ return
51
+
52
+ if not isinstance(data, list) or not data:
53
+ return
54
+
55
+ store = _get_store()
56
+ for entry in data:
57
+ if not isinstance(entry, dict):
58
+ continue
59
+ # Record each entry, using its original timestamp if present
60
+ record_data: dict[str, Any] = {}
61
+ record_data["app"] = entry.get("app", "")
62
+ record_data["total_size"] = entry.get("total_size", entry.get("total_bytes", 0))
63
+ record_data["js_size"] = entry.get("js_size", entry.get("js_bytes", 0))
64
+ record_data["css_size"] = entry.get("css_size", entry.get("css_bytes", 0))
65
+ record_data["asset_size"] = entry.get("asset_size", 0)
66
+ record_data["page_count"] = entry.get("page_count", 0)
67
+ record_data["snapshot"] = json.dumps(entry)
68
+ store.record("builds", **record_data)
69
+
70
+ # Rename old file as backup
71
+ backup = json_file.with_suffix(".json.bak")
72
+ json_file.rename(backup)
73
+
74
+
75
+ def load_history(root: Path) -> list[dict]:
76
+ """Load build size history. Triggers migration on first call."""
77
+ _migrate_json(root)
78
+ store = _get_store()
79
+ rows = store.query("builds", limit=50)
80
+ # Reconstruct snapshot dicts for backward compat
81
+ result = []
82
+ for row in rows:
83
+ if row.get("snapshot"):
84
+ try:
85
+ result.append(json.loads(row["snapshot"]))
86
+ except Exception:
87
+ result.append(dict(row))
88
+ else:
89
+ result.append(dict(row))
90
+ return result
91
+
92
+
93
+ def save_snapshot(root: Path, snapshot: dict) -> None:
94
+ """Save a build size snapshot."""
95
+ _migrate_json(root)
96
+ store = _get_store()
97
+ store.record(
98
+ "builds",
99
+ app=snapshot.get("app", ""),
100
+ total_size=snapshot.get("total_size", snapshot.get("total_bytes", 0)),
101
+ js_size=snapshot.get("js_size", snapshot.get("js_bytes", 0)),
102
+ css_size=snapshot.get("css_size", snapshot.get("css_bytes", 0)),
103
+ asset_size=snapshot.get("asset_size", 0),
104
+ page_count=snapshot.get("page_count", 0),
105
+ snapshot=json.dumps(snapshot),
106
+ )
107
+
108
+
109
+ def get_latest_snapshot(root: Path) -> dict | None:
110
+ """Get the most recent snapshot."""
111
+ store = _get_store()
112
+ rows = store.query("builds", limit=1)
113
+ if not rows:
114
+ return None
115
+ row = rows[0]
116
+ if row.get("snapshot"):
117
+ try:
118
+ return json.loads(row["snapshot"])
119
+ except Exception:
120
+ return dict(row)
121
+ return dict(row)
@@ -0,0 +1,5 @@
1
+ """Output handler — re-exported from kctl-lib."""
2
+
3
+ from kctl_lib.output import Output
4
+
5
+ __all__ = ["Output"]
@@ -0,0 +1,13 @@
1
+ """Plugin discovery — delegates to kctl-lib."""
2
+
3
+ from kctl_lib.plugins import KctlPlugin
4
+ from kctl_lib.plugins import discover_and_load_plugins as _discover
5
+
6
+ __all__ = ["KctlPlugin", "discover_and_load_plugins"]
7
+
8
+ ENTRY_POINT_GROUP = "kctl_react.plugins"
9
+
10
+
11
+ def discover_and_load_plugins(app): # noqa: ANN001, ANN201
12
+ """Discover and load kctl-react plugins."""
13
+ return _discover(app, ENTRY_POINT_GROUP)
@@ -0,0 +1,34 @@
1
+ """Shell command runner — delegates to kctl-lib, adds pnpm/turbo helpers."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import subprocess
6
+ from pathlib import Path
7
+
8
+ from kctl_lib.runner import get_git_branch, get_git_sha, run, run_quiet
9
+
10
+ __all__ = ["get_git_branch", "get_git_sha", "run", "run_quiet", "run_pnpm", "run_turbo"]
11
+
12
+
13
+ def run_pnpm(
14
+ args: list[str],
15
+ cwd: Path,
16
+ capture: bool = True,
17
+ timeout: int = 300,
18
+ ) -> subprocess.CompletedProcess[str]:
19
+ """Run pnpm command in the monorepo."""
20
+ return run(["pnpm", *args], cwd=cwd, capture=capture, timeout=timeout)
21
+
22
+
23
+ def run_turbo(
24
+ task: str,
25
+ cwd: Path,
26
+ filter_app: str | None = None,
27
+ capture: bool = True,
28
+ timeout: int = 600,
29
+ ) -> subprocess.CompletedProcess[str]:
30
+ """Run turbo task with optional app filter."""
31
+ cmd = ["pnpm", "turbo", "run", task]
32
+ if filter_app:
33
+ cmd.extend(["--filter", f"@kodemeio/{filter_app}"])
34
+ return run(cmd, cwd=cwd, capture=capture, timeout=timeout)
kctl_react/py.typed ADDED
File without changes
@@ -0,0 +1,17 @@
1
+ Metadata-Version: 2.4
2
+ Name: kctl-react
3
+ Version: 0.6.2
4
+ Summary: Kodemeio React CLI — manage the kodemeio-react monorepo
5
+ Requires-Python: >=3.12
6
+ Requires-Dist: httpx>=0.28.0
7
+ Requires-Dist: kctl-lib>=0.8.0
8
+ Requires-Dist: pydantic>=2.10.0
9
+ Requires-Dist: pyyaml>=6.0.2
10
+ Requires-Dist: rich>=13.9.0
11
+ Requires-Dist: typer>=0.15.0
12
+ Provides-Extra: dev
13
+ Requires-Dist: mypy>=1.14.0; extra == 'dev'
14
+ Requires-Dist: pytest-httpx>=0.35.0; extra == 'dev'
15
+ Requires-Dist: pytest>=8.3.0; extra == 'dev'
16
+ Requires-Dist: ruff>=0.9.0; extra == 'dev'
17
+ Requires-Dist: types-pyyaml>=6.0.0; extra == 'dev'
@@ -0,0 +1,102 @@
1
+ kctl_react/__init__.py,sha256=ZlOi28e3DsqgUSyLotDOGaelhYfY1Y_gjvCeHBdPevE,70
2
+ kctl_react/__main__.py,sha256=jzQSG4Sg2-ilm9KsEaj4ugQ3LldV2Wql3pKFCGTgubc,85
3
+ kctl_react/cli.py,sha256=p_spHp7iK-OROoTBxNdYjDjnXj2yrMOOi3aCHLlSzRI,7558
4
+ kctl_react/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ kctl_react/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ kctl_react/commands/a11y.py,sha256=hJf64RW1J9M6NbHf57bke7MCjPdVtZ_8BTmafl1yxXo,2760
7
+ kctl_react/commands/affected.py,sha256=Qx8v7TYBSvdrmU08pKVQpyullAtBk4IHIoqIT_4jniY,5322
8
+ kctl_react/commands/apps.py,sha256=eiuSYU-4MtUy-n40XRneuHBaITQ276o6fxK2qUIfCcM,10562
9
+ kctl_react/commands/build.py,sha256=l-uv-Ao4u325DR_PCvMUEleFd5Ol3cx4dnHG_zEFcoE,11921
10
+ kctl_react/commands/bundle_cmd.py,sha256=jIoLR9YIBVu5FZkEBZEPtWRH83oRxmxnhf-YGIVXW_Y,7703
11
+ kctl_react/commands/cap.py,sha256=h2-g3s3Ngn_MvEZtyYCE5eZdJXt7jaHrHe8cx_qE7OY,50875
12
+ kctl_react/commands/clean.py,sha256=3QEE3q7VjNn_Cn8InsDBahH6o4ojLgrheXl8utcccRE,2276
13
+ kctl_react/commands/codegen.py,sha256=oaLSBzS367n-vJv90xEcTBsNR7pwgnqt4zrkqjcWchE,17239
14
+ kctl_react/commands/compliance.py,sha256=VZpgqH1jOUW6DC5hZncJhd4Tp6uYKZ3Nrc1Ho98P-u8,20851
15
+ kctl_react/commands/config_cmd.py,sha256=O1g5OiFDVPVfmYhvfu2lrO0UcEDi_JPQmNe7ZB6gESE,12112
16
+ kctl_react/commands/dashboard.py,sha256=mojMHrzKnTYx5fv4LCoQ5LiHDiTGkjgwUOWwx0OYttw,5186
17
+ kctl_react/commands/deploy.py,sha256=iqqwoKjzo_VQ81dz8DtoaaazHCid7OXDJN3WRhBCq5c,9887
18
+ kctl_react/commands/deps.py,sha256=lCFCXp65jekx8YyGmeZ5B0MDtIo4pAX-uQPARVWRBYg,25762
19
+ kctl_react/commands/dev.py,sha256=EFxbe2208IYPimBP7Qhc8YC4Ehd3efza4vXmhwAqyYU,2500
20
+ kctl_react/commands/docker_cmd.py,sha256=mH8JQMkwAeTb_zVDJlcE-YYOnx0u1eeatQ340ufcmhI,2315
21
+ kctl_react/commands/doctor.py,sha256=Mvb5aKuQwLTkhUko21AF56YVq9t9Ai_OZSXE7PjVQG8,4566
22
+ kctl_react/commands/e2e.py,sha256=msYvFCBU5S5aUkZeDJhK0-skXOL--WLF38Dy32ReF_c,11651
23
+ kctl_react/commands/env.py,sha256=DNd6jIVhjEpAEcvWjitRF8C0dBmMx8AXbvQzDtzMWqI,4617
24
+ kctl_react/commands/i18n.py,sha256=7Uo8w4a2IbfC7ArKqOsVK6CbBtHVxHW6u25zSe9W7jE,11090
25
+ kctl_react/commands/lint.py,sha256=-YlClHjBh0ofMwCbDAh_DGAvQg0j4_bKEU0QR_PNA78,9911
26
+ kctl_react/commands/maintenance.py,sha256=mXBy5QARW2KI-8MzuCSHyQoTdCz4j0jPg8PyTKzgzFQ,9363
27
+ kctl_react/commands/monitor_cmd.py,sha256=ZLSeA7QtUBf3YjjjY5h5TOhWa45mr0sV3vOCAhoYRj0,1555
28
+ kctl_react/commands/observe.py,sha256=Mv0LTR9DCly_wQHcawaEUEVtmMHVgUygJnDzvPvCAPE,1101
29
+ kctl_react/commands/packages.py,sha256=OFCB7LkIeq5ELD0eb7O2MSG0NBJ77arjQs-D4HYRzkk,3915
30
+ kctl_react/commands/perf.py,sha256=bR0p61zpk0EQpcpwxv7_G6sAO_ZnLWvN2c3RM0jD5kk,25799
31
+ kctl_react/commands/pipeline.py,sha256=3rs1h3eohINJ-mJnYur_0v3en4OMLjwLGDjeW_kXiqw,9593
32
+ kctl_react/commands/pwa.py,sha256=hCmQqGQHv_xietEM5mn0vXiYobh6zk7ZO2epSAEQxdk,7283
33
+ kctl_react/commands/scaffold.py,sha256=YI6YCmzm0jRarSe6ucNSaj4sU6unlaIQ0FjC7EDqhRs,10163
34
+ kctl_react/commands/security.py,sha256=sCCQBunDG8R8IimZLoxc6yZZAtj8C2r9xWx7wBeTg9k,22958
35
+ kctl_react/commands/skill_cmd.py,sha256=olbabW6govL9G32HUyKM6c90Ot-tjA0Nx6tgaVPm8hc,1607
36
+ kctl_react/commands/state.py,sha256=UiCi8sdkTm4cqP1SM4kB5N5CEtV9nrkLB4qCZO5WHWY,8696
37
+ kctl_react/commands/test_cmd.py,sha256=CqeZnCCy_9-om1PriOSn-QuktPCO5EymGUSSOEjh8NE,14125
38
+ kctl_react/commands/ui_audit.py,sha256=MtMfJmqobslripsfZiQNHuE7riDk_UneR9OLNqEe65g,32787
39
+ kctl_react/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
+ kctl_react/core/analyzers.py,sha256=SBHLxbIe757L_TninqY7HGbUQ43M0ODkVjcORo-7B1o,7550
41
+ kctl_react/core/callbacks.py,sha256=TibXyEwKt_1c8-awXPQbJK0G-_OTnCDLwLYa8n1w6Qg,2530
42
+ kctl_react/core/config.py,sha256=uBftRKugd_QQIQW8N8COVAfuvpycHzHsl0MimtB5iqc,5875
43
+ kctl_react/core/discovery.py,sha256=y61HtH4zmuKEUAT82tgfVbwD1aNhFU6qpfuiwX5w7_I,5540
44
+ kctl_react/core/exceptions.py,sha256=P7cqZ4IjEbny4mGrKDHGPj0c7vIKWeiqR80AucnSOWQ,301
45
+ kctl_react/core/git.py,sha256=d0MMGR2oveJ7VOWDNqk8TA4pvtKgxD5vpCpL-Gt-Qy4,4522
46
+ kctl_react/core/history.py,sha256=u9gieBxrORDXjPFspYtVAGiWFTi5KIq2WkUwUxpZTjw,3709
47
+ kctl_react/core/output.py,sha256=irTgk_u3pGmOEViFXq1Tr10SFB0qFqiAc9hwpig7Dw8,110
48
+ kctl_react/core/plugins.py,sha256=ibnYKp3XIj8JQ9pwyl6dgZBNFgdxlQlyKRI5kkrNecQ,411
49
+ kctl_react/core/runner.py,sha256=vkFrFAKAwgnF9f7XN2DM_1CMuiQtHwwpN2YHN8VjdEk,987
50
+ kctl_react/core/compliance/__init__.py,sha256=Weff7l4MF7zeJAEHrpfgPSykZl5UscXiptk97ilrGVs,82
51
+ kctl_react/core/compliance/engine.py,sha256=07GNhMBio9n02NAWyLev6Avrs7rPEd9fj-vmEbsZXwM,3248
52
+ kctl_react/core/compliance/exceptions_map.py,sha256=jhMwUHwxf7D8XCLX_Vgu1ldBtKrdyfUpCkuxrO26QAM,524
53
+ kctl_react/core/compliance/models.py,sha256=cqfOcC8wno04EqfY9N6JCb5lHEo3rm7haY3hF_I4qaA,2810
54
+ kctl_react/core/compliance/api_check/__init__.py,sha256=bYf009atYXb-j1YIxYwEprnHJq71gH0Ve7fpUbxJHxM,94
55
+ kctl_react/core/compliance/api_check/hooks.py,sha256=tnI-d_eFbx8QHQkbuQcgTNgaF7FD5T0XiZbbc-B67Qk,5186
56
+ kctl_react/core/compliance/api_check/matcher.py,sha256=2B9XPzK7N9BHH4y-J3ePc44UU1eVX9Q90D9T5Xtt990,1982
57
+ kctl_react/core/compliance/api_check/schema.py,sha256=XRFz51hsBdmeqbMGyPczCc3VWJFN7fhUHaobrzZ1ZXc,4986
58
+ kctl_react/core/compliance/api_check/checks/__init__.py,sha256=2qnOyXEC7pm1f6uMqoIeXuO7dlhGqFR1tHM0JznHe4k,462
59
+ kctl_react/core/compliance/api_check/checks/endpoints.py,sha256=X9m1NcCR_X-eRDZ56wthbSVlpeu7AEnQ5QTDApoHqO8,1835
60
+ kctl_react/core/compliance/api_check/checks/envelope.py,sha256=uRwzJ0p1dKapN_4N3N6o066_Q3bt_iBuyEmyLYFPOHM,1544
61
+ kctl_react/core/compliance/api_check/checks/naming.py,sha256=9WaVNJZcJkDqvj3J2GIwMQ4ylatdkj7mpmtnlJ5yeL4,1853
62
+ kctl_react/core/compliance/api_check/checks/params.py,sha256=uVvXIlJHmpdJnodnPfaF6sW4CGCmEbnh_3t-U19eTsc,1482
63
+ kctl_react/core/compliance/api_check/checks/requests.py,sha256=Zo5nRew7D9Az00hpHBHAYn2FaaDHEG15-UqDtRGSMJc,2068
64
+ kctl_react/core/compliance/api_check/checks/types.py,sha256=7vICt86YBsjnc9zFC-x17cH4QvSRi6WkH0ATqWpUAJw,1958
65
+ kctl_react/core/compliance/api_health/__init__.py,sha256=C6u2wVQhnZNNPt3CSwK-y__2fPZ_Za8oi5uKEl4ubO4,899
66
+ kctl_react/core/compliance/api_health/client.py,sha256=gtzdGRzNjeb-5i_ZJTuLwMEJZHkMWxNE9SWIYvkObUE,3463
67
+ kctl_react/core/compliance/api_health/sampler.py,sha256=viJ4vzNtGXRuc1PhREqizdlnQZJvQKQDEGfAW1nALps,601
68
+ kctl_react/core/compliance/api_health/checks/__init__.py,sha256=Fx83Fyhb8EHqE78EtYTQLHo16-MRYZiwo17murbPaQ8,345
69
+ kctl_react/core/compliance/api_health/checks/auth.py,sha256=50kpGNt_o19fvhFTrmJ2tUur0UVreNgUCAICZvBiXOM,2544
70
+ kctl_react/core/compliance/api_health/checks/reachable.py,sha256=9MxxepPhujT9oWXHH_iJmFR2BwmZUXugTTt5p_fgfbc,1480
71
+ kctl_react/core/compliance/api_health/checks/response.py,sha256=Expp0cRjzDFPnVSf2MiQtxQKw6TJoazDNVj6ziI1_Ag,1937
72
+ kctl_react/core/compliance/api_health/checks/timing.py,sha256=x6puf4SekWUUMOPPfcjWloEIyXCfhDeoYGkQtADpicw,1260
73
+ kctl_react/core/compliance/checks/__init__.py,sha256=hDztCyNOWzlpTX8OKJlZ5tr4Dpl0hbmGy3b2f60KKo4,1252
74
+ kctl_react/core/compliance/checks/api.py,sha256=OsSpQgE8thLEYyov3_J6A9OrRLe-nvpRIkZKIVqve20,3878
75
+ kctl_react/core/compliance/checks/codegen.py,sha256=YmfziqXTQO02JEhHVFoft_K3iB6wXJ7JqE23Q9V9wQw,3394
76
+ kctl_react/core/compliance/checks/darkmode.py,sha256=VngUdTDgpKMDdT82-7_lRX2AFXvz35_UzMsvLkCvmgc,2050
77
+ kctl_react/core/compliance/checks/errors.py,sha256=wYem0Da3QXb49zh1aO43pv01EAcRtmDOLKbmGx1xrc8,2385
78
+ kctl_react/core/compliance/checks/features.py,sha256=hcvMXkGwWNAxATUE11eZHLsbbrw7vfb759EaiqMz3_4,2118
79
+ kctl_react/core/compliance/checks/i18n_check.py,sha256=igolt79f6liEYDu91jYwx1oCkLJzMtOK0X4S_d-9vw0,3474
80
+ kctl_react/core/compliance/checks/imports.py,sha256=ntPNtkPa1XXdOBpakJgJfrfmYLP6M7kSdL3-lJYyQTM,3149
81
+ kctl_react/core/compliance/checks/navigation.py,sha256=-z54XUXuYOR5nIGu37LZrsU3bBsrTzKcNd1URz0bFms,2237
82
+ kctl_react/core/compliance/checks/practices.py,sha256=a5A9P1lrZyCJgke1Cf4AIaUpxFxaRUl61-hGfwzhq98,4931
83
+ kctl_react/core/compliance/checks/providers.py,sha256=OtZ2gGDeigSo4qhKQ2h3kgeHz6zMnfXixd47DNDx1Q0,2738
84
+ kctl_react/core/compliance/checks/pwa.py,sha256=VMwaSxTAJiDJ0F5H9BqHXXtciKKggHR6cK-YBa00KkU,3373
85
+ kctl_react/core/compliance/checks/responsive.py,sha256=ukE7nDWFgHkCMIqij9bBJSFe8DK-Uv_jXOldw2v6i4A,1507
86
+ kctl_react/core/compliance/checks/scripts.py,sha256=MMpaYFxxXSONYFc84J3YMBvTiOVZUHopAPpk8yvx6jU,2385
87
+ kctl_react/core/compliance/checks/shadcn.py,sha256=yqjLOXc12UzuivmeWS_RNqdTtLOfoBglddWRHRzXnd4,1861
88
+ kctl_react/core/compliance/checks/structure.py,sha256=Rp7McLXcZaLWDu-_jzdzZpSzyXHypIjp41miR99pkps,1943
89
+ kctl_react/core/compliance/checks/testing.py,sha256=t4_oTVtd03-OZl1khOcdazizgkbvs8LSKzctAGc12M0,2841
90
+ kctl_react/core/compliance/checks/theme.py,sha256=v-z4knFMXLt--DwolSy-bu_kRqOjuuI8aNflsOJNiuY,3532
91
+ kctl_react/core/compliance/checks/ui_standard.py,sha256=ip7pJ-aAj3zy6XHzZRGwtPhmsHNUuuIZ7Bm3EXGmap0,6565
92
+ kctl_react/core/compliance/checks/vite.py,sha256=Ou9RJWFhERN9Cuqelmzfe6ZjLSHwCjB1c3nJiIBvJhA,2400
93
+ kctl_react/core/compliance/fixes/__init__.py,sha256=P6FypK4bpuadY2pKu3U9fgHBsO4WoY0sNeu0rH15lOA,1001
94
+ kctl_react/core/compliance/fixes/codegen_fix.py,sha256=mHqq0V1cfWtRuzqyLUDuSafNe8jufJu4VOds2PRiH0w,702
95
+ kctl_react/core/compliance/fixes/i18n_fix.py,sha256=S9FMEZ-bRW2pahumIXYW2QmRz_-U07RS42A_mH9zSY0,1936
96
+ kctl_react/core/compliance/fixes/imports_fix.py,sha256=4Ov0TQhF-ymKxUdI9wusm9NSmj2jvvbJQ7m7ggAD5Hg,1050
97
+ kctl_react/core/compliance/fixes/structure_fix.py,sha256=RM_vhk8mMxVgMk8wfm0ngkuppQp_l8jcUzbs6i_J5mI,595
98
+ kctl_react/core/compliance/fixes/theme_fix.py,sha256=u9S2hnCCz1nf0Yxt9RU9EA41C3jbRbhdKc0gtoKLszc,854
99
+ kctl_react-0.6.2.dist-info/METADATA,sha256=yODefC7ln-Wda81Bhin6GS8fV1I3mbDnrLGSobY0RI0,578
100
+ kctl_react-0.6.2.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
101
+ kctl_react-0.6.2.dist-info/entry_points.txt,sha256=peRxA_VxciHpLSlQc3dwS5Zf_A5huLhNbKRm0_D9NOg,50
102
+ kctl_react-0.6.2.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.29.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ kctl-react = kctl_react.cli:app