code-mower 0.5.0b37__tar.gz → 0.5.0b38__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 (275) hide show
  1. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/PKG-INFO +6 -6
  2. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/README.md +5 -5
  3. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/pyproject.toml +1 -1
  4. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/__init__.py +1 -1
  5. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/calibration/arms.py +7 -1
  6. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/calibration/commands.py +8 -1
  7. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/calibration/context_inputs.py +6 -1
  8. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/calibration/planning.py +6 -1
  9. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/calibration/results.py +8 -1
  10. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/cli.py +4 -1
  11. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/codex_audit_env_preflight.py +13 -3
  12. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/codex_audit_pr.py +1 -1
  13. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/common.py +14 -1
  14. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/provider_env.py +13 -2
  15. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/provider_env_required.py +29 -3
  16. code_mower-0.5.0b38/src/code_mower/grok_build_audit_pr.py +451 -0
  17. code_mower-0.5.0b38/src/code_mower/lane_configs/grok_build.py +35 -0
  18. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/package_manifest.py +2 -0
  19. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/provider_registry.py +53 -0
  20. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/templates/code-mower.example.yml +51 -1
  21. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/templates/providers.yml +52 -1
  22. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower.egg-info/PKG-INFO +6 -6
  23. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower.egg-info/SOURCES.txt +3 -0
  24. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/templates/providers.yml +52 -1
  25. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/tests/test_calibration_truth.py +51 -0
  26. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/tests/test_clear_stale.py +8 -0
  27. code_mower-0.5.0b38/tests/test_codex_audit_env_preflight.py +51 -0
  28. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/tests/test_doctor_provider_env_required.py +42 -0
  29. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/tests/test_provider_local_cli.py +36 -0
  30. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/tests/test_release_hygiene.py +42 -35
  31. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/CODE_OF_CONDUCT.md +0 -0
  32. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/LICENSE +0 -0
  33. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/MANIFEST.in +0 -0
  34. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/NOTICE +0 -0
  35. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/SUPPORT.md +0 -0
  36. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/requirements/requirements.txt +0 -0
  37. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/setup.cfg +0 -0
  38. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/adapters/__init__.py +0 -0
  39. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/adapters/_base.py +0 -0
  40. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/adapters/cursor_bugbot.py +0 -0
  41. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/adapters/gitar.py +0 -0
  42. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/adapters/greptile.py +0 -0
  43. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/adapters/qodo.py +0 -0
  44. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/antigravity_cli_audit_pr.py +0 -0
  45. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/audit_handoff_log.py +0 -0
  46. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/audit_labeler_lib.py +0 -0
  47. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/audit_progress.py +0 -0
  48. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/blind_review_artifacts.py +0 -0
  49. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/blind_review_coordinator.py +0 -0
  50. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/bootstrap.py +0 -0
  51. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/builder_experiment.py +0 -0
  52. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/calibration/__init__.py +0 -0
  53. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/calibration/auto_discovery.py +0 -0
  54. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/calibration/corpus.py +0 -0
  55. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/calibration/effect_report.py +0 -0
  56. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/calibration/evidence.py +0 -0
  57. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/calibration/evidence_report.py +0 -0
  58. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/calibration/identity.py +0 -0
  59. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/calibration/metrics.py +0 -0
  60. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/calibration/overlap.py +0 -0
  61. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/calibration/policy.py +0 -0
  62. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/calibration/run_results.py +0 -0
  63. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/calibration/run_status.py +0 -0
  64. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/calibration/runner.py +0 -0
  65. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/calibration/truth.py +0 -0
  66. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/calibration/value_report.py +0 -0
  67. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/checks.py +0 -0
  68. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/claude_audit_pr.py +0 -0
  69. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/claude_cli_bounce.py +0 -0
  70. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/claude_cli_environment.py +0 -0
  71. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/clear_stale.py +0 -0
  72. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/cloud.py +0 -0
  73. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/cloud_client/__init__.py +0 -0
  74. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/cloud_client/bundle.py +0 -0
  75. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/cloud_client/doctor.py +0 -0
  76. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/cloud_client/dogfood.py +0 -0
  77. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/cloud_client/endpoints.py +0 -0
  78. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/cloud_client/errors.py +0 -0
  79. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/cloud_client/events.py +0 -0
  80. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/cloud_client/export.py +0 -0
  81. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/cloud_client/git_metadata.py +0 -0
  82. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/cloud_client/manifest.py +0 -0
  83. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/cloud_client/operations.py +0 -0
  84. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/cloud_client/reports.py +0 -0
  85. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/cloud_client/setup.py +0 -0
  86. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/cloud_client/upload.py +0 -0
  87. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/code_mower_calibration.py +0 -0
  88. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/code_mower_context_packs.py +0 -0
  89. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/code_mower_merge.py +0 -0
  90. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/code_mower_telemetry.py +0 -0
  91. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/coderabbit_cli_audit_pr.py +0 -0
  92. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/codex_audit_schema_smoke.py +0 -0
  93. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/codex_audit_verdict.schema.json +0 -0
  94. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/config.py +0 -0
  95. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor.py +0 -0
  96. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/__init__.py +0 -0
  97. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/cloud.py +0 -0
  98. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/github.py +0 -0
  99. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/github_actions.py +0 -0
  100. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/github_actions_cost.py +0 -0
  101. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/github_actions_cost_summary.py +0 -0
  102. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/github_actions_failure_annotations.py +0 -0
  103. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/github_actions_failure_models.py +0 -0
  104. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/github_actions_failure_scan.py +0 -0
  105. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/github_actions_failure_selection.py +0 -0
  106. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/github_actions_failures.py +0 -0
  107. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/github_actions_permissions.py +0 -0
  108. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/github_api.py +0 -0
  109. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/github_branch.py +0 -0
  110. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/github_config.py +0 -0
  111. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/github_provider.py +0 -0
  112. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/github_repo.py +0 -0
  113. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/groups.py +0 -0
  114. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/models.py +0 -0
  115. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/output.py +0 -0
  116. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/presets.py +0 -0
  117. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/privacy.py +0 -0
  118. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/provider_api_model.py +0 -0
  119. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/provider_api_model_openai.py +0 -0
  120. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/provider_api_model_profiles.py +0 -0
  121. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/provider_env_tokens.py +0 -0
  122. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/provider_local_cli.py +0 -0
  123. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/provider_local_cli_commands.py +0 -0
  124. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/provider_local_cli_probe_config.py +0 -0
  125. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/provider_probe.py +0 -0
  126. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/provider_probe_auth.py +0 -0
  127. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/provider_probe_evaluation.py +0 -0
  128. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/provider_probe_json.py +0 -0
  129. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/provider_probe_remediation.py +0 -0
  130. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/provider_review_hygiene.py +0 -0
  131. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/providers.py +0 -0
  132. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/registry.py +0 -0
  133. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/runner.py +0 -0
  134. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/runtime.py +0 -0
  135. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/doctor_checks/runtime_github_auth.py +0 -0
  136. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/gemini_cli_audit_pr.py +0 -0
  137. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/hermes_cli_audit_pr.py +0 -0
  138. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/init.py +0 -0
  139. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/lane_configs/__init__.py +0 -0
  140. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/lane_configs/aider.py +0 -0
  141. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/lane_configs/antigravity_cli.py +0 -0
  142. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/lane_configs/claude.py +0 -0
  143. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/lane_configs/codex.py +0 -0
  144. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/lane_configs/devin.py +0 -0
  145. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/lane_configs/gemini_cli.py +0 -0
  146. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/lane_configs/hermes_cli.py +0 -0
  147. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/lane_configs/local_llm.py +0 -0
  148. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/local_llm_audit_pr.py +0 -0
  149. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/local_llm_bakeoff.py +0 -0
  150. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/local_llm_calibration.py +0 -0
  151. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/local_llm_profiles.py +0 -0
  152. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/migration.py +0 -0
  153. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/migration_install.py +0 -0
  154. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/migration_mirror.py +0 -0
  155. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/migration_readiness.py +0 -0
  156. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/migration_rehearsal.py +0 -0
  157. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/next_steps.py +0 -0
  158. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/package.py +0 -0
  159. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/package_content.py +0 -0
  160. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/package_paths.py +0 -0
  161. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/package_rendering.py +0 -0
  162. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/package_static.py +0 -0
  163. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/prompts.py +0 -0
  164. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/provider_runners/__init__.py +0 -0
  165. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/provider_runners/comments.py +0 -0
  166. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/provider_runners/git.py +0 -0
  167. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/provider_runners/github_auth.py +0 -0
  168. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/provider_runners/github_pr.py +0 -0
  169. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/provider_runners/pr_worktree.py +0 -0
  170. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/provider_runners/process.py +0 -0
  171. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/provider_runners/repo_paths.py +0 -0
  172. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/provider_runners/text_schema.py +0 -0
  173. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/provider_runners/verdict_artifacts.py +0 -0
  174. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/provider_runners/workspace.py +0 -0
  175. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/providers/__init__.py +0 -0
  176. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/providers/local_cli.py +0 -0
  177. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/providers/provenance.py +0 -0
  178. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/release_readiness.py +0 -0
  179. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/reviewer_metrics.py +0 -0
  180. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/saas_reviewer_labeler.py +0 -0
  181. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/secrets.py +0 -0
  182. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/templates/builder-experiment.example.json +0 -0
  183. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/templates/calibration-corpus.example.json +0 -0
  184. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/templates/calibration-corpus.json +0 -0
  185. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/templates/context-packs.example.json +0 -0
  186. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/templates/lane_prompts/base-audit.md +0 -0
  187. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/templates/lane_prompts/calibration-policy.md +0 -0
  188. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/templates/lane_prompts/context-driven-quality.md +0 -0
  189. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/templates/lane_prompts/docs-design.md +0 -0
  190. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/templates/lane_prompts/generic-programming.md +0 -0
  191. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/templates/lane_prompts/operability.md +0 -0
  192. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/templates/lane_prompts/package-runtime.md +0 -0
  193. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/templates/lane_prompts/security-threat-model.md +0 -0
  194. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/templates/product-support/code_mower +0 -0
  195. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/templates/product-support/code_mower_standalone_pin.env +0 -0
  196. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/templates/product-support/code_mower_standalone_shadow.sh +0 -0
  197. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/templates/product-support/run_claude_audit_pr.sh +0 -0
  198. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/templates/product-support/run_codex_audit_pr.sh +0 -0
  199. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/templates/product-support/safe_gh_comment.py +0 -0
  200. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/templates/reviewer-spend.example.json +0 -0
  201. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/templates/reviewer-value-report.example.md +0 -0
  202. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/templates/workflows/audit-label-cleanup.yml.j2 +0 -0
  203. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/templates/workflows/hosted-bridge.yml.j2 +0 -0
  204. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/templates/workflows/local-cli-audit.yml.j2 +0 -0
  205. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/templates/workflows/private-standalone-shadow.yml.j2 +0 -0
  206. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/templates/workflows/review-clear-stale.yml.j2 +0 -0
  207. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/templates/workflows/saas-reviewer-labeler.yml.j2 +0 -0
  208. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/templates/workflows/trailer-comment-labeler.yml.j2 +0 -0
  209. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/trailer_comment_labeler.py +0 -0
  210. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/versioning.py +0 -0
  211. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower/work_orders.py +0 -0
  212. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower.egg-info/dependency_links.txt +0 -0
  213. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower.egg-info/entry_points.txt +0 -0
  214. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower.egg-info/requires.txt +0 -0
  215. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/src/code_mower.egg-info/top_level.txt +0 -0
  216. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/templates/builder-experiment.example.json +0 -0
  217. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/templates/calibration-corpus.example.json +0 -0
  218. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/templates/calibration-corpus.json +0 -0
  219. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/templates/code-mower.yml.j2 +0 -0
  220. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/templates/context-packs.example.json +0 -0
  221. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/templates/cursor/BUGBOT.md +0 -0
  222. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/templates/providers/acp_bridge.yml +0 -0
  223. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/templates/providers/aider.yml +0 -0
  224. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/templates/providers/antigravity_cli.yml +0 -0
  225. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/templates/providers/claude_audit.yml +0 -0
  226. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/templates/providers/claude_review.yml +0 -0
  227. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/templates/providers/coderabbit_cli.yml +0 -0
  228. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/templates/providers/codex.yml +0 -0
  229. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/templates/providers/cursor_bugbot.yml +0 -0
  230. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/templates/providers/devin.yml +0 -0
  231. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/templates/providers/gemini_cli.yml +0 -0
  232. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/templates/providers/gitar.yml +0 -0
  233. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/templates/providers/greptile.yml +0 -0
  234. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/templates/providers/hermes_cli.yml +0 -0
  235. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/templates/providers/local_llm.yml +0 -0
  236. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/templates/providers/qodo.yml +0 -0
  237. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/templates/reviewer-spend.example.json +0 -0
  238. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/templates/reviewer-value-report.example.md +0 -0
  239. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/templates/workflows/audit-label-cleanup.yml.j2 +0 -0
  240. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/templates/workflows/blind-review-artifacts-dry-run.yml.j2 +0 -0
  241. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/templates/workflows/hosted-bridge.yml.j2 +0 -0
  242. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/templates/workflows/local-cli-audit.yml.j2 +0 -0
  243. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/templates/workflows/private-standalone-shadow.yml.j2 +0 -0
  244. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/templates/workflows/review-clear-stale.yml.j2 +0 -0
  245. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/templates/workflows/saas-reviewer-labeler.yml.j2 +0 -0
  246. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/templates/workflows/trailer-comment-labeler.yml.j2 +0 -0
  247. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/tests/test_calibration_effect_report.py +0 -0
  248. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/tests/test_checks.py +0 -0
  249. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/tests/test_claude_cli_bounce.py +0 -0
  250. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/tests/test_cloud_client.py +0 -0
  251. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/tests/test_cloud_git_metadata.py +0 -0
  252. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/tests/test_cloud_manifest.py +0 -0
  253. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/tests/test_cloud_reports.py +0 -0
  254. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/tests/test_coderabbit_cli_audit_pr.py +0 -0
  255. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/tests/test_doctor_actions_cost_summary.py +0 -0
  256. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/tests/test_doctor_actions_failure_selection.py +0 -0
  257. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/tests/test_doctor_boundaries.py +0 -0
  258. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/tests/test_doctor_github_checks.py +0 -0
  259. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/tests/test_doctor_output.py +0 -0
  260. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/tests/test_doctor_privacy.py +0 -0
  261. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/tests/test_doctor_provider_env_tokens.py +0 -0
  262. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/tests/test_doctor_provider_probe.py +0 -0
  263. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/tests/test_doctor_provider_review_hygiene.py +0 -0
  264. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/tests/test_doctor_registry.py +0 -0
  265. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/tests/test_local_llm_github_helpers.py +0 -0
  266. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/tests/test_provider_runners_comments.py +0 -0
  267. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/tests/test_provider_runners_git.py +0 -0
  268. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/tests/test_provider_runners_github_pr.py +0 -0
  269. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/tests/test_provider_runners_pr_worktree.py +0 -0
  270. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/tests/test_provider_runners_process.py +0 -0
  271. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/tests/test_provider_runners_repo_paths.py +0 -0
  272. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/tests/test_provider_runners_text_schema.py +0 -0
  273. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/tests/test_provider_runners_workspace.py +0 -0
  274. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/tests/test_reviewer_metrics_core.py +0 -0
  275. {code_mower-0.5.0b37 → code_mower-0.5.0b38}/tests/test_work_orders.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-mower
