code-mower 0.5.0b10__tar.gz → 0.5.0b11__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.
Files changed (262) hide show
  1. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/PKG-INFO +11 -7
  2. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/README.md +10 -6
  3. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/pyproject.toml +1 -1
  4. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/__init__.py +1 -1
  5. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/claude_audit_pr.py +15 -78
  6. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/cli.py +40 -75
  7. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/codex_audit_pr.py +32 -65
  8. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/package_manifest.py +5 -0
  9. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/provider_runners/__init__.py +20 -0
  10. code_mower-0.5.0b11/src/code_mower/provider_runners/pr_worktree.py +152 -0
  11. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower.egg-info/PKG-INFO +11 -7
  12. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower.egg-info/SOURCES.txt +2 -0
  13. code_mower-0.5.0b11/tests/test_provider_runners_pr_worktree.py +115 -0
  14. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/tests/test_release_hygiene.py +42 -37
  15. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/CODE_OF_CONDUCT.md +0 -0
  16. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/LICENSE +0 -0
  17. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/MANIFEST.in +0 -0
  18. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/NOTICE +0 -0
  19. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/SUPPORT.md +0 -0
  20. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/requirements/requirements.txt +0 -0
  21. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/setup.cfg +0 -0
  22. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/adapters/__init__.py +0 -0
  23. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/adapters/_base.py +0 -0
  24. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/adapters/cursor_bugbot.py +0 -0
  25. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/adapters/gitar.py +0 -0
  26. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/adapters/greptile.py +0 -0
  27. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/adapters/qodo.py +0 -0
  28. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/antigravity_cli_audit_pr.py +0 -0
  29. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/audit_handoff_log.py +0 -0
  30. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/audit_labeler_lib.py +0 -0
  31. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/audit_progress.py +0 -0
  32. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/blind_review_artifacts.py +0 -0
  33. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/blind_review_coordinator.py +0 -0
  34. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/bootstrap.py +0 -0
  35. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/builder_experiment.py +0 -0
  36. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/calibration/__init__.py +0 -0
  37. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/calibration/arms.py +0 -0
  38. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/calibration/auto_discovery.py +0 -0
  39. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/calibration/commands.py +0 -0
  40. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/calibration/context_inputs.py +0 -0
  41. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/calibration/corpus.py +0 -0
  42. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/calibration/evidence.py +0 -0
  43. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/calibration/evidence_report.py +0 -0
  44. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/calibration/identity.py +0 -0
  45. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/calibration/metrics.py +0 -0
  46. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/calibration/overlap.py +0 -0
  47. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/calibration/planning.py +0 -0
  48. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/calibration/policy.py +0 -0
  49. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/calibration/results.py +0 -0
  50. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/calibration/run_results.py +0 -0
  51. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/calibration/run_status.py +0 -0
  52. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/calibration/runner.py +0 -0
  53. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/calibration/truth.py +0 -0
  54. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/calibration/value_report.py +0 -0
  55. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/checks.py +0 -0
  56. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/claude_cli_bounce.py +0 -0
  57. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/claude_cli_environment.py +0 -0
  58. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/clear_stale.py +0 -0
  59. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/cloud.py +0 -0
  60. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/cloud_client/__init__.py +0 -0
  61. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/cloud_client/bundle.py +0 -0
  62. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/cloud_client/doctor.py +0 -0
  63. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/cloud_client/dogfood.py +0 -0
  64. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/cloud_client/endpoints.py +0 -0
  65. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/cloud_client/errors.py +0 -0
  66. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/cloud_client/events.py +0 -0
  67. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/cloud_client/export.py +0 -0
  68. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/cloud_client/git_metadata.py +0 -0
  69. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/cloud_client/manifest.py +0 -0
  70. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/cloud_client/operations.py +0 -0
  71. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/cloud_client/reports.py +0 -0
  72. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/cloud_client/setup.py +0 -0
  73. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/cloud_client/upload.py +0 -0
  74. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/code_mower_calibration.py +0 -0
  75. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/code_mower_context_packs.py +0 -0
  76. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/code_mower_merge.py +0 -0
  77. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/code_mower_telemetry.py +0 -0
  78. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/coderabbit_cli_audit_pr.py +0 -0
  79. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/codex_audit_env_preflight.py +0 -0
  80. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/codex_audit_schema_smoke.py +0 -0
  81. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/codex_audit_verdict.schema.json +0 -0
  82. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/config.py +0 -0
  83. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor.py +0 -0
  84. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/__init__.py +0 -0
  85. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/cloud.py +0 -0
  86. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/common.py +0 -0
  87. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/github.py +0 -0
  88. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/github_actions.py +0 -0
  89. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/github_actions_cost.py +0 -0
  90. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/github_actions_cost_summary.py +0 -0
  91. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/github_actions_failure_annotations.py +0 -0
  92. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/github_actions_failure_models.py +0 -0
  93. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/github_actions_failure_scan.py +0 -0
  94. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/github_actions_failure_selection.py +0 -0
  95. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/github_actions_failures.py +0 -0
  96. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/github_actions_permissions.py +0 -0
  97. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/github_api.py +0 -0
  98. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/github_branch.py +0 -0
  99. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/github_config.py +0 -0
  100. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/github_provider.py +0 -0
  101. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/github_repo.py +0 -0
  102. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/groups.py +0 -0
  103. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/models.py +0 -0
  104. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/output.py +0 -0
  105. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/presets.py +0 -0
  106. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/privacy.py +0 -0
  107. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/provider_api_model.py +0 -0
  108. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/provider_api_model_openai.py +0 -0
  109. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/provider_api_model_profiles.py +0 -0
  110. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/provider_env.py +0 -0
  111. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/provider_env_required.py +0 -0
  112. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/provider_env_tokens.py +0 -0
  113. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/provider_local_cli.py +0 -0
  114. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/provider_local_cli_commands.py +0 -0
  115. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/provider_local_cli_probe_config.py +0 -0
  116. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/provider_probe.py +0 -0
  117. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/provider_probe_auth.py +0 -0
  118. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/provider_probe_evaluation.py +0 -0
  119. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/provider_probe_json.py +0 -0
  120. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/provider_probe_remediation.py +0 -0
  121. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/providers.py +0 -0
  122. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/registry.py +0 -0
  123. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/runner.py +0 -0
  124. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/runtime.py +0 -0
  125. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/doctor_checks/runtime_github_auth.py +0 -0
  126. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/gemini_cli_audit_pr.py +0 -0
  127. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/hermes_cli_audit_pr.py +0 -0
  128. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/init.py +0 -0
  129. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/lane_configs/__init__.py +0 -0
  130. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/lane_configs/aider.py +0 -0
  131. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/lane_configs/antigravity_cli.py +0 -0
  132. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/lane_configs/claude.py +0 -0
  133. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/lane_configs/codex.py +0 -0
  134. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/lane_configs/devin.py +0 -0
  135. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/lane_configs/gemini_cli.py +0 -0
  136. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/lane_configs/hermes_cli.py +0 -0
  137. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/lane_configs/local_llm.py +0 -0
  138. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/local_llm_audit_pr.py +0 -0
  139. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/local_llm_bakeoff.py +0 -0
  140. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/local_llm_calibration.py +0 -0
  141. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/local_llm_profiles.py +0 -0
  142. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/migration.py +0 -0
  143. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/migration_install.py +0 -0
  144. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/migration_mirror.py +0 -0
  145. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/migration_readiness.py +0 -0
  146. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/migration_rehearsal.py +0 -0
  147. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/next_steps.py +0 -0
  148. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/package.py +0 -0
  149. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/package_content.py +0 -0
  150. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/package_paths.py +0 -0
  151. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/package_rendering.py +0 -0
  152. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/package_static.py +0 -0
  153. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/prompts.py +0 -0
  154. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/provider_registry.py +0 -0
  155. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/provider_runners/comments.py +0 -0
  156. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/provider_runners/git.py +0 -0
  157. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/provider_runners/github_auth.py +0 -0
  158. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/provider_runners/github_pr.py +0 -0
  159. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/provider_runners/process.py +0 -0
  160. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/provider_runners/repo_paths.py +0 -0
  161. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/provider_runners/text_schema.py +0 -0
  162. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/provider_runners/verdict_artifacts.py +0 -0
  163. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/provider_runners/workspace.py +0 -0
  164. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/release_readiness.py +0 -0
  165. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/reviewer_metrics.py +0 -0
  166. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/saas_reviewer_labeler.py +0 -0
  167. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/secrets.py +0 -0
  168. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/templates/builder-experiment.example.json +0 -0
  169. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/templates/calibration-corpus.example.json +0 -0
  170. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/templates/calibration-corpus.json +0 -0
  171. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/templates/code-mower.example.yml +0 -0
  172. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/templates/context-packs.example.json +0 -0
  173. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/templates/lane_prompts/base-audit.md +0 -0
  174. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/templates/lane_prompts/calibration-policy.md +0 -0
  175. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/templates/lane_prompts/context-driven-quality.md +0 -0
  176. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/templates/lane_prompts/docs-design.md +0 -0
  177. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/templates/lane_prompts/generic-programming.md +0 -0
  178. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/templates/lane_prompts/operability.md +0 -0
  179. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/templates/lane_prompts/package-runtime.md +0 -0
  180. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/templates/lane_prompts/security-threat-model.md +0 -0
  181. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/templates/product-support/code_mower +0 -0
  182. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/templates/product-support/code_mower_standalone_pin.env +0 -0
  183. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/templates/product-support/code_mower_standalone_shadow.sh +0 -0
  184. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/templates/product-support/run_claude_audit_pr.sh +0 -0
  185. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/templates/product-support/run_codex_audit_pr.sh +0 -0
  186. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/templates/product-support/safe_gh_comment.py +0 -0
  187. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/templates/providers.yml +0 -0
  188. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/templates/reviewer-spend.example.json +0 -0
  189. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/templates/reviewer-value-report.example.md +0 -0
  190. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/templates/workflows/audit-label-cleanup.yml.j2 +0 -0
  191. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/templates/workflows/hosted-bridge.yml.j2 +0 -0
  192. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/templates/workflows/local-cli-audit.yml.j2 +0 -0
  193. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/templates/workflows/private-standalone-shadow.yml.j2 +0 -0
  194. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/templates/workflows/review-clear-stale.yml.j2 +0 -0
  195. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/templates/workflows/saas-reviewer-labeler.yml.j2 +0 -0
  196. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/templates/workflows/trailer-comment-labeler.yml.j2 +0 -0
  197. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/trailer_comment_labeler.py +0 -0
  198. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower/versioning.py +0 -0
  199. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower.egg-info/dependency_links.txt +0 -0
  200. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower.egg-info/entry_points.txt +0 -0
  201. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower.egg-info/requires.txt +0 -0
  202. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/src/code_mower.egg-info/top_level.txt +0 -0
  203. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/templates/builder-experiment.example.json +0 -0
  204. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/templates/calibration-corpus.example.json +0 -0
  205. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/templates/calibration-corpus.json +0 -0
  206. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/templates/code-mower.yml.j2 +0 -0
  207. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/templates/context-packs.example.json +0 -0
  208. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/templates/cursor/BUGBOT.md +0 -0
  209. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/templates/providers/acp_bridge.yml +0 -0
  210. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/templates/providers/aider.yml +0 -0
  211. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/templates/providers/antigravity_cli.yml +0 -0
  212. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/templates/providers/claude_audit.yml +0 -0
  213. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/templates/providers/claude_review.yml +0 -0
  214. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/templates/providers/coderabbit_cli.yml +0 -0
  215. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/templates/providers/codex.yml +0 -0
  216. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/templates/providers/cursor_bugbot.yml +0 -0
  217. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/templates/providers/devin.yml +0 -0
  218. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/templates/providers/gemini_cli.yml +0 -0
  219. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/templates/providers/gitar.yml +0 -0
  220. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/templates/providers/greptile.yml +0 -0
  221. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/templates/providers/hermes_cli.yml +0 -0
  222. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/templates/providers/local_llm.yml +0 -0
  223. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/templates/providers/qodo.yml +0 -0
  224. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/templates/providers.yml +0 -0
  225. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/templates/reviewer-spend.example.json +0 -0
  226. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/templates/reviewer-value-report.example.md +0 -0
  227. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/templates/workflows/audit-label-cleanup.yml.j2 +0 -0
  228. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/templates/workflows/blind-review-artifacts-dry-run.yml.j2 +0 -0
  229. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/templates/workflows/hosted-bridge.yml.j2 +0 -0
  230. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/templates/workflows/local-cli-audit.yml.j2 +0 -0
  231. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/templates/workflows/private-standalone-shadow.yml.j2 +0 -0
  232. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/templates/workflows/review-clear-stale.yml.j2 +0 -0
  233. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/templates/workflows/saas-reviewer-labeler.yml.j2 +0 -0
  234. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/templates/workflows/trailer-comment-labeler.yml.j2 +0 -0
  235. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/tests/test_calibration_truth.py +0 -0
  236. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/tests/test_checks.py +0 -0
  237. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/tests/test_claude_cli_bounce.py +0 -0
  238. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/tests/test_clear_stale.py +0 -0
  239. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/tests/test_cloud_client.py +0 -0
  240. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/tests/test_cloud_git_metadata.py +0 -0
  241. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/tests/test_cloud_manifest.py +0 -0
  242. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/tests/test_cloud_reports.py +0 -0
  243. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/tests/test_coderabbit_cli_audit_pr.py +0 -0
  244. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/tests/test_doctor_actions_cost_summary.py +0 -0
  245. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/tests/test_doctor_actions_failure_selection.py +0 -0
  246. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/tests/test_doctor_boundaries.py +0 -0
  247. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/tests/test_doctor_github_checks.py +0 -0
  248. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/tests/test_doctor_output.py +0 -0
  249. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/tests/test_doctor_privacy.py +0 -0
  250. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/tests/test_doctor_provider_env_required.py +0 -0
  251. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/tests/test_doctor_provider_env_tokens.py +0 -0
  252. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/tests/test_doctor_provider_probe.py +0 -0
  253. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/tests/test_doctor_registry.py +0 -0
  254. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/tests/test_local_llm_github_helpers.py +0 -0
  255. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/tests/test_provider_runners_comments.py +0 -0
  256. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/tests/test_provider_runners_git.py +0 -0
  257. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/tests/test_provider_runners_github_pr.py +0 -0
  258. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/tests/test_provider_runners_process.py +0 -0
  259. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/tests/test_provider_runners_repo_paths.py +0 -0
  260. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/tests/test_provider_runners_text_schema.py +0 -0
  261. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/tests/test_provider_runners_workspace.py +0 -0
  262. {code_mower-0.5.0b10 → code_mower-0.5.0b11}/tests/test_reviewer_metrics_core.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-mower
