code-mower 0.5.0b5__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 (185) hide show
  1. code_mower/__init__.py +3 -0
  2. code_mower/adapters/__init__.py +39 -0
  3. code_mower/adapters/_base.py +148 -0
  4. code_mower/adapters/cursor_bugbot.py +97 -0
  5. code_mower/adapters/gitar.py +111 -0
  6. code_mower/adapters/greptile.py +191 -0
  7. code_mower/adapters/qodo.py +140 -0
  8. code_mower/antigravity_cli_audit_pr.py +241 -0
  9. code_mower/audit_handoff_log.py +345 -0
  10. code_mower/audit_labeler_lib.py +311 -0
  11. code_mower/audit_progress.py +203 -0
  12. code_mower/blind_review_artifacts.py +562 -0
  13. code_mower/blind_review_coordinator.py +276 -0
  14. code_mower/bootstrap.py +524 -0
  15. code_mower/builder_experiment.py +539 -0
  16. code_mower/calibration/__init__.py +181 -0
  17. code_mower/calibration/arms.py +267 -0
  18. code_mower/calibration/auto_discovery.py +348 -0
  19. code_mower/calibration/commands.py +192 -0
  20. code_mower/calibration/context_inputs.py +199 -0
  21. code_mower/calibration/corpus.py +91 -0
  22. code_mower/calibration/evidence.py +20 -0
  23. code_mower/calibration/evidence_report.py +360 -0
  24. code_mower/calibration/identity.py +27 -0
  25. code_mower/calibration/metrics.py +18 -0
  26. code_mower/calibration/overlap.py +103 -0
  27. code_mower/calibration/planning.py +309 -0
  28. code_mower/calibration/policy.py +207 -0
  29. code_mower/calibration/results.py +315 -0
  30. code_mower/calibration/run_results.py +147 -0
  31. code_mower/calibration/run_status.py +64 -0
  32. code_mower/calibration/runner.py +360 -0
  33. code_mower/calibration/truth.py +188 -0
  34. code_mower/calibration/value_report.py +142 -0
  35. code_mower/checks.py +402 -0
  36. code_mower/claude_audit_pr.py +1126 -0
  37. code_mower/claude_cli_bounce.py +303 -0
  38. code_mower/claude_cli_environment.py +73 -0
  39. code_mower/clear_stale.py +374 -0
  40. code_mower/cli.py +537 -0
  41. code_mower/cloud.py +674 -0
  42. code_mower/cloud_client/__init__.py +173 -0
  43. code_mower/cloud_client/bundle.py +155 -0
  44. code_mower/cloud_client/doctor.py +206 -0
  45. code_mower/cloud_client/dogfood.py +78 -0
  46. code_mower/cloud_client/endpoints.py +114 -0
  47. code_mower/cloud_client/errors.py +7 -0
  48. code_mower/cloud_client/events.py +278 -0
  49. code_mower/cloud_client/export.py +272 -0
  50. code_mower/cloud_client/git_metadata.py +46 -0
  51. code_mower/cloud_client/manifest.py +39 -0
  52. code_mower/cloud_client/operations.py +448 -0
  53. code_mower/cloud_client/reports.py +45 -0
  54. code_mower/cloud_client/setup.py +205 -0
  55. code_mower/cloud_client/upload.py +97 -0
  56. code_mower/code_mower_calibration.py +598 -0
  57. code_mower/code_mower_context_packs.py +591 -0
  58. code_mower/code_mower_merge.py +227 -0
  59. code_mower/code_mower_telemetry.py +561 -0
  60. code_mower/coderabbit_cli_audit_pr.py +526 -0
  61. code_mower/codex_audit_env_preflight.py +220 -0
  62. code_mower/codex_audit_pr.py +1738 -0
  63. code_mower/codex_audit_schema_smoke.py +160 -0
  64. code_mower/codex_audit_verdict.schema.json +44 -0
  65. code_mower/config.py +655 -0
  66. code_mower/doctor.py +161 -0
  67. code_mower/doctor_checks/__init__.py +104 -0
  68. code_mower/doctor_checks/cloud.py +129 -0
  69. code_mower/doctor_checks/common.py +215 -0
  70. code_mower/doctor_checks/github.py +128 -0
  71. code_mower/doctor_checks/github_actions.py +11 -0
  72. code_mower/doctor_checks/github_actions_cost.py +99 -0
  73. code_mower/doctor_checks/github_actions_cost_summary.py +111 -0
  74. code_mower/doctor_checks/github_actions_failure_annotations.py +27 -0
  75. code_mower/doctor_checks/github_actions_failure_models.py +47 -0
  76. code_mower/doctor_checks/github_actions_failure_scan.py +200 -0
  77. code_mower/doctor_checks/github_actions_failure_selection.py +63 -0
  78. code_mower/doctor_checks/github_actions_failures.py +103 -0
  79. code_mower/doctor_checks/github_actions_permissions.py +55 -0
  80. code_mower/doctor_checks/github_api.py +79 -0
  81. code_mower/doctor_checks/github_branch.py +56 -0
  82. code_mower/doctor_checks/github_config.py +25 -0
  83. code_mower/doctor_checks/github_provider.py +61 -0
  84. code_mower/doctor_checks/github_repo.py +120 -0
  85. code_mower/doctor_checks/groups.py +36 -0
  86. code_mower/doctor_checks/models.py +96 -0
  87. code_mower/doctor_checks/output.py +86 -0
  88. code_mower/doctor_checks/presets.py +64 -0
  89. code_mower/doctor_checks/privacy.py +20 -0
  90. code_mower/doctor_checks/provider_api_model.py +138 -0
  91. code_mower/doctor_checks/provider_api_model_openai.py +29 -0
  92. code_mower/doctor_checks/provider_api_model_profiles.py +137 -0
  93. code_mower/doctor_checks/provider_env.py +113 -0
  94. code_mower/doctor_checks/provider_env_required.py +56 -0
  95. code_mower/doctor_checks/provider_env_tokens.py +100 -0
  96. code_mower/doctor_checks/provider_local_cli.py +162 -0
  97. code_mower/doctor_checks/provider_local_cli_commands.py +47 -0
  98. code_mower/doctor_checks/provider_local_cli_probe_config.py +70 -0
  99. code_mower/doctor_checks/provider_probe.py +20 -0
  100. code_mower/doctor_checks/provider_probe_auth.py +52 -0
  101. code_mower/doctor_checks/provider_probe_evaluation.py +109 -0
  102. code_mower/doctor_checks/provider_probe_json.py +45 -0
  103. code_mower/doctor_checks/provider_probe_remediation.py +39 -0
  104. code_mower/doctor_checks/providers.py +159 -0
  105. code_mower/doctor_checks/registry.py +69 -0
  106. code_mower/doctor_checks/runner.py +188 -0
  107. code_mower/doctor_checks/runtime.py +89 -0
  108. code_mower/doctor_checks/runtime_github_auth.py +148 -0
  109. code_mower/gemini_cli_audit_pr.py +897 -0
  110. code_mower/hermes_cli_audit_pr.py +436 -0
  111. code_mower/init.py +888 -0
  112. code_mower/lane_configs/__init__.py +37 -0
  113. code_mower/lane_configs/aider.py +32 -0
  114. code_mower/lane_configs/antigravity_cli.py +35 -0
  115. code_mower/lane_configs/claude.py +35 -0
  116. code_mower/lane_configs/codex.py +32 -0
  117. code_mower/lane_configs/devin.py +33 -0
  118. code_mower/lane_configs/gemini_cli.py +35 -0
  119. code_mower/lane_configs/hermes_cli.py +35 -0
  120. code_mower/lane_configs/local_llm.py +31 -0
  121. code_mower/local_llm_audit_pr.py +1364 -0
  122. code_mower/local_llm_bakeoff.py +458 -0
  123. code_mower/local_llm_calibration.py +441 -0
  124. code_mower/local_llm_profiles.py +66 -0
  125. code_mower/migration.py +508 -0
  126. code_mower/migration_install.py +292 -0
  127. code_mower/migration_mirror.py +392 -0
  128. code_mower/migration_readiness.py +237 -0
  129. code_mower/migration_rehearsal.py +718 -0
  130. code_mower/next_steps.py +441 -0
  131. code_mower/package.py +673 -0
  132. code_mower/package_content.py +444 -0
  133. code_mower/package_manifest.py +452 -0
  134. code_mower/package_paths.py +53 -0
  135. code_mower/package_rendering.py +90 -0
  136. code_mower/package_static.py +585 -0
  137. code_mower/prompts.py +267 -0
  138. code_mower/provider_registry.py +469 -0
  139. code_mower/provider_runners/__init__.py +60 -0
  140. code_mower/provider_runners/comments.py +31 -0
  141. code_mower/provider_runners/git.py +46 -0
  142. code_mower/provider_runners/github_auth.py +61 -0
  143. code_mower/provider_runners/github_pr.py +120 -0
  144. code_mower/provider_runners/process.py +58 -0
  145. code_mower/provider_runners/repo_paths.py +23 -0
  146. code_mower/provider_runners/text_schema.py +41 -0
  147. code_mower/provider_runners/verdict_artifacts.py +103 -0
  148. code_mower/provider_runners/workspace.py +57 -0
  149. code_mower/release_readiness.py +549 -0
  150. code_mower/reviewer_metrics.py +389 -0
  151. code_mower/saas_reviewer_labeler.py +809 -0
  152. code_mower/secrets.py +89 -0
  153. code_mower/templates/builder-experiment.example.json +55 -0
  154. code_mower/templates/calibration-corpus.example.json +129 -0
  155. code_mower/templates/calibration-corpus.json +129 -0
  156. code_mower/templates/code-mower.example.yml +423 -0
  157. code_mower/templates/context-packs.example.json +150 -0
  158. code_mower/templates/lane_prompts/base-audit.md +22 -0
  159. code_mower/templates/lane_prompts/calibration-policy.md +21 -0
  160. code_mower/templates/lane_prompts/context-driven-quality.md +21 -0
  161. code_mower/templates/lane_prompts/docs-design.md +12 -0
  162. code_mower/templates/lane_prompts/generic-programming.md +21 -0
  163. code_mower/templates/lane_prompts/operability.md +22 -0
  164. code_mower/templates/lane_prompts/package-runtime.md +12 -0
  165. code_mower/templates/lane_prompts/security-threat-model.md +22 -0
  166. code_mower/templates/product-support/code_mower +216 -0
  167. code_mower/templates/product-support/code_mower_standalone_pin.env +7 -0
  168. code_mower/templates/product-support/code_mower_standalone_shadow.sh +151 -0
  169. code_mower/templates/product-support/run_claude_audit_pr.sh +32 -0
  170. code_mower/templates/product-support/run_codex_audit_pr.sh +32 -0
  171. code_mower/templates/product-support/safe_gh_comment.py +96 -0
  172. code_mower/templates/providers.yml +454 -0
  173. code_mower/templates/reviewer-spend.example.json +28 -0
  174. code_mower/templates/reviewer-value-report.example.md +20 -0
  175. code_mower/templates/workflows/private-standalone-shadow.yml.j2 +106 -0
  176. code_mower/templates/workflows/review-clear-stale.yml.j2 +83 -0
  177. code_mower/trailer_comment_labeler.py +207 -0
  178. code_mower/versioning.py +32 -0
  179. code_mower-0.5.0b5.dist-info/METADATA +302 -0
  180. code_mower-0.5.0b5.dist-info/RECORD +185 -0
  181. code_mower-0.5.0b5.dist-info/WHEEL +5 -0
  182. code_mower-0.5.0b5.dist-info/entry_points.txt +2 -0
  183. code_mower-0.5.0b5.dist-info/licenses/LICENSE +202 -0
  184. code_mower-0.5.0b5.dist-info/licenses/NOTICE +10 -0
  185. code_mower-0.5.0b5.dist-info/top_level.txt +1 -0
