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,444 @@
1
+ """Generated package content builders and command inventory."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pathlib import Path
6
+
7
+
8
+ if __package__ in {None, "", "tools"}:
9
+ try:
10
+ from tools import code_mower_versioning
11
+ except ImportError: # pragma: no cover - package-installed fallback.
12
+ from code_mower import versioning as code_mower_versioning
13
+ else: # pragma: no cover - exercised after package extraction.
14
+ from . import versioning as code_mower_versioning
15
+
16
+
17
+ def current_alpha_package_spec(version: str) -> str:
18
+ """Return the documented installable package spec for prerelease users."""
19
+
20
+ return code_mower_versioning.public_package_spec(version)
21
+
22
+
23
+ def _init_py_text(version: str) -> str:
24
+ return f'"""Code Mower package."""\n\n__version__ = "{version}"\n'
25
+
26
+
27
+ def _pyproject_text(package_name: str, *, version: str) -> str:
28
+ return "\n".join(
29
+ [
30
+ "[build-system]",
31
+ 'requires = ["setuptools>=68"]',
32
+ 'build-backend = "setuptools.build_meta"',
33
+ "",
34
+ "[project]",
35
+ f'name = "{package_name}"',
36
+ f'version = "{version}"',
37
+ 'description = "Multi-reviewer AI code audit orchestration"',
38
+ 'requires-python = ">=3.11"',
39
+ 'readme = "README.md"',
40
+ 'license = {text = "Apache-2.0"}',
41
+ 'dependencies = ["PyYAML>=6.0"]',
42
+ "",
43
+ "[project.scripts]",
44
+ f'{package_name} = "code_mower.cli:main"',
45
+ "",
46
+ "[tool.setuptools.packages.find]",
47
+ 'where = ["src"]',
48
+ "",
49
+ "[tool.setuptools.package-data]",
50
+ 'code_mower = ["*.json", "templates/**/*.json", "templates/**/*.md", "templates/**/*.yml", "templates/**/*.yaml", "templates/**/*.j2", "templates/product-support/*"]',
51
+ "",
52
+ ]
53
+ )
54
+
55
+
56
+ def _workflow_template_text(target: str) -> str:
57
+ if target.endswith("blind-review-artifacts-dry-run.yml.j2"):
58
+ return "\n".join(
59
+ [
60
+ "# Code Mower blind-review artifact dry-run template",
61
+ "# Install as .github/workflows/code-mower-blind-review-artifacts-dry-run.yml.",
62
+ "name: Code Mower blind-review artifact dry run",
63
+ "on:",
64
+ " workflow_dispatch:",
65
+ "permissions:",
66
+ " contents: read",
67
+ " actions: write",
68
+ "jobs:",
69
+ " dry-run:",
70
+ " runs-on: ubuntu-latest",
71
+ " timeout-minutes: 10",
72
+ " steps:",
73
+ " - name: Check out workflow code",
74
+ " uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10",
75
+ " with:",
76
+ " persist-credentials: false",
77
+ " - name: Build synthetic manifests",
78
+ " run: |",
79
+ " set -euo pipefail",
80
+ " mkdir -p .code-mower/dry-run-source",
81
+ " printf 'Codex Audit: PASS\\n' > .code-mower/dry-run-source/codex.md",
82
+ " printf 'Claude Audit: PASS\\n' > .code-mower/dry-run-source/claude.md",
83
+ " python3 - <<'PY'",
84
+ " import json",
85
+ " import os",
86
+ " import subprocess",
87
+ " repo = os.environ.get('GITHUB_REPOSITORY', 'owner/repo')",
88
+ " head_sha = subprocess.check_output(['git', 'rev-parse', 'HEAD'], text=True).strip()",
89
+ " base = {'repo': repo, 'pr_number': 0, 'head_sha': head_sha, 'required_lanes': ['codex', 'claude_audit']}",
90
+ " hold = {**base, 'events': [{'lane': 'codex', 'state': 'done', 'artifact': 'dry-run-source/codex.md', 'head_sha': head_sha}, {'lane': 'claude_audit', 'state': 'running', 'head_sha': head_sha}]}",
91
+ " release = {**base, 'events': [{'lane': 'codex', 'state': 'done', 'artifact': 'dry-run-source/codex.md', 'head_sha': head_sha}, {'lane': 'claude_audit', 'state': 'done', 'artifact': 'dry-run-source/claude.md', 'head_sha': head_sha}]}",
92
+ " for name, payload in (('hold', hold), ('release', release)):",
93
+ " with open(f'.code-mower/{name}-manifest.json', 'w', encoding='utf-8') as handle:",
94
+ " json.dump(payload, handle, indent=2, sort_keys=True)",
95
+ " handle.write('\\n')",
96
+ " PY",
97
+ " - name: Install Code Mower",
98
+ " run: |",
99
+ " python3 -m pip install --upgrade pip",
100
+ " python3 -m pip install code-mower",
101
+ " code-mower --help",
102
+ " - name: Materialize held artifacts",
103
+ " run: |",
104
+ " code-mower blind-review artifacts .code-mower/hold-manifest.json --write --json",
105
+ " - name: Upload held artifacts",
106
+ " uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a",
107
+ " with:",
108
+ " name: code-mower-blind-review-held-dry-run",
109
+ " path: .code-mower/blind-review",
110
+ " include-hidden-files: true",
111
+ " retention-days: 1",
112
+ " - name: Download held artifacts",
113
+ " uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c",
114
+ " with:",
115
+ " name: code-mower-blind-review-held-dry-run",
116
+ " path: .code-mower/downloaded-held",
117
+ " - name: Release downloaded held artifacts",
118
+ " run: |",
119
+ " rm -f .code-mower/dry-run-source/codex.md",
120
+ " code-mower blind-review artifacts .code-mower/release-manifest.json --output-dir .code-mower/downloaded-held --write --json | tee .code-mower/release-plan.json",
121
+ " python3 - <<'PY'",
122
+ " import hashlib",
123
+ " import json",
124
+ " from pathlib import Path",
125
+ " def sha256_file(path):",
126
+ " digest = hashlib.sha256()",
127
+ " with path.open('rb') as handle:",
128
+ " for chunk in iter(lambda: handle.read(1024 * 1024), b''):",
129
+ " digest.update(chunk)",
130
+ " return digest.hexdigest()",
131
+ " plan = json.loads(Path('.code-mower/release-plan.json').read_text())",
132
+ " release_path = Path(plan['release_manifest']['path'])",
133
+ " if not release_path.is_file():",
134
+ " raise SystemExit(f'release manifest was not written: {release_path}')",
135
+ " for artifact in plan['release_manifest']['artifacts']:",
136
+ " path = Path(artifact['release_path'])",
137
+ " if not path.is_file():",
138
+ " raise SystemExit(f'release artifact was not written: {path}')",
139
+ " actual = sha256_file(path)",
140
+ " if artifact.get('release_sha256') != actual:",
141
+ " raise SystemExit(f'release artifact hash mismatch: {path}')",
142
+ " PY",
143
+ "",
144
+ ]
145
+ )
146
+ if target.endswith("private-standalone-shadow.yml.j2"):
147
+ return (
148
+ r"""name: Code Mower standalone shadow
149
+
150
+ on:
151
+ pull_request:
152
+ paths:
153
+ - "tools/code_mower"
154
+ - "tools/code_mower_standalone_shadow.sh"
155
+ - "tools/code_mower_standalone_pin.env"
156
+ - "tools/code_mower_*.py"
157
+ - "tools/CODE_MOWER*.md"
158
+ - "code-mower*.yml"
159
+ - ".github/workflows/code-mower-standalone-shadow.yml"
160
+ workflow_dispatch:
161
+
162
+ permissions:
163
+ contents: read
164
+
165
+ env:
166
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
167
+ CODE_MOWER_STANDALONE_REPO_URL: {{ code_mower_standalone_repo_url | default('https://github.com/OWNER/code-mower.git', true) }}
168
+ CODE_MOWER_STANDALONE_PACKAGE_REPO_URL: {{ code_mower_standalone_package_repo_url | default('git+ssh://git@github.com/OWNER/code-mower.git', true) }}
169
+ CODE_MOWER_STANDALONE_REINSTALL: "1"
170
+ CODE_MOWER_BOOTSTRAP_PYTHON: python3
171
+
172
+ jobs:
173
+ shadow:
174
+ if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
175
+ runs-on: ubuntu-latest
176
+ timeout-minutes: 10
177
+ steps:
178
+ - name: Check out product repo
179
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10
180
+ with:
181
+ persist-credentials: false
182
+
183
+ - name: Configure Code Mower deploy key
184
+ shell: bash
185
+ env:
186
+ CODE_MOWER_STANDALONE_DEPLOY_KEY: {% raw %}${{ secrets.CODE_MOWER_STANDALONE_DEPLOY_KEY }}{% endraw %}
187
+ run: |
188
+ set -euo pipefail
189
+ if [ -z "${CODE_MOWER_STANDALONE_DEPLOY_KEY}" ]; then
190
+ echo "::error::Missing CODE_MOWER_STANDALONE_DEPLOY_KEY. Add a read-only deploy key for the configured Code Mower standalone repository to this repository's Actions secrets."
191
+ exit 1
192
+ fi
193
+ install -m 700 -d ~/.ssh
194
+ printf '%s\n' "${CODE_MOWER_STANDALONE_DEPLOY_KEY}" > ~/.ssh/code_mower_standalone
195
+ chmod 600 ~/.ssh/code_mower_standalone
196
+ ssh-keyscan github.com > ~/.ssh/known_hosts
197
+ cat > ~/.ssh/config <<'EOF'
198
+ Host github.com
199
+ IdentityFile ~/.ssh/code_mower_standalone
200
+ IdentitiesOnly yes
201
+ StrictHostKeyChecking yes
202
+ EOF
203
+ chmod 600 ~/.ssh/config
204
+
205
+ - name: Run standalone wrapper shadow proof
206
+ shell: bash
207
+ run: |
208
+ set -euo pipefail
209
+ mkdir -p .code-mower
210
+ tools/code_mower --version
211
+ tools/code_mower doctor --easy --json | tee .code-mower/standalone-doctor.json
212
+ tools/code_mower migration wrapper-rehearsal \
213
+ --repo-path "$GITHUB_WORKSPACE" \
214
+ --local-command "env CODE_MOWER_USE_LOCAL=1 tools/code_mower" \
215
+ --package-command "tools/code_mower" \
216
+ --timeout 120 \
217
+ --json | tee .code-mower/standalone-wrapper-rehearsal.json
218
+ code_mower_ref="${CODE_MOWER_STANDALONE_REF:-}"
219
+ if [ -z "${code_mower_ref}" ]; then
220
+ code_mower_ref="$(sed -n 's/^CODE_MOWER_STANDALONE_REF="\([^"]*\)"/\1/p' tools/code_mower_standalone_pin.env)"
221
+ fi
222
+ if [ -z "${code_mower_ref}" ]; then
223
+ echo "::error::tools/code_mower_standalone_pin.env does not define CODE_MOWER_STANDALONE_REF"
224
+ exit 1
225
+ fi
226
+ if [ "${code_mower_ref}" = "<pin-a-reviewed-code-mower-commit-or-tag>" ]; then
227
+ echo "::error::replace the placeholder CODE_MOWER_STANDALONE_REF before package-install rehearsal"
228
+ exit 1
229
+ fi
230
+ if [ "${CODE_MOWER_STANDALONE_PACKAGE_REPO_URL:-}" = "" ] || [ "${CODE_MOWER_STANDALONE_PACKAGE_REPO_URL}" = "git+ssh://git@github.com/OWNER/code-mower.git" ]; then
231
+ echo "::error::replace CODE_MOWER_STANDALONE_PACKAGE_REPO_URL with a pip-installable Code Mower package source"
232
+ exit 1
233
+ fi
234
+ package_spec="${CODE_MOWER_STANDALONE_PACKAGE_REPO_URL}@${code_mower_ref}"
235
+ tools/code_mower migration package-install-rehearsal \
236
+ --package-spec "$package_spec" \
237
+ --repo-path "$GITHUB_WORKSPACE" \
238
+ --local-command "env CODE_MOWER_USE_LOCAL=1 tools/code_mower" \
239
+ --work-dir "$GITHUB_WORKSPACE/.code-mower/package-install-rehearsal" \
240
+ --timeout 180 \
241
+ --json | tee .code-mower/package-install-rehearsal.json
242
+
243
+ - name: Upload shadow proof artifacts
244
+ if: always()
245
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
246
+ with:
247
+ name: code-mower-standalone-shadow
248
+ path: |
249
+ .code-mower/standalone-doctor.json
250
+ .code-mower/standalone-wrapper-rehearsal.json
251
+ .code-mower/package-install-rehearsal.json
252
+ if-no-files-found: ignore
253
+ retention-days: 7
254
+ """.strip()
255
+ + "\n"
256
+ )
257
+ if target.endswith("review-clear-stale.yml.j2"):
258
+ return (
259
+ r"""# Code Mower workflow template: clear stale terminal audit labels on new commits.
260
+ #
261
+ # Defaults to the Devin lane because hosted/paid lanes are the most likely to
262
+ # need explicit re-dispatch. Change CLEAR_STALE_LANE or generate one workflow
263
+ # per merge-authority lane.
264
+ name: Code Mower Clear Stale Audits
265
+
266
+ on:
267
+ pull_request_target:
268
+ types: [synchronize]
269
+ workflow_dispatch:
270
+ inputs:
271
+ lane:
272
+ description: "Code Mower trailer lane, for example devin"
273
+ required: false
274
+ default: "devin"
275
+ pr:
276
+ description: "Pull request number for manual runs"
277
+ required: false
278
+ head_sha:
279
+ description: "Current PR head SHA for manual runs"
280
+ required: false
281
+
282
+ permissions:
283
+ actions: write
284
+ contents: read
285
+ issues: write
286
+ pull-requests: read
287
+
288
+ concurrency:
289
+ group: {% raw %}code-mower-clear-stale-${{ github.event.pull_request.number || github.event.inputs.pr || github.run_id }}{% endraw %}
290
+ cancel-in-progress: true
291
+
292
+ jobs:
293
+ clear-stale:
294
+ runs-on: ubuntu-latest
295
+ env:
296
+ CLEAR_STALE_LANE: {% raw %}${{ github.event.inputs.lane || 'devin' }}{% endraw %}
297
+ CLEAR_STALE_PR: {% raw %}${{ github.event.pull_request.number || github.event.inputs.pr }}{% endraw %}
298
+ CLEAR_STALE_HEAD_SHA: {% raw %}${{ github.event.pull_request.head.sha || github.event.inputs.head_sha }}{% endraw %}
299
+ # Optional: dispatch the paid/hosted audit bridge directly when this
300
+ # command adds a fresh needs-* label. Keep unset for label-only requeue.
301
+ # CLEAR_STALE_DISPATCH_WORKFLOW: devin-audit-bridge.yml
302
+ # CLEAR_STALE_DISPATCH_REF: main
303
+ # CLEAR_STALE_DISPATCH_INPUTS: |
304
+ # pr_number={pr}
305
+ steps:
306
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10
307
+ with:
308
+ persist-credentials: false
309
+
310
+ - name: Clear stale Code Mower audit labels
311
+ env:
312
+ GITHUB_TOKEN: {% raw %}${{ secrets.GITHUB_TOKEN }}{% endraw %}
313
+ run: |
314
+ set -euo pipefail
315
+
316
+ if [ -z "${CLEAR_STALE_PR:-}" ] || [ -z "${CLEAR_STALE_HEAD_SHA:-}" ]; then
317
+ echo "::notice::No PR/head SHA available for stale-label cleanup; skipping."
318
+ exit 0
319
+ fi
320
+
321
+ extra_args=()
322
+ if [ -n "${CLEAR_STALE_DISPATCH_WORKFLOW:-}" ]; then
323
+ extra_args+=(--dispatch-workflow "${CLEAR_STALE_DISPATCH_WORKFLOW}")
324
+ fi
325
+ if [ -n "${CLEAR_STALE_DISPATCH_REF:-}" ]; then
326
+ extra_args+=(--dispatch-ref "${CLEAR_STALE_DISPATCH_REF}")
327
+ fi
328
+ if [ -n "${CLEAR_STALE_DISPATCH_INPUTS:-}" ]; then
329
+ while IFS= read -r dispatch_input; do
330
+ [ -n "${dispatch_input}" ] || continue
331
+ extra_args+=(--dispatch-input "${dispatch_input}")
332
+ done <<< "${CLEAR_STALE_DISPATCH_INPUTS}"
333
+ fi
334
+
335
+ tools/code_mower clear-stale \
336
+ --lane "${CLEAR_STALE_LANE}" \
337
+ --repo "${GITHUB_REPOSITORY}" \
338
+ --pr "${CLEAR_STALE_PR}" \
339
+ --head-sha "${CLEAR_STALE_HEAD_SHA}" \
340
+ --json \
341
+ "${extra_args[@]}"
342
+ """.strip()
343
+ + "\n"
344
+ )
345
+ workflow_name = Path(target).stem.replace("-", " ").title()
346
+ return "\n".join(
347
+ [
348
+ "# Code Mower workflow template",
349
+ "# Replace placeholders before installing this in .github/workflows/.",
350
+ f"name: {workflow_name}",
351
+ "on:",
352
+ " workflow_dispatch:",
353
+ "jobs:",
354
+ " configure-code-mower:",
355
+ " runs-on: ubuntu-latest",
356
+ " steps:",
357
+ ' - run: echo "Install this generated template in a repository workflow."',
358
+ "",
359
+ ]
360
+ )
361
+
362
+
363
+ def _config_template_text() -> str:
364
+ return "\n".join(
365
+ [
366
+ "# Code Mower config template",
367
+ "version: 1",
368
+ "project:",
369
+ ' name: "{{ project_name }}"',
370
+ ' state_dir: "{{ state_dir }}"',
371
+ "repositories:",
372
+ ' - slug: "{{ repository_slug }}"',
373
+ " default_branch: main",
374
+ "lanes: {}",
375
+ "profiles: {}",
376
+ "",
377
+ ]
378
+ )
379
+
380
+
381
+ def cli_commands(version: str) -> tuple[str, ...]:
382
+ return (
383
+ "code-mower config validate code-mower.yml",
384
+ "code-mower config plan code-mower.yml --json",
385
+ "code-mower init --easy",
386
+ "code-mower init --easy --apply --output-dir .code-mower.generated",
387
+ "code-mower next-steps --profile recommended",
388
+ "code-mower next-steps --profile recommended --json",
389
+ "code-mower builder-experiment plan builder-experiment.json --json",
390
+ "code-mower builder-experiment report builder-experiment.json --runs builder-results.json --output builder-experiment-report.md",
391
+ "code-mower calibration plan calibration-corpus.json --replicates 2 --json",
392
+ "code-mower calibration run calibration-corpus.json --lanes antigravity-cli,gemini-cli,hermes-cli --results-dir .code-mower/calibration-results --json",
393
+ "code-mower calibration evidence calibration-corpus.json --json",
394
+ "code-mower calibration value-report calibration-corpus.json --runs .code-mower/calibration-results/calibration-run-results.json --output reviewer-value-report.md",
395
+ "code-mower calibration overlap calibration.json --json",
396
+ "code-mower doctor --easy --json",
397
+ "code-mower doctor --profile recommended --json",
398
+ "code-mower doctor --profile privacy --probe-runtime --json",
399
+ "code-mower checks detect --json",
400
+ "code-mower checks run --dry-run --json",
401
+ "code-mower init --profile recommended --dry-run",
402
+ "code-mower init --profile recommended --apply --output-dir .code-mower.generated",
403
+ "code-mower merge-plan owner/repo#123 --json",
404
+ "code-mower clear-stale --lane devin --repo owner/repo --pr 123 --json",
405
+ "code-mower migration wrapper-rehearsal --repo-path /path/to/product-repo --json",
406
+ "code-mower migration mirror-removal-plan --repo-path /path/to/product-repo --shadow-cycles 1 --standalone-default-cycles 1 --json",
407
+ "code-mower migration runner-aliases --json",
408
+ (
409
+ "code-mower migration package-install-rehearsal "
410
+ f"--package-spec {current_alpha_package_spec(version)} "
411
+ "--repo-path /path/to/product-repo --json"
412
+ ),
413
+ "code-mower local-llm profiles --json",
414
+ "code-mower local-llm probe --profile qwen3-coder-next-lmstudio --json",
415
+ "code-mower local-llm probe --profile gemma4-ollama --json",
416
+ "code-mower local-llm audit --repo owner/repo --pr 123 --dry-run --max-files 8",
417
+ "code-mower local-llm bakeoff --repo owner/repo --pr 123 --profiles qwen3-coder-next-lmstudio,gemma4-ollama --json",
418
+ "code-mower local-llm calibrate /tmp/code-mower-local-bakeoff/summary.json --json",
419
+ "code-mower gemini-cli --repo owner/repo --pr 123 --output-dir .code-mower/calibration/pr-123/gemini-cli --json",
420
+ "code-mower antigravity-cli --repo owner/repo --pr 123 --output-dir .code-mower/calibration/pr-123/antigravity-cli --json",
421
+ "code-mower hermes-cli --repo owner/repo --pr 123 --output-dir .code-mower/calibration/pr-123/hermes-cli --json",
422
+ "code-mower coderabbit-cli --repo owner/repo --pr 123 --repo-path /path/to/pr-worktree --output-dir .code-mower/calibration/pr-123/coderabbit-cli --json",
423
+ "code-mower local-llm calibrate /tmp/code-mower-local-bakeoff/summary.json --write-disposition-template dispositions.json",
424
+ "code-mower context-packs context-packs.json --json",
425
+ "code-mower context-packs templates/context-packs.example.json --json",
426
+ "code-mower context-packs context-packs.json --write --output-dir .code-mower/context-packs --json",
427
+ "code-mower prompts list --json",
428
+ "code-mower prompts show base-audit --json",
429
+ "code-mower prompts validate --lenses base-audit,calibration-policy,package-runtime --json",
430
+ "code-mower prompts validate --lenses base-audit,generic-programming,context-driven-quality --json",
431
+ "code-mower prompts validate --lenses base-audit,security-threat-model,operability --json",
432
+ "code-mower reviewer-metrics calibration.json --spend templates/reviewer-spend.example.json --json",
433
+ "code-mower blind-review plan blind-review-manifest.json --json",
434
+ "code-mower blind-review artifacts blind-review-manifest.json --json",
435
+ "code-mower blind-review artifacts blind-review-manifest.json --write --require-sources --json",
436
+ "code-mower providers list",
437
+ "code-mower providers show <provider>",
438
+ "code-mower telemetry summarize ~/.cache/code-mower-audits/events.jsonl --json",
439
+ "code-mower cloud export --report reviewer-metrics=reviewer-metrics.json --report lane-policy=lane-policy.json --report value-report=reviewer-value-report.md --output-dir .code-mower/cloud-benchmark-bundle --json",
440
+ "code-mower cloud setup --token-stdin --team-id YOUR_TEAM_SLUG --install-id YOUR_INSTALL_ID --out ~/.config/code-mower/tokens/YOUR_INSTALL_ID.env",
441
+ "code-mower cloud upload .code-mower/cloud-benchmark-bundle --dry-run --json",
442
+ "python scripts/smoke_easy_mode.py --json",
443
+ "python scripts/fresh_clone_rehearsal.py --json",
444
+ )