3
- Version: 0.5.0b10
3
+ Version: 0.5.0b11
4
4
  Summary: Multi-reviewer AI code audit orchestration
5
5
  License-Expression: Apache-2.0
6
6
  Requires-Python: >=3.11
@@ -98,11 +98,11 @@ Code Mower currently targets Python 3.11+; Python 3.12 is recommended.
98
98
 
99
99
  ```bash
100
100
  python3.12 --version
101
- pipx install --python python3.12 code-mower==0.5.0b10
101
+ pipx install --python python3.12 code-mower==0.5.0b11
102
102
  code-mower --version
103
103
  ```
104
104
 
105
- `0.5.0b10` is a beta release. Until Code Mower publishes a stable `1.0`
105
+ `0.5.0b11` is a beta release. Until Code Mower publishes a stable `1.0`
106
106
  line, use the explicit beta version above or allow prereleases with:
107
107
 
108
108
  ```bash
@@ -143,6 +143,10 @@ every disposition before using it for lane promotion or merge policy.
143
143
  Full walkthrough: [docs/try-in-10-minutes.md](docs/try-in-10-minutes.md).
144
144
  First-time command map: [docs/launch-command-surface.md](docs/launch-command-surface.md).
145
145
 
146
+ The current PyPI beta has been rehearsed end-to-end from a clean install:
147
+ [First-User Install Rehearsal](docs/first-user-install-rehearsal.md) records
148
+ the latest 10/10 public-package readiness proof for `code-mower==0.5.0b11`.
149
+
146
150
  ## Why Not Just Run Codex Or Claude Yourself?
147
151
 
148
152
  You should, at first. Code Mower is not a replacement for a good local agent or
@@ -246,11 +250,11 @@ best?" to "which AI builder plus reviewer loop ships best on this product?" See
246
250
 
247
251
  ## Installation Status
248
252
 
249
- The current release target is `v0.5.0-beta.10` from
253
+ The current public beta is `v0.5.0-beta.11` from
250
254
  [codemower-ai/code-mower](https://github.com/codemower-ai/code-mower), published
251
- as `code-mower==0.5.0b10` on [PyPI](https://pypi.org/project/code-mower/)
252
- after release gates pass. GitHub releases remain the auditable source for tags,
253
- build artifacts, and release notes.
255
+ as `code-mower==0.5.0b11` on [PyPI](https://pypi.org/project/code-mower/).
256
+ GitHub releases remain the auditable source for tags, build artifacts, and
257
+ release notes.
254
258
 
255
259
  For source checkout development and release rehearsal, use:
256
260
 
@@ -86,11 +86,11 @@ Code Mower currently targets Python 3.11+; Python 3.12 is recommended.
86
86
 
87
87
  ```bash