3
- Version: 0.5.0b37
3
+ Version: 0.5.0b38
4
4
  Summary: Multi-reviewer AI code audit orchestration
5
5
  License-Expression: Apache-2.0
6
6
  Requires-Python: >=3.11
@@ -103,11 +103,11 @@ Code Mower currently targets Python 3.11+; Python 3.12 is recommended.
103
103
 
104
104
  ```bash
105
105
  python3.12 --version
106
- pipx install --python python3.12 code-mower==0.5.0b37
106
+ pipx install --python python3.12 code-mower==0.5.0b38
107
107
  code-mower --version
108
108
  ```
109
109
 
110
- `0.5.0b37` is a beta release. Until Code Mower publishes a stable `1.0`
110
+ `0.5.0b38` is a beta release. Until Code Mower publishes a stable `1.0`
111
111
  line, use the explicit beta version above or allow prereleases with:
112
112
 
113
113
  ```bash
@@ -150,7 +150,7 @@ First-time command map: [docs/launch-command-surface.md](docs/launch-command-sur
150
150
 
151
151
  The current PyPI beta has been rehearsed end-to-end from a clean install:
152
152
  [First-User Install Rehearsal](docs/first-user-install-rehearsal.md) records
153
- the latest 10/10 public-package readiness proof for `code-mower==0.5.0b37`.
153
+ the latest 10/10 public-package readiness proof for `code-mower==0.5.0b38`.
154
154
 
155
155
  ## Optional: Plan Before Coding
156
156
 
@@ -291,9 +291,9 @@ best?" to "which AI builder plus reviewer loop ships best on this product?" See
291
291
 
292
292
  ## Installation Status
293
293
 
294
- The current public beta is `v0.5.0-beta.37` from
294
+ The current public beta is `v0.5.0-beta.38` from
295
295
  [codemower-ai/code-mower](https://github.com/codemower-ai/code-mower), published
296
- as `code-mower==0.5.0b37` on [PyPI](https://pypi.org/project/code-mower/).
296
+ as `code-mower==0.5.0b38` on [PyPI](https://pypi.org/project/code-mower/).
297
297
  GitHub releases remain the auditable source for tags, build artifacts, and
298
298
  release notes.
299
299
 
@@ -88,11 +88,11 @@ Code Mower currently targets Python 3.11+; Python 3.12 is recommended.
88
88
 
89
89
  ```bash