@@ -0,0 +1,220 @@
1
+ #!/usr/bin/env python3
2
+ """Preflight the local environment for structured Codex audits.
3
+
4
+ This catches the common macOS failure mode where a freshly-created
5
+ framework-Python venv is executable but cannot validate GitHub TLS
6
+ certificates. Run after sourcing ``tools/codex_audit_env.sh`` and before
7
+ starting a long PR audit.
8
+ """
9
+ from __future__ import annotations
10
+
11
+ import argparse
12
+ import os
13
+ import subprocess
14
+ import sys
15
+ from dataclasses import dataclass
16
+ from pathlib import Path
17
+ from typing import Callable, Mapping, Optional, Sequence
18
+
19
+
20
+ DEFAULT_CODEX_CLI_PATH = "/Applications/Codex.app/Contents/Resources/codex"
21
+ DEFAULT_GITHUB_API_URL = "https://api.github.com"
22
+ ENV_HELP = "Run: source tools/codex_audit_env.sh"
23
+
24
+ Runner = Callable[..., subprocess.CompletedProcess]
25
+
26
+
27
+ @dataclass(frozen=True)
28
+ class CheckResult:
29
+ name: str
30
+ ok: bool
31
+ detail: str
32
+
33
+
34
+ def resolve_required_setting(
35
+ *,
36
+ cli_value: Optional[str],
37
+ env: Mapping[str, str],
38
+ env_name: str,
39
+ label: str,
40
+ ) -> CheckResult:
41
+ value = cli_value or env.get(env_name)
42
+ if not value:
43
+ return CheckResult(label, False, f"{env_name} is not set. {ENV_HELP}")
44
+ path = Path(value)
45
+ if not path.exists():
46
+ return CheckResult(label, False, f"{env_name} does not exist: {value}")
47
+ if not os.access(path, os.X_OK):
48
+ return CheckResult(label, False, f"{env_name} is not executable: {value}")
49
+ return CheckResult(label, True, str(path))
50
+
51
+
52
+ def _run_command(
53
+ command: Sequence[str],
54
+ *,
55
+ timeout: int,
56
+ runner: Runner = subprocess.run,
57
+ ) -> subprocess.CompletedProcess:
58
+ argv = list(command)
59
+ try:
60
+ return runner(
61
+ argv,
62
+ stdin=subprocess.DEVNULL,
63
+ capture_output=True,
64
+ text=True,
65
+ timeout=timeout,
66
+ )
67
+ except subprocess.TimeoutExpired as exc:
68
+ stdout = exc.stdout if isinstance(exc.stdout, str) else ""
69
+ stderr = exc.stderr if isinstance(exc.stderr, str) else ""
70
+ detail = stderr or stdout or f"timed out after {timeout}s"
71
+ return subprocess.CompletedProcess(argv, 1, stdout=stdout, stderr=detail)
72
+ except OSError as exc:
73
+ return subprocess.CompletedProcess(argv, 1, stdout="", stderr=str(exc))
74
+
75
+
76
+ def check_python_github_tls(
77
+ *,
78
+ python_path: str,
79
+ github_url: str,
80
+ timeout: int,
81
+ runner: Runner = subprocess.run,
82
+ ) -> CheckResult:
83
+ probe = (
84
+ "import urllib.error\n"
85
+ "import urllib.request\n"
86
+ "try:\n"
87
+ f" with urllib.request.urlopen({github_url!r}, timeout={timeout}) as response:\n"
88
+ " response.read(1)\n"
89
+ "except urllib.error.HTTPError as exc:\n"
90
+ " exc.close()\n"
91
+ "print('github TLS ok')\n"
92
+ )
93
+ result = _run_command(
94
+ [python_path, "-c", probe],
95
+ timeout=timeout,
96
+ runner=runner,
97
+ )
98
+ if result.returncode == 0:
99
+ return CheckResult("github TLS", True, result.stdout.strip() or github_url)
100
+ detail = (result.stderr or result.stdout or "").strip()
101
+ return CheckResult(
102
+ "github TLS",
103
+ False,
104
+ detail
105
+ or f"{python_path} could not reach {github_url}; check certificates/network.",
106
+ )
107
+
108
+
109
+ def check_codex_cli(
110
+ *,
111
+ codex_cli_path: str,
112
+ timeout: int,
113
+ runner: Runner = subprocess.run,
114
+ ) -> CheckResult:
115
+ result = _run_command(
116
+ [codex_cli_path, "--version"],
117
+ timeout=timeout,
118
+ runner=runner,
119
+ )
120
+ if result.returncode == 0:
121
+ return CheckResult("codex CLI", True, result.stdout.strip() or codex_cli_path)
122
+ detail = (result.stderr or result.stdout or "").strip()
123
+ return CheckResult("codex CLI", False, detail or f"{codex_cli_path} failed")
124
+
125
+
126
+ def run_preflight(
127
+ *,
128
+ python_path: str,
129
+ codex_cli_path: str,
130
+ github_url: str = DEFAULT_GITHUB_API_URL,
131
+ timeout: int = 10,
132
+ runner: Runner = subprocess.run,
133
+ ) -> list[CheckResult]:
134
+ return [
135
+ check_python_github_tls(
136
+ python_path=python_path,
137
+ github_url=github_url,
138
+ timeout=timeout,
139
+ runner=runner,
140
+ ),
141
+ check_codex_cli(
142
+ codex_cli_path=codex_cli_path,
143
+ timeout=timeout,
144
+ runner=runner,
145
+ ),
146
+ ]
147
+
148
+
149
+ def _print_results(results: Sequence[CheckResult], *, quiet: bool) -> None:
150
+ for result in results:
151
+ if quiet and result.ok:
152
+ continue
153
+ marker = "ok" if result.ok else "error"
154
+ stream = sys.stdout if result.ok else sys.stderr
155
+ print(f"{marker}: {result.name}: {result.detail}", file=stream)
156
+
157
+
158
+ def _parse_args(argv: Optional[Sequence[str]] = None) -> argparse.Namespace:
159
+ parser = argparse.ArgumentParser(description=__doc__)
160
+ parser.add_argument(
161
+ "--python",
162
+ dest="python_path",
163
+ help="Controlled Python to preflight. Defaults to CODEX_AUDIT_PYTHON.",
164
+ )
165
+ parser.add_argument(
166
+ "--codex-cli-path",
167
+ default=os.environ.get("CODEX_CLI_PATH"),
168
+ help="Codex CLI path. Defaults to CODEX_CLI_PATH.",
169
+ )
170
+ parser.add_argument(
171
+ "--github-url",
172
+ default=DEFAULT_GITHUB_API_URL,
173
+ help="HTTPS URL used to verify the selected Python's TLS store.",
174
+ )
175
+ parser.add_argument(
176
+ "--timeout",
177
+ type=int,
178
+ default=10,
179
+ help="Timeout in seconds for each probe.",
180
+ )
181
+ parser.add_argument(
182
+ "--quiet",
183
+ action="store_true",
184
+ help="Print only failures.",
185
+ )
186
+ return parser.parse_args(argv)
187
+
188
+
189
+ def main(argv: Optional[Sequence[str]] = None) -> int:
190
+ args = _parse_args(argv)
191
+ env = os.environ
192
+ python_check = resolve_required_setting(
193
+ cli_value=args.python_path,
194
+ env=env,
195
+ env_name="CODEX_AUDIT_PYTHON",
196
+ label="controlled Python",
197
+ )
198
+ codex_check = resolve_required_setting(
199
+ cli_value=args.codex_cli_path,
200
+ env=env,
201
+ env_name="CODEX_CLI_PATH",
202
+ label="Codex CLI",
203
+ )
204
+ setup_results = [python_check, codex_check]
205
+ if not all(result.ok for result in setup_results):
206
+ _print_results(setup_results, quiet=args.quiet)
207
+ return 1
208
+
209
+ probe_results = run_preflight(
210
+ python_path=python_check.detail,
211
+ codex_cli_path=codex_check.detail,
212
+ github_url=args.github_url,
213
+ timeout=args.timeout,
214
+ )
215
+ _print_results(setup_results + probe_results, quiet=args.quiet)
216
+ return 0 if all(result.ok for result in probe_results) else 1
217
+
218
+
219
+ if __name__ == "__main__":
220
+ raise SystemExit(main())