88
88
  python3.12 --version
89
- pipx install --python python3.12 code-mower==0.5.0b10
89
+ pipx install --python python3.12 code-mower==0.5.0b11
90
90
  code-mower --version
91
91
  ```
92
92
 
93
- `0.5.0b10` is a beta release. Until Code Mower publishes a stable `1.0`
93
+ `0.5.0b11` is a beta release. Until Code Mower publishes a stable `1.0`
94
94
  line, use the explicit beta version above or allow prereleases with:
95
95
 
96
96
  ```bash
@@ -131,6 +131,10 @@ every disposition before using it for lane promotion or merge policy.
131
131
  Full walkthrough: [docs/try-in-10-minutes.md](docs/try-in-10-minutes.md).
132
132
  First-time command map: [docs/launch-command-surface.md](docs/launch-command-surface.md).
133
133
 
134
+ The current PyPI beta has been rehearsed end-to-end from a clean install:
135
+ [First-User Install Rehearsal](docs/first-user-install-rehearsal.md) records
136
+ the latest 10/10 public-package readiness proof for `code-mower==0.5.0b11`.
137
+
134
138
  ## Why Not Just Run Codex Or Claude Yourself?
135
139
 
136
140
  You should, at first. Code Mower is not a replacement for a good local agent or
@@ -234,11 +238,11 @@ best?" to "which AI builder plus reviewer loop ships best on this product?" See
234
238
 