90
90
  python3.12 --version
91
- pipx install --python python3.12 code-mower==0.5.0b37
91
+ pipx install --python python3.12 code-mower==0.5.0b38
92
92
  code-mower --version
93
93
  ```
94
94
 
95
- `0.5.0b37` is a beta release. Until Code Mower publishes a stable `1.0`
95
+ `0.5.0b38` is a beta release. Until Code Mower publishes a stable `1.0`
96
96
  line, use the explicit beta version above or allow prereleases with:
97
97
 
98
98
  ```bash
@@ -135,7 +135,7 @@ First-time command map: [docs/launch-command-surface.md](docs/launch-command-sur
135
135
 
136
136
  The current PyPI beta has been rehearsed end-to-end from a clean install:
137
137
  [First-User Install Rehearsal](docs/first-user-install-rehearsal.md) records
138
- the latest 10/10 public-package readiness proof for `code-mower==0.5.0b37`.
138
+ the latest 10/10 public-package readiness proof for `code-mower==0.5.0b38`.
139
139
 
140
140
  ## Optional: Plan Before Coding
141
141
 
@@ -276,9 +276,9 @@ best?" to "which AI builder plus reviewer loop ships best on this product?" See
276
276
 
277
277
  ## Installation Status
278
278
 
279
- The current public beta is `v0.5.0-beta.37` from
279
+ The current public beta is `v0.5.0-beta.38` from
280
280
  [codemower-ai/code-mower](https://github.com/codemower-ai/code-mower), published
281
- as `code-mower==0.5.0b37` on [PyPI](https://pypi.org/project/code-mower/).
281
+ as `code-mower==0.5.0b38` on [PyPI](https://pypi.org/project/code-mower/).
282
282
  GitHub releases remain the auditable source for tags, build artifacts, and
283
283
  release notes.
284
284
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "code-mower"
7
- version = "0.5.0b37"
7
+ version = "0.5.0b38"
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.0b37"
3
+ __version__ = "0.5.0b38"
@@ -9,7 +9,13 @@ DEFAULT_LOCAL_LLM_PROFILES = (
9
9
  "qwen3-coder-next-lmstudio",
10
10
  "gemma4-ollama",
11
11
  )
12
- DEFAULT_CLI_LANES = ("gemini_cli", "antigravity_cli", "hermes_cli", "coderabbit_cli")
12
+ DEFAULT_CLI_LANES = (
13
+ "gemini_cli",
14
+ "antigravity_cli",
15
+ "hermes_cli",
16
+ "coderabbit_cli",
17
+ "grok_build",
18
+ )
13
19
 
14
20
 
15
21
  def default_arms() -> list[dict[str, Any]]:
@@ -137,7 +137,12 @@ def materialize_command(
137
137
  lane_id = command_lane_id(command)
138
138
  repo = str(item.get("repo") or "")
139
139
  repo_path = repo_path_for_item(item, repo_path_map)
140
- historical_local_cli_lanes = {"antigravity-cli", "gemini-cli", "hermes-cli"}
140
+ historical_local_cli_lanes = {
141
+ "antigravity-cli",
142
+ "gemini-cli",
143
+ "grok-build",
144
+ "hermes-cli",
145
+ }
141
146
  if lane_id in {"coderabbit-cli", "local-llm", *historical_local_cli_lanes}:
142
147
  existing_repo_path = option_value(materialized, "--repo-path")
143
148
  if repo_path:
@@ -169,6 +174,8 @@ def summary_path_for_command(command: Sequence[Any]) -> Path | None:
169
174
  return root / "antigravity-cli.summary.json"
170
175
  if lane_id == "gemini-cli":
171
176
  return root / "gemini-cli.summary.json"
177
+ if lane_id == "grok-build":
178
+ return root / "grok-build.summary.json"
172
179
  if lane_id == "hermes-cli":
173
180
  return root / "hermes-cli.summary.json"
174
181
  if lane_id == "coderabbit-cli":
@@ -16,7 +16,12 @@ else: # pragma: no cover - import shape depends on package layout.
16
16
  from .. import code_mower_context_packs
17
17
 
18
18
 
19
- CONTEXT_PACK_CLI_LANES = {"antigravity-cli", "gemini-cli", "hermes-cli"}
19
+ CONTEXT_PACK_CLI_LANES = {
20
+ "antigravity-cli",
21
+ "gemini-cli",
22
+ "grok-build",
23
+ "hermes-cli",
24
+ }
20
25
 
21
26
 
22
27
  def repo_roots_from_path_map(repo_path_map: Mapping[str, str]) -> dict[str, Path]:
@@ -227,7 +227,12 @@ def build_pilot_plan(
227
227
  for lens in reviewer.get("lenses", ["base-audit"])
228
228
  if str(lens).strip()
229
229
  ] or ["base-audit"]
230
- if lane_id in {"antigravity_cli", "gemini_cli", "hermes_cli"}:
230
+ if lane_id in {
231
+ "antigravity_cli",
232
+ "gemini_cli",
233
+ "grok_build",
234
+ "hermes_cli",
235
+ }:
231
236
  output_leaf = _local_cli_output_leaf(
232
237
  lane_slug=lane_slug,
233
238
  lane_id=lane_id,
@@ -165,10 +165,17 @@ def run_records_from_summary(
165
165
  return expected_finding_matches(expected_findings, findings)
166
166
  return 1
167
167
 
168
- if mode in {"antigravity-cli-audit", "gemini-cli-audit", "hermes-cli-audit"}:
168
+ if mode in {
169
+ "antigravity-cli-audit",
170
+ "gemini-cli-audit",
171
+ "grok-build-audit",
172
+ "hermes-cli-audit",
173
+ }:
169
174
  default_reviewer = (
170
175
  "antigravity-cli"
171
176
  if mode == "antigravity-cli-audit"
177
+ else "grok-build"
178
+ if mode == "grok-build-audit"
172
179
  else "hermes-cli"
173
180
  if mode == "hermes-cli-audit"
174
181
  else "gemini-cli"
@@ -14,7 +14,7 @@ from pathlib import Path
14
14
  if __package__ in {None, ""}:
15
15
  raise SystemExit(
16
16
  "code_mower.cli is a packaged entrypoint. Install Code Mower with "
17
- "`pipx install code-mower==0.5.0b37`, or run source checkouts with "
17
+ "`pipx install code-mower==0.5.0b38`, or run source checkouts with "
18
18
  "`PYTHONPATH=src python -m code_mower.cli`."
19
19
  )
20
20
 
@@ -39,6 +39,7 @@ from . import code_mower_telemetry
39
39
  from . import config as code_mower_config
40
40
  from . import doctor as code_mower_doctor
41
41
  from . import gemini_cli_audit_pr
42
+ from . import grok_build_audit_pr
42
43
  from . import hermes_cli_audit_pr
43
44
  from . import init as code_mower_init
44
45
  from . import local_llm_audit_pr
@@ -395,6 +396,7 @@ COMMAND_DESCRIPTIONS: dict[str, str] = {
395
396
  "codex-audit-schema-smoke": "Smoke-test Codex audit schema parsing.",
396
397
  "doctor": "Check runtime, GitHub, providers, privacy, and cloud setup.",
397
398
  "gemini-cli": "Run a Gemini CLI structured audit lane.",
399
+ "grok-build": "Run a Grok Build informational audit lane.",
398
400
  "hermes-cli": "Run a Hermes CLI structured audit lane.",
399
401
  "init": "Render safe easy-mode setup output.",
400
402
  "local-llm": "Probe and run local OpenAI-compatible model lanes.",
@@ -524,6 +526,7 @@ COMMAND_HANDLERS: dict[str, CommandHandler] = {
524
526
  "codex-audit-schema-smoke": codex_audit_schema_smoke.main,
525
527
  "doctor": code_mower_doctor.main,
526
528
  "gemini-cli": gemini_cli_audit_pr.main,
529
+ "grok-build": grok_build_audit_pr.main,
527
530
  "hermes-cli": hermes_cli_audit_pr.main,
528
531
  "init": _init_main,
529
532
  "local-llm": _local_llm_main,
@@ -10,6 +10,7 @@ from __future__ import annotations
10
10
 
11
11
  import argparse
12
12
  import os
13
+ import shutil
13
14
  import subprocess
14
15
  import sys
15
16
  from dataclasses import dataclass
@@ -17,7 +18,7 @@ from pathlib import Path
17
18
  from typing import Callable, Mapping, Optional, Sequence
18
19
 
19
20
 
20
- DEFAULT_CODEX_CLI_PATH = "/Applications/Codex.app/Contents/Resources/codex"
21
+ DEFAULT_CODEX_CLI_PATH = "codex"
21
22
  DEFAULT_GITHUB_API_URL = "https://api.github.com"
22
23
  ENV_HELP = "Run: source tools/codex_audit_env.sh"
23
24
 
@@ -37,10 +38,18 @@ def resolve_required_setting(
37
38
  env: Mapping[str, str],
38
39
  env_name: str,
39
40
  label: str,
41
+ allow_path_lookup: bool = False,
40
42
  ) -> CheckResult:
41
43
  value = cli_value or env.get(env_name)
44
+ if not value and allow_path_lookup:
45
+ value = DEFAULT_CODEX_CLI_PATH
42
46
  if not value:
43
47
  return CheckResult(label, False, f"{env_name} is not set. {ENV_HELP}")
48
+ if allow_path_lookup and os.sep not in value and not (os.altsep and os.altsep in value):
49
+ resolved = shutil.which(value)
50
+ if not resolved:
51
+ return CheckResult(label, False, f"{env_name} command not found on PATH: {value}")
52
+ return CheckResult(label, True, resolved)
44
53
  path = Path(value)
45
54
  if not path.exists():
46
55
  return CheckResult(label, False, f"{env_name} does not exist: {value}")
@@ -164,8 +173,8 @@ def _parse_args(argv: Optional[Sequence[str]] = None) -> argparse.Namespace:
164
173
  )
165
174
  parser.add_argument(
166
175
  "--codex-cli-path",
167
- default=os.environ.get("CODEX_CLI_PATH"),
168
- help="Codex CLI path. Defaults to CODEX_CLI_PATH.",
176
+ default=os.environ.get("CODEX_CLI_PATH", DEFAULT_CODEX_CLI_PATH),
177
+ help="Codex CLI path or command. Defaults to CODEX_CLI_PATH or `codex` on PATH.",
169
178
  )
170
179
  parser.add_argument(
171
180
  "--github-url",
@@ -200,6 +209,7 @@ def main(argv: Optional[Sequence[str]] = None) -> int:
200
209
  env=env,
201
210
  env_name="CODEX_CLI_PATH",
202
211
  label="Codex CLI",
212
+ allow_path_lookup=True,
203
213
  )
204
214
  setup_results = [python_check, codex_check]
205
215
  if not all(result.ok for result in setup_results):
@@ -146,7 +146,7 @@ else: # pragma: no cover - exercised after package extraction.
146
146
 
147
147
  # ----- Configuration / defaults -----
148
148
 
149
- DEFAULT_CODEX_CLI_PATH = "/Applications/Codex.app/Contents/Resources/codex"
149
+ DEFAULT_CODEX_CLI_PATH = "codex"
150
150
  DEFAULT_CODEX_TIMEOUT = 900 # 15 min; Codex review can take 5-10 min on a large diff
151
151
  DEFAULT_BASE_REF = "origin/main"
152
152
  DEFAULT_REPOS = "owner/repo,owner/other-repo"
@@ -37,7 +37,15 @@ else: # pragma: no cover - exercised after package extraction.
37
37
  from .. import secrets as code_mower_secrets
38
38
 
39
39
 
40
- SUPPORTED_TOKEN_FILE_ENV_NAMES = frozenset({"GEMINI_API_KEY", "GOOGLE_API_KEY"})
40
+ SUPPORTED_TOKEN_FILE_ENV_NAMES = frozenset(
41
+ {
42
+ "GEMINI_API_KEY",
43
+ "GOOGLE_API_KEY",
44
+ "GROK_API_KEY",
45
+ "GROK_DEPLOYMENT_KEY",
46
+ "XAI_API_KEY",
47
+ }
48
+ )
41
49
  TRUTHY_ENV_VALUES = frozenset({"1", "true", "yes", "on"})
42
50
  ACTIONS_BILLING_BLOCK_PATTERNS = (
43
51
  "recent account payments have failed",
@@ -122,6 +130,11 @@ def token_remediation(
122
130
  "set GEMINI_API_KEY or GOOGLE_API_KEY, or run "
123
131
  "`code-mower init auth gemini` and export GEMINI_API_KEY_FILE"
124
132
  )
133
+ elif set(names) & {"XAI_API_KEY", "GROK_DEPLOYMENT_KEY", "GROK_API_KEY"}:
134
+ parts.append(
135
+ "run `grok login --device-code` locally, or set XAI_API_KEY "
136
+ "or GROK_DEPLOYMENT_KEY before enabling the Grok Build lane"
137
+ )
125
138
  else:
126
139
  parts.append("set one of " + join_names(names))
127
140
  if not parts:
@@ -75,9 +75,15 @@ def check_required_env(lane_id: str, lane: Mapping[str, Any]) -> list[DoctorChec
75
75
  return []
76
76
  required = list(env_status.required)
77
77
  required_truthy = list(env_status.required_truthy)
78
+ required_any = list(env_status.required_any)
79
+ required_truthy_any = list(env_status.required_truthy_any)
78
80
  missing = list(env_status.missing)
79
81
  missing_truthy = list(env_status.missing_truthy)
80
- if missing or missing_truthy:
82
+ if missing or missing_truthy or env_status.missing_any:
83
+ missing_parts = [*missing, *missing_truthy]
84
+ if env_status.missing_any:
85
+ any_group = [*required_any, *required_truthy_any]
86
+ missing_parts.append("one of: " + ", ".join(any_group))
81
87
  return [
82
88
  DoctorCheck(
83
89
  name="env.required",
@@ -85,13 +91,16 @@ def check_required_env(lane_id: str, lane: Mapping[str, Any]) -> list[DoctorChec
85
91
  lane=lane_id,
86
92
  message=(
87
93
  "missing required env vars: "
88
- + ", ".join([*missing, *missing_truthy])
94
+ + ", ".join(missing_parts)
89
95
  ),
90
96
  detail={
91
97
  "missing": missing,
92
98
  "missing_truthy": missing_truthy,
99
+ "missing_any": env_status.missing_any,
93
100
  "required_env": required,
94
101
  "required_env_truthy": required_truthy,
102
+ "required_env_any": required_any,
103
+ "required_env_truthy_any": required_truthy_any,
95
104
  },
96
105
  remediation=(
97
106
  "Set the required env vars only when you accept the lane's "
@@ -108,6 +117,8 @@ def check_required_env(lane_id: str, lane: Mapping[str, Any]) -> list[DoctorChec
108
117
  detail={
109
118
  "required_env": required,
110
119
  "required_env_truthy": required_truthy,
120
+ "required_env_any": required_any,
121
+ "required_env_truthy_any": required_truthy_any,
111
122
  },
112
123
  )
113
124
  ]
@@ -13,22 +13,30 @@ from .common import TRUTHY_ENV_VALUES, as_sequence
13
13
  class ProviderRequiredEnvStatus:
14
14
  required: tuple[str, ...]
15
15
  required_truthy: tuple[str, ...]
16
+ required_any: tuple[str, ...]
17
+ required_truthy_any: tuple[str, ...]
16
18
  missing: tuple[str, ...]
17
19
  missing_truthy: tuple[str, ...]
20
+ missing_any: bool
18
21
 
19
22
  @property
20
23
  def declares_required_env(self) -> bool:
21
- return bool(self.required or self.required_truthy)
24
+ return bool(
25
+ self.required
26
+ or self.required_truthy
27
+ or self.required_any
28
+ or self.required_truthy_any
29
+ )
22
30
 
23
31
  @property
24
32
  def all_present(self) -> bool:
25
- return not self.missing and not self.missing_truthy
33
+ return not self.missing and not self.missing_truthy and not self.missing_any
26
34
 
27
35
 
28
36
  def provider_required_env_status(lane: Mapping[str, Any]) -> ProviderRequiredEnvStatus:
29
37
  provider_config = lane.get("provider_config", {})
30
38
  if not isinstance(provider_config, Mapping):
31
- return ProviderRequiredEnvStatus((), (), (), ())
39
+ return ProviderRequiredEnvStatus((), (), (), (), (), (), False)
32
40
  required = tuple(
33
41
  str(name)
34
42
  for name in as_sequence(provider_config.get("required_env", []))
@@ -39,17 +47,35 @@ def provider_required_env_status(lane: Mapping[str, Any]) -> ProviderRequiredEnv
39
47
  for name in as_sequence(provider_config.get("required_env_truthy", []))
40
48
  if str(name).strip()
41
49
  )
50
+ required_any = tuple(
51
+ str(name)
52
+ for name in as_sequence(provider_config.get("required_env_any", []))
53
+ if str(name).strip()
54
+ )
55
+ required_truthy_any = tuple(
56
+ str(name)
57
+ for name in as_sequence(provider_config.get("required_env_truthy_any", []))
58
+ if str(name).strip()
59
+ )
42
60
  missing = tuple(name for name in required if not os.environ.get(name))
43
61
  missing_truthy = tuple(
44
62
  name
45
63
  for name in required_truthy
46
64
  if os.environ.get(name, "").strip().lower() not in TRUTHY_ENV_VALUES
47
65
  )
66
+ any_satisfied = any(os.environ.get(name) for name in required_any) or any(
67
+ os.environ.get(name, "").strip().lower() in TRUTHY_ENV_VALUES
68
+ for name in required_truthy_any
69
+ )
70
+ missing_any = bool(required_any or required_truthy_any) and not any_satisfied
48
71
  return ProviderRequiredEnvStatus(
49
72
  required=required,
50
73
  required_truthy=required_truthy,
74
+ required_any=required_any,
75
+ required_truthy_any=required_truthy_any,
51
76
  missing=missing,
52
77
  missing_truthy=missing_truthy,
78
+ missing_any=missing_any,
53
79
  )
54
80
 
55
81