235
239
  ## Installation Status
236
240
 
237
- The current release target is `v0.5.0-beta.10` from
241
+ The current public beta is `v0.5.0-beta.11` from
238
242
  [codemower-ai/code-mower](https://github.com/codemower-ai/code-mower), published
239
- as `code-mower==0.5.0b10` on [PyPI](https://pypi.org/project/code-mower/)
240
- after release gates pass. GitHub releases remain the auditable source for tags,
241
- build artifacts, and release notes.
243
+ as `code-mower==0.5.0b11` on [PyPI](https://pypi.org/project/code-mower/).
244
+ GitHub releases remain the auditable source for tags, build artifacts, and
245
+ release notes.
242
246
 
243
247
  For source checkout development and release rehearsal, use:
244
248
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "code-mower"
7
- version = "0.5.0b10"
7
+ version = "0.5.0b11"
8
8
  description = "Multi-reviewer AI code audit orchestration"
9
9
  requires-python = ">=3.11"
10
10
  readme = "README.md"
@@ -1,3 +1,3 @@
1
1
  """Code Mower package."""
2
2
 
3
- __version__ = "0.5.0b10"
3
+ __version__ = "0.5.0b11"
@@ -32,13 +32,17 @@ if __package__ in {None, "", "tools"}:
32
32
  from tools.provider_runners import (
33
33
  clip_text as _clip_text,
34
34
  fetch_pull_request,
35
+ fetch_base_ref_sha as _shared_fetch_base_ref_sha,
36
+ fetch_pr_head_sha as _shared_fetch_pr_head_sha,
35
37
  limit_comment_body,
36
38
  one_line as _one_line,
37
39
  parse_repo_paths as _parse_repo_paths,
38
40
  post_pr_comment,
41
+ FetchedHeadMismatch,
39
42
  repost_audit_verdict_artifact,
40
43
  require_exact_keys as _require_exact_keys,
41
44
  resolve_github_token_from_stdin_or_env,
45
+ run_git_text as _shared_run_git_text,
42
46
  write_audit_verdict_artifact,
43
47
  )
44
48
  except ImportError: # pragma: no cover - direct script execution fallback
@@ -51,13 +55,17 @@ if __package__ in {None, "", "tools"}:
51
55
  from provider_runners import ( # type: ignore
52
56
  clip_text as _clip_text,
53
57
  fetch_pull_request,
58
+ fetch_base_ref_sha as _shared_fetch_base_ref_sha,
59
+ fetch_pr_head_sha as _shared_fetch_pr_head_sha,
54
60
  limit_comment_body,
55
61
  one_line as _one_line,
56
62
  parse_repo_paths as _parse_repo_paths,
57
63
  post_pr_comment,
64
+ FetchedHeadMismatch,
58
65
  repost_audit_verdict_artifact,
59
66
  require_exact_keys as _require_exact_keys,
60
67
  resolve_github_token_from_stdin_or_env,
68
+ run_git_text as _shared_run_git_text,
61
69
  write_audit_verdict_artifact,
62
70
  )
63
71
  else: # pragma: no cover - exercised after package extraction.
@@ -65,8 +73,11 @@ else: # pragma: no cover - exercised after package extraction.
65
73
  from .audit_progress import AuditProgress, run_subprocess_with_progress
66
74
  from .claude_cli_environment import clean_claude_cli_env, env_flag
67
75
  from .provider_runners import (
76
+ FetchedHeadMismatch,
68
77
  clip_text as _clip_text,
78
+ fetch_base_ref_sha as _shared_fetch_base_ref_sha,
69
79
  fetch_pull_request,
80
+ fetch_pr_head_sha as _shared_fetch_pr_head_sha,
70
81
  limit_comment_body,
71
82
  one_line as _one_line,
72
83
  parse_repo_paths as _parse_repo_paths,
@@ -74,6 +85,7 @@ else: # pragma: no cover - exercised after package extraction.
74
85
  repost_audit_verdict_artifact,
75
86
  require_exact_keys as _require_exact_keys,
76
87
  resolve_github_token_from_stdin_or_env,
88
+ run_git_text as _shared_run_git_text,
77
89
  write_audit_verdict_artifact,
78
90
  )
79
91
 
@@ -175,15 +187,6 @@ class ClaudeAuditResult:
175
187
  verdict_artifact_path: Optional[Path] = None
176
188
 
177
189
 
178
- class FetchedHeadMismatch(RuntimeError):
179
- def __init__(self, expected_sha: str, actual_sha: str) -> None:
180
- self.expected_sha = expected_sha
181
- self.actual_sha = actual_sha
182
- super().__init__(
183
- f"fetched PR head {actual_sha} does not match expected {expected_sha}"
184
- )
185
-
186
-
187
190
  @dataclass(frozen=True)
188
191
  class DiffContext:
189
192
  stat: str
@@ -365,81 +368,15 @@ def _timeout_output(value: Any) -> str:
365
368
 
366
369
 
367
370
  def _run_git(local_repo: Path, args: List[str], *, timeout: int = 60) -> str:
368
- result = subprocess.run(
369
- ["git", "-C", str(local_repo), *args],
370
- check=True,
371
- text=True,
372
- capture_output=True,
373
- timeout=timeout,
374
- )
375
- return result.stdout
371
+ return _shared_run_git_text(local_repo, args, timeout=timeout)
376
372
 
377
373
 
378
374
  def _fetch_base_sha_for_diff(local_repo: Path, base_ref: str) -> str:
379
- temporary_ref = False
380
- if base_ref.startswith("origin/"):
381
- remote_branch = base_ref[len("origin/") :]
382
- local_ref = f"refs/remotes/origin/{remote_branch}"
383
- fetch_refspec = f"+{remote_branch}:{local_ref}"
384
- elif base_ref.startswith("refs/heads/"):
385
- remote_branch = base_ref[len("refs/heads/") :]
386
- local_ref = f"refs/remotes/origin/{remote_branch}"
387
- fetch_refspec = f"+{base_ref}:{local_ref}"
388
- elif "/" not in base_ref:
389
- local_ref = f"refs/remotes/origin/{base_ref}"
390
- fetch_refspec = f"+{base_ref}:{local_ref}"
391
- else:
392
- local_ref = f"refs/code-mower/base/{os.getpid()}-{secrets.token_hex(8)}"
393
- fetch_refspec = f"+{base_ref}:{local_ref}"
394
- temporary_ref = True
395
- try:
396
- subprocess.run(
397
- ["git", "-C", str(local_repo), "fetch", "origin", fetch_refspec],
398
- check=True,
399
- capture_output=True,
400
- text=True,
401
- )
402
- return _run_git(
403
- local_repo,
404
- ["rev-parse", "--verify", f"{local_ref}^{{commit}}"],
405
- ).strip()
406
- finally:
407
- if temporary_ref:
408
- subprocess.run(
409
- ["git", "-C", str(local_repo), "update-ref", "-d", local_ref],
410
- check=False,
411
- capture_output=True,
412
- text=True,
413
- )
375
+ return _shared_fetch_base_ref_sha(local_repo, base_ref)
414
376
 
415
377
 
416
378
  def _fetch_pr_head_sha_for_diff(local_repo: Path, pr_number: int) -> str:
417
- local_ref = f"refs/code-mower/pr/{pr_number}/{os.getpid()}-{secrets.token_hex(8)}"
418
- try:
419
- subprocess.run(
420
- [
421
- "git",
422
- "-C",
423
- str(local_repo),
424
- "fetch",
425
- "origin",
426
- f"+pull/{pr_number}/head:{local_ref}",
427
- ],
428
- check=True,
429
- capture_output=True,
430
- text=True,
431
- )
432
- return _run_git(
433
- local_repo,
434
- ["rev-parse", "--verify", f"{local_ref}^{{commit}}"],
435
- ).strip()
436
- finally:
437
- subprocess.run(
438
- ["git", "-C", str(local_repo), "update-ref", "-d", local_ref],
439
- check=False,
440
- capture_output=True,
441
- text=True,
442
- )
379
+ return _shared_fetch_pr_head_sha(local_repo, pr_number)
443
380
 
444
381
 
445
382
  def _clip_bytes(text: str, max_bytes: int) -> Tuple[str, bool]:
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env python3
2
- """Reference dispatcher for the future standalone Code Mower CLI."""
2
+ """Command dispatcher for the packaged Code Mower CLI."""
3
3
 
4
4
  from __future__ import annotations
5
5
 
@@ -11,82 +11,47 @@ import urllib.error
11
11
  import urllib.request
12
12
  from collections.abc import Callable
13
13
  from pathlib import Path
14
-
15
14
  if __package__ in {None, ""}:
16
- sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
17
-
18
- if __package__ in {None, "", "tools"}:
19
- from tools import __version__
20
- from tools import (
21
- antigravity_cli_audit_pr,
22
- blind_review_coordinator,
23
- bootstrap as code_mower_bootstrap,
24
- claude_audit_pr,
25
- claude_cli_bounce,
26
- clear_stale,
27
- coderabbit_cli_audit_pr,
28
- codex_audit_env_preflight,
29
- codex_audit_pr,
30
- codex_audit_schema_smoke,
31
- hermes_cli_audit_pr,
32
- code_mower_builder_experiment,
33
- code_mower_cloud,
34
- code_mower_config,
35
- code_mower_calibration,
36
- code_mower_context_packs,
37
- code_mower_doctor,
38
- code_mower_init,
39
- code_mower_merge,
40
- code_mower_next_steps,
41
- code_mower_package,
42
- code_mower_prompts,
43
- code_mower_telemetry,
44
- migration as code_mower_migration,
45
- gemini_cli_audit_pr,
46
- local_llm_bakeoff,
47
- local_llm_calibration,
48
- local_llm_audit_pr,
49
- local_llm_profiles,
50
- reviewer_metrics,
51
- saas_reviewer_labeler,
52
- trailer_comment_labeler,
15
+ raise SystemExit(
16
+ "code_mower.cli is a packaged entrypoint. Install Code Mower with "
17
+ "`pipx install code-mower==0.5.0b11`, or run source checkouts with "
18
+ "`PYTHONPATH=src python -m code_mower.cli`."
53
19
  )
54
- from code_mower import checks as code_mower_checks
55
- else: # pragma: no cover - exercised after package extraction.
56
- from . import __version__
57
- from . import blind_review_coordinator
58
- from . import antigravity_cli_audit_pr
59
- from . import bootstrap as code_mower_bootstrap
60
- from . import builder_experiment as code_mower_builder_experiment
61
- from . import claude_audit_pr
62
- from . import claude_cli_bounce
63
- from . import clear_stale
64
- from . import cloud as code_mower_cloud
65
- from . import coderabbit_cli_audit_pr
66
- from . import codex_audit_env_preflight
67
- from . import codex_audit_pr
68
- from . import codex_audit_schema_smoke
69
- from . import config as code_mower_config
70
- from . import code_mower_calibration
71
- from . import checks as code_mower_checks
72
- from . import code_mower_context_packs
73
- from . import code_mower_merge
74
- from . import next_steps as code_mower_next_steps
75
- from . import doctor as code_mower_doctor
76
- from . import gemini_cli_audit_pr
77
- from . import hermes_cli_audit_pr
78
- from . import init as code_mower_init
79
- from . import code_mower_telemetry
80
- from . import local_llm_bakeoff
81
- from . import local_llm_calibration
82
- from . import local_llm_audit_pr
83
- from . import local_llm_profiles
84
- from . import migration as code_mower_migration
85
- from . import package as code_mower_package
86
- from . import prompts as code_mower_prompts
87
- from . import reviewer_metrics
88
- from . import saas_reviewer_labeler
89
- from . import trailer_comment_labeler
20
+
21
+ from . import __version__
22
+ from . import antigravity_cli_audit_pr
23
+ from . import blind_review_coordinator
24
+ from . import bootstrap as code_mower_bootstrap
25
+ from . import builder_experiment as code_mower_builder_experiment
26
+ from . import checks as code_mower_checks
27
+ from . import claude_audit_pr
28
+ from . import claude_cli_bounce
29
+ from . import clear_stale
30
+ from . import cloud as code_mower_cloud
31
+ from . import coderabbit_cli_audit_pr
32
+ from . import codex_audit_env_preflight
33
+ from . import codex_audit_pr
34
+ from . import codex_audit_schema_smoke
35
+ from . import code_mower_calibration
36
+ from . import code_mower_context_packs
37
+ from . import code_mower_merge
38
+ from . import code_mower_telemetry
39
+ from . import config as code_mower_config
40
+ from . import doctor as code_mower_doctor
41
+ from . import gemini_cli_audit_pr
42
+ from . import hermes_cli_audit_pr
43
+ from . import init as code_mower_init
44
+ from . import local_llm_audit_pr
45
+ from . import local_llm_bakeoff
46
+ from . import local_llm_calibration
47
+ from . import local_llm_profiles
48
+ from . import migration as code_mower_migration
49
+ from . import next_steps as code_mower_next_steps
50
+ from . import package as code_mower_package
51
+ from . import prompts as code_mower_prompts
52
+ from . import reviewer_metrics
53
+ from . import saas_reviewer_labeler
54
+ from . import trailer_comment_labeler
90
55
 
91
56
 
92
57
  def _has_positional_config(argv: list[str], options_with_values: set[str]) -> bool:
@@ -40,16 +40,16 @@ CLI usage:
40
40
  owner/repo:/path/to/reference-app,\\
41
41
  owner/other-repo:/path/to/reference-service \\
42
42
  GITHUB_TOKEN=... \\
43
- tools/run_codex_audit_pr.sh --repo owner/other-repo --pr 233
43
+ code-mower codex-audit --repo owner/other-repo --pr 233
44
44
 
45
- Prefer the wrapper over direct `python3 tools/codex_audit_pr.py`: it
46
- selects a controlled Python interpreter for this script and refuses to
47
- fall back silently to ambient system Python.
45
+ Prefer the packaged CLI over direct module execution: the package entrypoint
46
+ selects the supported runtime path and avoids silently falling back to ambient
47
+ system Python.
48
48
 
49
49
  Module usage (called by `codex_audit_bridge.py` if/when we add a polling
50
50
  daemon analogous to local_llm_audit_bridge.py):
51
51
 
52
- from tools.codex_audit_pr import AuditConfig, audit_pr
52
+ from code_mower.codex_audit_pr import AuditConfig, audit_pr
53
53
  result = audit_pr(config, "owner/other-repo", 233)
54
54
 
55
55
  Exit codes (CLI mode):
@@ -87,14 +87,19 @@ if __package__ in {None, "", "tools"}:
87
87
  from tools.provider_runners import (
88
88
  clip_text as _clip_text,
89
89
  fetch_pull_request,
90
+ fetch_base_ref as _shared_fetch_base_ref,
91
+ fetch_pr_head as _shared_fetch_pr_head,
90
92
  limit_comment_body,
91
93
  one_line as _one_line,
92
94
  parse_repo_paths as _parse_repo_paths,
93
95
  pop_github_token_env,
94
96
  post_pr_comment,
97
+ create_temp_worktree as _shared_create_temp_worktree,
98
+ remove_worktree as _shared_remove_worktree,
95
99
  repost_audit_verdict_artifact,
96
100
  require_exact_keys as _require_exact_keys,
97
101
  resolve_github_token_from_stdin_or_env,
102
+ run_git_text as _shared_run_git_text,
98
103
  write_audit_verdict_artifact,
99
104
  )
100
105
  except ImportError: # pragma: no cover - direct script execution fallback
@@ -102,29 +107,39 @@ if __package__ in {None, "", "tools"}:
102
107
  from provider_runners import ( # type: ignore
103
108
  clip_text as _clip_text,
104
109
  fetch_pull_request,
110
+ fetch_base_ref as _shared_fetch_base_ref,
111
+ fetch_pr_head as _shared_fetch_pr_head,
105
112
  limit_comment_body,
106
113
  one_line as _one_line,
107
114
  parse_repo_paths as _parse_repo_paths,
108
115
  pop_github_token_env,
109
116
  post_pr_comment,
117
+ create_temp_worktree as _shared_create_temp_worktree,
118
+ remove_worktree as _shared_remove_worktree,
110
119
  repost_audit_verdict_artifact,
111
120
  require_exact_keys as _require_exact_keys,
112
121
  resolve_github_token_from_stdin_or_env,
122
+ run_git_text as _shared_run_git_text,
113
123
  write_audit_verdict_artifact,
114
124
  )
115
125
  else: # pragma: no cover - exercised after package extraction.
116
126
  from .audit_progress import AuditProgress, run_subprocess_with_progress
117
127
  from .provider_runners import (
118
128
  clip_text as _clip_text,
129
+ create_temp_worktree as _shared_create_temp_worktree,
130
+ fetch_base_ref as _shared_fetch_base_ref,
119
131
  fetch_pull_request,
132
+ fetch_pr_head as _shared_fetch_pr_head,
120
133
  limit_comment_body,
121
134
  one_line as _one_line,
122
135
  parse_repo_paths as _parse_repo_paths,
123
136
  pop_github_token_env,
124
137
  post_pr_comment,
138
+ remove_worktree as _shared_remove_worktree,
125
139
  repost_audit_verdict_artifact,
126
140
  require_exact_keys as _require_exact_keys,
127
141
  resolve_github_token_from_stdin_or_env,
142
+ run_git_text as _shared_run_git_text,
128
143
  write_audit_verdict_artifact,
129
144
  )
130
145
 
@@ -612,46 +627,21 @@ def dump_cli_failure(
612
627
  def _create_temp_worktree(local_repo: Path, head_sha: str) -> Path:
613
628
  """Create a detached worktree at `head_sha` under a tempdir. Returns
614
629
  the worktree path."""
615
- # First make sure the SHA is present locally. `git fetch origin
616
- # pull/<N>/head` would also work but we don't know the PR number here;
617
- # use a direct fetch of the commit.
618
- # Actually for PR commits not on main, we need to ensure the SHA is
619
- # locally available. The caller (audit_pr) handles this by passing
620
- # the head SHA after fetching pull/<n>/head.
621
- tmp_root = Path(tempfile.mkdtemp(prefix="codex-audit-"))
622
- worktree_path = tmp_root / "wt"
623
- subprocess.run(
624
- ["git", "-C", str(local_repo), "worktree", "add", "--detach",
625
- str(worktree_path), head_sha],
626
- check=True, capture_output=True, text=True,
630
+ return _shared_create_temp_worktree(
631
+ local_repo,
632
+ head_sha,
633
+ prefix="codex-audit-",
627
634
  )
628
- return worktree_path
629
635
 
630
636
 
631
637
  def _remove_worktree(local_repo: Path, worktree_path: Path) -> None:
632
638
  """Remove a worktree, ignoring errors (best-effort cleanup)."""
633
- try:
634
- subprocess.run(
635
- ["git", "-C", str(local_repo), "worktree", "remove", "--force",
636
- str(worktree_path)],
637
- check=False, capture_output=True, text=True,
638
- )
639
- except Exception: # noqa: BLE001
640
- pass
641
- # Also rmdir the tempdir parent
642
- try:
643
- worktree_path.parent.rmdir()
644
- except Exception: # noqa: BLE001
645
- pass
639
+ _shared_remove_worktree(local_repo, worktree_path)
646
640
 
647
641
 
648
642
  def _fetch_pr_head(local_repo: Path, pr_number: int) -> None:
649
643
  """Ensure the PR's head commit is locally available."""
650
- subprocess.run(
651
- ["git", "-C", str(local_repo), "fetch", "origin",
652
- f"pull/{pr_number}/head"],
653
- check=True, capture_output=True, text=True,
654
- )
644
+ _shared_fetch_pr_head(local_repo, pr_number)
655
645
 
656
646
 
657
647
  def _fetch_base_ref(local_repo: Path, base_ref: str) -> None:
@@ -666,33 +656,11 @@ def _fetch_base_ref(local_repo: Path, base_ref: str) -> None:
666
656
  `origin/main`. We `git fetch origin main` (the remote branch part)
667
657
  to update the corresponding tracking ref.
668
658
  """
669
- # Parse `origin/<branch>` or fall back to the full ref string.
670
- # Codex meta-review round 2 — P2: avoid str.removeprefix() (Python 3.9+
671
- # only). The repo's local `python3` is 3.7, and we don't want this
672
- # tool to require .venv just to extract a branch name.
673
- if "/" in base_ref and base_ref.startswith("origin/"):
674
- remote_branch = base_ref[len("origin/"):]
675
- subprocess.run(
676
- ["git", "-C", str(local_repo), "fetch", "origin", remote_branch],
677
- check=True, capture_output=True, text=True,
678
- )
679
- else:
680
- # Generic fetch — let git figure out the remote.
681
- subprocess.run(
682
- ["git", "-C", str(local_repo), "fetch", "origin", base_ref],
683
- check=True, capture_output=True, text=True,
684
- )
659
+ _shared_fetch_base_ref(local_repo, base_ref)
685
660
 
686
661
 
687
662
  def _run_git_text(local_repo: Path, args: List[str], *, timeout: int = 60) -> str:
688
- result = subprocess.run(
689
- ["git", "-C", str(local_repo), *args],
690
- check=True,
691
- capture_output=True,
692
- text=True,
693
- timeout=timeout,
694
- )
695
- return result.stdout
663
+ return _shared_run_git_text(local_repo, args, timeout=timeout)
696
664
 
697
665
 
698
666
  def _count_git_stdout_bytes(
@@ -1341,16 +1309,15 @@ def audit_pr(config: AuditConfig, repo: str, pr_number: int) -> AuditResult:
1341
1309
  )
1342
1310
  # Loud-failure contract: post_pr_comment() raises on any
1343
1311
  # HTTP error or network failure. DO NOT catch here. The
1344
- # wrapper (tools/run_codex_audit_pr.sh) relies on this
1312
+ # packaged CLI/product-support wrapper relies on this
1345
1313
  # script exiting non-zero when posting fails so its
1346
1314
  # finish_lock trap can log status="failed" instead of
1347
1315
  # "completed". A silent catch would re-create the
1348
1316
  # reference-app#184 silent-failure mode where three audit
1349
1317
  # runs reported exitCode=0 but never posted a GitHub
1350
- # comment. See run_codex_audit_pr.sh's finish_lock
1351
- # comment for the wrapper-side history and the memory
1352
- # file feedback_silent_success_silent_failure.md for the
1353
- # general lesson.
1318
+ # comment. See generated product-support wrapper
1319
+ # finish_lock handling for the wrapper-side history and
1320
+ # the general silent-success/silent-failure lesson.
1354
1321
  posted = post_pr_comment(repo, pr_number, comment_body,
1355
1322
  token=config.github_token)
1356
1323
  result.posted_comment_url = posted.get("html_url")
@@ -248,6 +248,11 @@ PACKAGE_FILES = (
248
248
  "src/code_mower/provider_runners/process.py",
249
249
  "reviewer",
250
250
  ),
251
+ (
252
+ "src/code_mower/provider_runners/pr_worktree.py",
253
+ "src/code_mower/provider_runners/pr_worktree.py",
254
+ "reviewer",
255
+ ),
251
256
  (
252
257
  "src/code_mower/provider_runners/repo_paths.py",
253
258
  "src/code_mower/provider_runners/repo_paths.py",
@@ -19,6 +19,17 @@ from .github_pr import (
19
19
  post_pr_comment,
20
20
  )
21
21
  from .process import DEFAULT_HOME_ENV_KEYS, build_allowlisted_child_env
22
+ from .pr_worktree import (
23
+ FetchedHeadMismatch,
24
+ create_temp_worktree,
25
+ fetch_base_ref,
26
+ fetch_base_ref_sha,
27
+ fetch_pr_head,
28
+ fetch_pr_head_sha,
29
+ fetch_pr_head_sha_or_raise,
30
+ remove_worktree,
31
+ run_git_text,
32
+ )
22
33
  from .repo_paths import parse_repo_paths
23
34
  from .text_schema import clip_text, one_line, require_exact_keys
24
35
  from .verdict_artifacts import (
@@ -36,7 +47,13 @@ __all__ = [
36
47
  "fetch_pull_request",
37
48
  "fetch_pull_request_diff",
38
49
  "fetch_pull_request_files",
50
+ "FetchedHeadMismatch",
51
+ "fetch_base_ref",
52
+ "fetch_base_ref_sha",
39
53
  "fetch_local_checkout_diff",
54
+ "fetch_pr_head",
55
+ "fetch_pr_head_sha",
56
+ "fetch_pr_head_sha_or_raise",
40
57
  "load_audit_verdict_artifact",
41
58
  "local_head_sha",
42
59
  "limit_comment_body",
@@ -53,6 +70,9 @@ __all__ = [
53
70
  "resolve_github_token_from_env_or_gh",
54
71
  "resolve_github_token_from_stdin_or_env",
55
72
  "run_git",
73
+ "run_git_text",
74
+ "create_temp_worktree",
75
+ "remove_worktree",
56
76
  "verify_checkout_at_head",
57
77
  "working_tree_status",
58
78
  "build_allowlisted_child_env",