code-mower 0.5.0b39__tar.gz → 0.5.0b40__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.0b39 → code_mower-0.5.0b40}/PKG-INFO +6 -6
  2. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/README.md +5 -5
  3. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/pyproject.toml +1 -1
  4. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/__init__.py +1 -1
  5. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/cli.py +1 -1
  6. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/grok_build_audit_pr.py +30 -0
  7. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/init.py +55 -0
  8. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/templates/code-mower.example.yml +2 -0
  9. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/templates/workflows/saas-reviewer-labeler.yml.j2 +3 -9
  10. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/templates/workflows/trailer-comment-labeler.yml.j2 +2 -8
  11. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower.egg-info/PKG-INFO +6 -6
  12. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/templates/workflows/saas-reviewer-labeler.yml.j2 +3 -9
  13. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/templates/workflows/trailer-comment-labeler.yml.j2 +2 -8
  14. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/tests/test_provider_local_cli.py +49 -0
  15. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/tests/test_release_hygiene.py +69 -37
  16. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/CODE_OF_CONDUCT.md +0 -0
  17. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/LICENSE +0 -0
  18. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/MANIFEST.in +0 -0
  19. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/NOTICE +0 -0
  20. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/SUPPORT.md +0 -0
  21. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/requirements/requirements.txt +0 -0
  22. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/setup.cfg +0 -0
  23. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/adapters/__init__.py +0 -0
  24. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/adapters/_base.py +0 -0
  25. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/adapters/cursor_bugbot.py +0 -0
  26. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/adapters/gitar.py +0 -0
  27. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/adapters/greptile.py +0 -0
  28. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/adapters/qodo.py +0 -0
  29. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/antigravity_cli_audit_pr.py +0 -0
  30. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/audit_handoff_log.py +0 -0
  31. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/audit_labeler_lib.py +0 -0
  32. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/audit_progress.py +0 -0
  33. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/blind_review_artifacts.py +0 -0
  34. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/blind_review_coordinator.py +0 -0
  35. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/bootstrap.py +0 -0
  36. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/builder_experiment.py +0 -0
  37. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/calibration/__init__.py +0 -0
  38. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/calibration/arms.py +0 -0
  39. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/calibration/auto_discovery.py +0 -0
  40. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/calibration/commands.py +0 -0
  41. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/calibration/context_inputs.py +0 -0
  42. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/calibration/corpus.py +0 -0
  43. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/calibration/effect_report.py +0 -0
  44. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/calibration/evidence.py +0 -0
  45. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/calibration/evidence_report.py +0 -0
  46. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/calibration/identity.py +0 -0
  47. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/calibration/metrics.py +0 -0
  48. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/calibration/overlap.py +0 -0
  49. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/calibration/planning.py +0 -0
  50. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/calibration/policy.py +0 -0
  51. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/calibration/results.py +0 -0
  52. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/calibration/run_results.py +0 -0
  53. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/calibration/run_status.py +0 -0
  54. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/calibration/runner.py +0 -0
  55. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/calibration/truth.py +0 -0
  56. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/calibration/value_report.py +0 -0
  57. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/checks.py +0 -0
  58. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/claude_audit_pr.py +0 -0
  59. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/claude_cli_bounce.py +0 -0
  60. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/claude_cli_environment.py +0 -0
  61. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/clear_stale.py +0 -0
  62. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/cloud.py +0 -0
  63. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/cloud_client/__init__.py +0 -0
  64. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/cloud_client/bundle.py +0 -0
  65. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/cloud_client/doctor.py +0 -0
  66. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/cloud_client/dogfood.py +0 -0
  67. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/cloud_client/endpoints.py +0 -0
  68. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/cloud_client/errors.py +0 -0
  69. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/cloud_client/events.py +0 -0
  70. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/cloud_client/export.py +0 -0
  71. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/cloud_client/git_metadata.py +0 -0
  72. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/cloud_client/manifest.py +0 -0
  73. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/cloud_client/operations.py +0 -0
  74. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/cloud_client/reports.py +0 -0
  75. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/cloud_client/setup.py +0 -0
  76. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/cloud_client/upload.py +0 -0
  77. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/code_mower_calibration.py +0 -0
  78. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/code_mower_context_packs.py +0 -0
  79. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/code_mower_merge.py +0 -0
  80. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/code_mower_telemetry.py +0 -0
  81. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/coderabbit_cli_audit_pr.py +0 -0
  82. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/codex_audit_env_preflight.py +0 -0
  83. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/codex_audit_pr.py +0 -0
  84. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/codex_audit_schema_smoke.py +0 -0
  85. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/codex_audit_verdict.schema.json +0 -0
  86. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/config.py +0 -0
  87. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor.py +0 -0
  88. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/__init__.py +0 -0
  89. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/cloud.py +0 -0
  90. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/common.py +0 -0
  91. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/github.py +0 -0
  92. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/github_actions.py +0 -0
  93. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/github_actions_cost.py +0 -0
  94. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/github_actions_cost_summary.py +0 -0
  95. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/github_actions_failure_annotations.py +0 -0
  96. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/github_actions_failure_models.py +0 -0
  97. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/github_actions_failure_scan.py +0 -0
  98. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/github_actions_failure_selection.py +0 -0
  99. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/github_actions_failures.py +0 -0
  100. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/github_actions_permissions.py +0 -0
  101. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/github_api.py +0 -0
  102. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/github_branch.py +0 -0
  103. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/github_config.py +0 -0
  104. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/github_provider.py +0 -0
  105. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/github_repo.py +0 -0
  106. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/groups.py +0 -0
  107. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/models.py +0 -0
  108. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/output.py +0 -0
  109. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/presets.py +0 -0
  110. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/privacy.py +0 -0
  111. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/provider_api_model.py +0 -0
  112. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/provider_api_model_openai.py +0 -0
  113. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/provider_api_model_profiles.py +0 -0
  114. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/provider_env.py +0 -0
  115. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/provider_env_required.py +0 -0
  116. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/provider_env_tokens.py +0 -0
  117. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/provider_local_cli.py +0 -0
  118. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/provider_local_cli_commands.py +0 -0
  119. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/provider_local_cli_probe_config.py +0 -0
  120. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/provider_probe.py +0 -0
  121. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/provider_probe_auth.py +0 -0
  122. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/provider_probe_evaluation.py +0 -0
  123. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/provider_probe_json.py +0 -0
  124. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/provider_probe_remediation.py +0 -0
  125. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/provider_review_hygiene.py +0 -0
  126. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/providers.py +0 -0
  127. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/registry.py +0 -0
  128. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/runner.py +0 -0
  129. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/runtime.py +0 -0
  130. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/doctor_checks/runtime_github_auth.py +0 -0
  131. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/gemini_cli_audit_pr.py +0 -0
  132. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/hermes_cli_audit_pr.py +0 -0
  133. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/lane_configs/__init__.py +0 -0
  134. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/lane_configs/aider.py +0 -0
  135. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/lane_configs/antigravity_cli.py +0 -0
  136. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/lane_configs/claude.py +0 -0
  137. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/lane_configs/codex.py +0 -0
  138. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/lane_configs/devin.py +0 -0
  139. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/lane_configs/gemini_cli.py +0 -0
  140. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/lane_configs/grok_build.py +0 -0
  141. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/lane_configs/hermes_cli.py +0 -0
  142. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/lane_configs/local_llm.py +0 -0
  143. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/local_llm_audit_pr.py +0 -0
  144. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/local_llm_bakeoff.py +0 -0
  145. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/local_llm_calibration.py +0 -0
  146. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/local_llm_profiles.py +0 -0
  147. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/migration.py +0 -0
  148. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/migration_install.py +0 -0
  149. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/migration_mirror.py +0 -0
  150. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/migration_readiness.py +0 -0
  151. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/migration_rehearsal.py +0 -0
  152. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/next_steps.py +0 -0
  153. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/package.py +0 -0
  154. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/package_content.py +0 -0
  155. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/package_manifest.py +0 -0
  156. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/package_paths.py +0 -0
  157. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/package_rendering.py +0 -0
  158. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/package_static.py +0 -0
  159. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/prompts.py +0 -0
  160. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/provider_registry.py +0 -0
  161. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/provider_runners/__init__.py +0 -0
  162. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/provider_runners/comments.py +0 -0
  163. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/provider_runners/git.py +0 -0
  164. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/provider_runners/github_auth.py +0 -0
  165. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/provider_runners/github_pr.py +0 -0
  166. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/provider_runners/pr_worktree.py +0 -0
  167. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/provider_runners/process.py +0 -0
  168. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/provider_runners/repo_paths.py +0 -0
  169. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/provider_runners/text_schema.py +0 -0
  170. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/provider_runners/verdict_artifacts.py +0 -0
  171. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/provider_runners/workspace.py +0 -0
  172. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/providers/__init__.py +0 -0
  173. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/providers/local_cli.py +0 -0
  174. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/providers/provenance.py +0 -0
  175. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/release_readiness.py +0 -0
  176. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/reviewer_metrics.py +0 -0
  177. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/saas_reviewer_labeler.py +0 -0
  178. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/secrets.py +0 -0
  179. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/templates/builder-experiment.example.json +0 -0
  180. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/templates/calibration-corpus.example.json +0 -0
  181. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/templates/calibration-corpus.json +0 -0
  182. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/templates/context-packs.example.json +0 -0
  183. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/templates/lane_prompts/base-audit.md +0 -0
  184. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/templates/lane_prompts/calibration-policy.md +0 -0
  185. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/templates/lane_prompts/context-driven-quality.md +0 -0
  186. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/templates/lane_prompts/docs-design.md +0 -0
  187. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/templates/lane_prompts/generic-programming.md +0 -0
  188. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/templates/lane_prompts/operability.md +0 -0
  189. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/templates/lane_prompts/package-runtime.md +0 -0
  190. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/templates/lane_prompts/security-threat-model.md +0 -0
  191. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/templates/product-support/code_mower +0 -0
  192. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/templates/product-support/code_mower_standalone_pin.env +0 -0
  193. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/templates/product-support/code_mower_standalone_shadow.sh +0 -0
  194. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/templates/product-support/run_claude_audit_pr.sh +0 -0
  195. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/templates/product-support/run_codex_audit_pr.sh +0 -0
  196. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/templates/product-support/safe_gh_comment.py +0 -0
  197. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/templates/providers.yml +0 -0
  198. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/templates/reviewer-spend.example.json +0 -0
  199. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/templates/reviewer-value-report.example.md +0 -0
  200. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/templates/workflows/audit-label-cleanup.yml.j2 +0 -0
  201. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/templates/workflows/hosted-bridge.yml.j2 +0 -0
  202. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/templates/workflows/local-cli-audit.yml.j2 +0 -0
  203. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/templates/workflows/private-standalone-shadow.yml.j2 +0 -0
  204. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/templates/workflows/review-clear-stale.yml.j2 +0 -0
  205. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/trailer_comment_labeler.py +0 -0
  206. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/versioning.py +0 -0
  207. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower/work_orders.py +0 -0
  208. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower.egg-info/SOURCES.txt +0 -0
  209. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower.egg-info/dependency_links.txt +0 -0
  210. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower.egg-info/entry_points.txt +0 -0
  211. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower.egg-info/requires.txt +0 -0
  212. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/src/code_mower.egg-info/top_level.txt +0 -0
  213. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/templates/builder-experiment.example.json +0 -0
  214. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/templates/calibration-corpus.example.json +0 -0
  215. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/templates/calibration-corpus.json +0 -0
  216. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/templates/code-mower.yml.j2 +0 -0
  217. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/templates/context-packs.example.json +0 -0
  218. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/templates/cursor/BUGBOT.md +0 -0
  219. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/templates/providers/acp_bridge.yml +0 -0
  220. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/templates/providers/aider.yml +0 -0
  221. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/templates/providers/antigravity_cli.yml +0 -0
  222. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/templates/providers/claude_audit.yml +0 -0
  223. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/templates/providers/claude_review.yml +0 -0
  224. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/templates/providers/coderabbit_cli.yml +0 -0
  225. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/templates/providers/codex.yml +0 -0
  226. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/templates/providers/cursor_bugbot.yml +0 -0
  227. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/templates/providers/devin.yml +0 -0
  228. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/templates/providers/gemini_cli.yml +0 -0
  229. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/templates/providers/gitar.yml +0 -0
  230. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/templates/providers/greptile.yml +0 -0
  231. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/templates/providers/hermes_cli.yml +0 -0
  232. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/templates/providers/local_llm.yml +0 -0
  233. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/templates/providers/qodo.yml +0 -0
  234. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/templates/providers.yml +0 -0
  235. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/templates/reviewer-spend.example.json +0 -0
  236. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/templates/reviewer-value-report.example.md +0 -0
  237. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/templates/workflows/audit-label-cleanup.yml.j2 +0 -0
  238. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/templates/workflows/blind-review-artifacts-dry-run.yml.j2 +0 -0
  239. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/templates/workflows/hosted-bridge.yml.j2 +0 -0
  240. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/templates/workflows/local-cli-audit.yml.j2 +0 -0
  241. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/templates/workflows/private-standalone-shadow.yml.j2 +0 -0
  242. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/templates/workflows/review-clear-stale.yml.j2 +0 -0
  243. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/tests/test_calibration_effect_report.py +0 -0
  244. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/tests/test_calibration_truth.py +0 -0
  245. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/tests/test_checks.py +0 -0
  246. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/tests/test_claude_cli_bounce.py +0 -0
  247. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/tests/test_clear_stale.py +0 -0
  248. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/tests/test_cloud_client.py +0 -0
  249. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/tests/test_cloud_git_metadata.py +0 -0
  250. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/tests/test_cloud_manifest.py +0 -0
  251. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/tests/test_cloud_reports.py +0 -0
  252. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/tests/test_coderabbit_cli_audit_pr.py +0 -0
  253. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/tests/test_codex_audit_env_preflight.py +0 -0
  254. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/tests/test_doctor_actions_cost_summary.py +0 -0
  255. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/tests/test_doctor_actions_failure_selection.py +0 -0
  256. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/tests/test_doctor_boundaries.py +0 -0
  257. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/tests/test_doctor_github_checks.py +0 -0
  258. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/tests/test_doctor_output.py +0 -0
  259. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/tests/test_doctor_privacy.py +0 -0
  260. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/tests/test_doctor_provider_env_required.py +0 -0
  261. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/tests/test_doctor_provider_env_tokens.py +0 -0
  262. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/tests/test_doctor_provider_probe.py +0 -0
  263. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/tests/test_doctor_provider_review_hygiene.py +0 -0
  264. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/tests/test_doctor_registry.py +0 -0
  265. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/tests/test_local_llm_github_helpers.py +0 -0
  266. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/tests/test_provider_runners_comments.py +0 -0
  267. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/tests/test_provider_runners_git.py +0 -0
  268. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/tests/test_provider_runners_github_pr.py +0 -0
  269. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/tests/test_provider_runners_pr_worktree.py +0 -0
  270. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/tests/test_provider_runners_process.py +0 -0
  271. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/tests/test_provider_runners_repo_paths.py +0 -0
  272. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/tests/test_provider_runners_text_schema.py +0 -0
  273. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/tests/test_provider_runners_workspace.py +0 -0
  274. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/tests/test_reviewer_metrics_core.py +0 -0
  275. {code_mower-0.5.0b39 → code_mower-0.5.0b40}/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.0b39
3
+ Version: 0.5.0b40
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.0b39
106
+ pipx install --python python3.12 code-mower==0.5.0b40
107
107
  code-mower --version
108
108
  ```
109
109
 
110
- `0.5.0b39` is a beta release. Until Code Mower publishes a stable `1.0`
110
+ `0.5.0b40` 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.0b39`.
153
+ the latest 10/10 public-package readiness proof for `code-mower==0.5.0b40`.
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.39` from
294
+ The current public beta is `v0.5.0-beta.40` from
295
295
  [codemower-ai/code-mower](https://github.com/codemower-ai/code-mower), published
296
- as `code-mower==0.5.0b39` on [PyPI](https://pypi.org/project/code-mower/).
296
+ as `code-mower==0.5.0b40` 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.0b39
91
+ pipx install --python python3.12 code-mower==0.5.0b40
92
92
  code-mower --version
93
93
  ```
94
94
 
95
- `0.5.0b39` is a beta release. Until Code Mower publishes a stable `1.0`
95
+ `0.5.0b40` 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.0b39`.
138
+ the latest 10/10 public-package readiness proof for `code-mower==0.5.0b40`.
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.39` from
279
+ The current public beta is `v0.5.0-beta.40` from
280
280
  [codemower-ai/code-mower](https://github.com/codemower-ai/code-mower), published
281
- as `code-mower==0.5.0b39` on [PyPI](https://pypi.org/project/code-mower/).
281
+ as `code-mower==0.5.0b40` 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.0b39"
7
+ version = "0.5.0b40"
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.0b39"
3
+ __version__ = "0.5.0b40"
@@ -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.0b39`, or run source checkouts with "
17
+ "`pipx install code-mower==0.5.0b40`, or run source checkouts with "
18
18
  "`PYTHONPATH=src python -m code_mower.cli`."
19
19
  )
20
20
 
@@ -148,9 +148,34 @@ def _response_text_from_grok_payload(
148
148
  parsed_response = raw_payload
149
149
  if parsed_response is None:
150
150
  parsed_response = gemini_cli_audit_pr.parse_response_json(response_text)
151
+ if parsed_response is None:
152
+ parsed_response = _last_verdict_json_object(response_text)
151
153
  return response_text, parsed_response
152
154
 
153
155
 
156
+ def _last_verdict_json_object(text: str) -> Mapping[str, Any] | None:
157
+ """Recover the final verdict object from chatty multi-turn Grok output."""
158
+
159
+ decoder = json.JSONDecoder()
160
+ candidates: list[Mapping[str, Any]] = []
161
+ index = 0
162
+ while index < len(text):
163
+ if text[index] != "{":
164
+ index += 1
165
+ continue
166
+ try:
167
+ payload, end = decoder.raw_decode(text[index:])
168
+ except json.JSONDecodeError:
169
+ index += 1
170
+ continue
171
+ if isinstance(payload, Mapping) and "verdict" in payload and (
172
+ "findings" in payload or "summary" in payload
173
+ ):
174
+ candidates.append(payload)
175
+ index += max(end, 1)
176
+ return candidates[-1] if candidates else None
177
+
178
+
154
179
  def run_grok_build_audit(
155
180
  *,
156
181
  repo: str,
@@ -294,6 +319,11 @@ def run_grok_build_audit(
294
319
  completed.stdout,
295
320
  )
296
321
  verdict = gemini_cli_audit_pr._validate_verdict(parsed_response)
322
+ if verdict.get("parse_failed"):
323
+ verdict = {
324
+ **verdict,
325
+ "summary": "Grok Build response did not contain parseable verdict JSON.",
326
+ }
297
327
  if repo_path is None:
298
328
  head_after_meta = gemini_cli_audit_pr.fetch_pull_request(
299
329
  repo,
@@ -192,7 +192,24 @@ def _audit_token_env(lane: Mapping[str, Any]) -> str:
192
192
  return "CODE_MOWER_AUDIT_LABEL_TOKEN"
193
193
 
194
194
 
195
+ def _token_env_names(lane: Mapping[str, Any]) -> tuple[str, ...]:
196
+ token_env = lane.get("token_env", [])
197
+ if isinstance(token_env, str):
198
+ return (token_env,)
199
+ if isinstance(token_env, list):
200
+ return tuple(str(name) for name in token_env)
201
+ return ()
202
+
203
+
204
+ def _bot_author_csv(authors: str, lane: Mapping[str, Any]) -> str:
205
+ values = [author.strip() for author in authors.split(",") if author.strip()]
206
+ return ",".join(dict.fromkeys(values))
207
+
208
+
195
209
  def _authors_env_for_trailer_lane(trailer_lane: str) -> str:
210
+ lane_config = _load_trailer_lane_config(trailer_lane)
211
+ if lane_config is not None:
212
+ return lane_config.authors_env_var
196
213
  normalized = trailer_lane.replace("-", "_").upper()
197
214
  explicit = {
198
215
  "CLAUDE": "CLAUDE_AUDIT_BOT_AUTHORS",
@@ -202,6 +219,36 @@ def _authors_env_for_trailer_lane(trailer_lane: str) -> str:
202
219
  return explicit.get(normalized, f"{normalized}_BOT_AUTHORS")
203
220
 
204
221
 
222
+ def _load_trailer_lane_config(trailer_lane: str) -> Any | None:
223
+ try:
224
+ if __package__ in {None, "", "tools"}:
225
+ from tools.lane_configs import load_lane_config
226
+ else: # pragma: no cover - package import path covered by CLI tests.
227
+ from .lane_configs import load_lane_config
228
+
229
+ return load_lane_config(trailer_lane)
230
+ except (ImportError, ModuleNotFoundError, ValueError):
231
+ return None
232
+
233
+
234
+ def _default_trailer_bot_authors(trailer_lane: str) -> str:
235
+ lane_config = _load_trailer_lane_config(trailer_lane)
236
+ if lane_config is not None:
237
+ return ",".join(lane_config.default_authors)
238
+ stem = trailer_lane.replace("_", "-")
239
+ return f"{stem}-audit-bot,{stem}-audit-bot[bot]"
240
+
241
+
242
+ def _configured_bot_authors(lane: Mapping[str, Any]) -> str:
243
+ provider_config = lane.get("provider_config")
244
+ if not isinstance(provider_config, Mapping):
245
+ return ""
246
+ authors = provider_config.get("bot_authors", [])
247
+ if not isinstance(authors, list):
248
+ return ""
249
+ return ",".join(str(author).strip() for author in authors if str(author).strip())
250
+
251
+
205
252
  def _trailer_prefix_for_lane(trailer_lane: str) -> str:
206
253
  return f"{trailer_lane.replace('-', '_').upper()}_AUDIT_STATE"
207
254
 
@@ -240,6 +287,7 @@ def _workflow_entry_for_target(
240
287
  "package_copy_from": "templates/workflows/saas-reviewer-labeler.yml.j2",
241
288
  "adapter": adapter,
242
289
  "authors_env": f"{adapter.replace('-', '_').upper()}_BOT_AUTHORS",
290
+ "bot_authors": _bot_author_csv(_configured_bot_authors(lane), lane),
243
291
  }
244
292
  return {
245
293
  **common,
@@ -249,6 +297,7 @@ def _workflow_entry_for_target(
249
297
  "trailer_lane": trailer_lane,
250
298
  "trailer_prefix": _trailer_prefix_for_lane(trailer_lane),
251
299
  "authors_env": _authors_env_for_trailer_lane(trailer_lane),
300
+ "bot_authors": _bot_author_csv(_default_trailer_bot_authors(trailer_lane), lane),
252
301
  }
253
302
 
254
303
 
@@ -335,6 +384,11 @@ def _lane_warnings(
335
384
  warnings.append(f"{lane_id}: opt-in lane selected by profile")
336
385
  if lane.get("trigger_policy") == "manual":
337
386
  warnings.append(f"{lane_id}: manual trigger policy; installer must not auto-dispatch")
387
+ if "GITHUB_TOKEN" in _token_env_names(lane):
388
+ warnings.append(
389
+ f"{lane_id}: GITHUB_TOKEN posting comments as github-actions[bot] requires "
390
+ "an explicit *_BOT_AUTHORS repository variable"
391
+ )
338
392
  if package_mode:
339
393
  driver = lane.get("driver")
340
394
  if driver in {"local_cli", "hosted_bridge", "api_model"}:
@@ -566,6 +620,7 @@ def _render_workflow_template(text: str, entry: Mapping[str, Any]) -> str:
566
620
  "__ADAPTER__": str(entry.get("adapter") or ""),
567
621
  "__AUTHORS_ENV__": str(entry.get("authors_env") or ""),
568
622
  "__BLOCKED_LABEL__": str(entry.get("blocked_label") or ""),
623
+ "__BOT_AUTHORS__": str(entry.get("bot_authors") or ""),
569
624
  "__DISPLAY_NAME__": str(entry.get("display_name") or ""),
570
625
  "__DONE_LABEL__": str(entry.get("done_label") or ""),
571
626
  "__LABEL_TOKEN_ENV__": str(entry.get("label_token_env") or ""),
@@ -112,6 +112,8 @@ lanes:
112
112
  - GREPTILE_AUDIT_LABEL_TOKEN
113
113
  - GITHUB_TOKEN
114
114
  provider_config:
115
+ # Required by generated issue-comment labeler prefilters. Keep SaaS
116
+ # reviewer bot authors explicit so unrelated bots cannot spoof labels.
115
117
  bot_authors:
116
118
  - greptile-apps[bot]
117
119
  - greptile-apps
@@ -10,12 +10,6 @@ on:
10
10
  types: [submitted, edited]
11
11
  check_run:
12
12
  types: [completed]
13
- workflow_dispatch:
14
- inputs:
15
- adapter:
16
- description: "SaaS reviewer adapter to classify"
17
- required: false
18
- default: "__ADAPTER__"
19
13
 
20
14
  permissions:
21
15
  contents: read
@@ -29,10 +23,10 @@ env:
29
23
  jobs:
30
24
  label:
31
25
  if: >-
32
- github.event_name == 'workflow_dispatch' ||
33
26
  (
34
27
  github.event_name == 'issue_comment' &&
35
- github.event.issue.pull_request
28
+ github.event.issue.pull_request &&
29
+ contains(format(',__BOT_AUTHORS__,{0},', vars.__AUTHORS_ENV__), format(',{0},', github.event.comment.user.login))
36
30
  ) ||
37
31
  (
38
32
  github.event_name == 'issues' &&
@@ -54,5 +48,5 @@ jobs:
54
48
  GITHUB_TOKEN: {% raw %}${{ github.token }}{% endraw %}
55
49
  __LABEL_TOKEN_ENV__: {% raw %}${{ secrets.__LABEL_TOKEN_ENV__ }}{% endraw %}
56
50
  __AUTHORS_ENV__: {% raw %}${{ vars.__AUTHORS_ENV__ }}{% endraw %}
57
- REVIEWER_ADAPTER: {% raw %}${{ github.event.inputs.adapter || '__ADAPTER__' }}{% endraw %}
51
+ REVIEWER_ADAPTER: __ADAPTER__
58
52
  run: tools/code_mower saas-reviewer-labeler --adapter "${REVIEWER_ADAPTER}"
@@ -4,12 +4,6 @@ name: __WORKFLOW_NAME__
4
4
  on:
5
5
  issue_comment:
6
6
  types: [created]
7
- workflow_dispatch:
8
- inputs:
9
- lane:
10
- description: "Trailer-comment lane to classify"
11
- required: false
12
- default: "__TRAILER_LANE__"
13
7
 
14
8
  permissions:
15
9
  contents: read
@@ -22,10 +16,10 @@ env:
22
16
  jobs:
23
17
  label:
24
18
  if: >-
25
- github.event_name == 'workflow_dispatch' ||
26
19
  (
27
20
  github.event_name == 'issue_comment' &&
28
21
  github.event.issue.pull_request &&
22
+ contains(format(',__BOT_AUTHORS__,{0},', vars.__AUTHORS_ENV__), format(',{0},', github.event.comment.user.login)) &&
29
23
  (
30
24
  contains(github.event.comment.body, '__TRAILER_PREFIX__') ||
31
25
  contains(github.event.comment.body, '__DISPLAY_NAME__ Audit') ||
@@ -53,5 +47,5 @@ jobs:
53
47
  GITHUB_TOKEN: {% raw %}${{ github.token }}{% endraw %}
54
48
  __LABEL_TOKEN_ENV__: {% raw %}${{ secrets.__LABEL_TOKEN_ENV__ }}{% endraw %}
55
49
  __AUTHORS_ENV__: {% raw %}${{ vars.__AUTHORS_ENV__ }}{% endraw %}
56
- TRAILER_LANE: {% raw %}${{ github.event.inputs.lane || '__TRAILER_LANE__' }}{% endraw %}
50
+ TRAILER_LANE: __TRAILER_LANE__
57
51
  run: tools/code_mower trailer-comment-labeler --lane "${TRAILER_LANE}"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-mower
3
- Version: 0.5.0b39
3
+ Version: 0.5.0b40
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.0b39
106
+ pipx install --python python3.12 code-mower==0.5.0b40
107
107
  code-mower --version
108
108
  ```
109
109
 
110
- `0.5.0b39` is a beta release. Until Code Mower publishes a stable `1.0`
110
+ `0.5.0b40` 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.0b39`.
153
+ the latest 10/10 public-package readiness proof for `code-mower==0.5.0b40`.
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.39` from
294
+ The current public beta is `v0.5.0-beta.40` from
295
295
  [codemower-ai/code-mower](https://github.com/codemower-ai/code-mower), published
296
- as `code-mower==0.5.0b39` on [PyPI](https://pypi.org/project/code-mower/).
296
+ as `code-mower==0.5.0b40` 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
 
@@ -10,12 +10,6 @@ on:
10
10
  types: [submitted, edited]
11
11
  check_run:
12
12
  types: [completed]
13
- workflow_dispatch:
14
- inputs:
15
- adapter:
16
- description: "SaaS reviewer adapter to classify"
17
- required: false
18
- default: "__ADAPTER__"
19
13
 
20
14
  permissions:
21
15
  contents: read
@@ -29,10 +23,10 @@ env:
29
23
  jobs:
30
24
  label:
31
25
  if: >-
32
- github.event_name == 'workflow_dispatch' ||
33
26
  (
34
27
  github.event_name == 'issue_comment' &&
35
- github.event.issue.pull_request
28
+ github.event.issue.pull_request &&
29
+ contains(format(',__BOT_AUTHORS__,{0},', vars.__AUTHORS_ENV__), format(',{0},', github.event.comment.user.login))
36
30
  ) ||
37
31
  (
38
32
  github.event_name == 'issues' &&
@@ -54,5 +48,5 @@ jobs:
54
48
  GITHUB_TOKEN: {% raw %}${{ github.token }}{% endraw %}
55
49
  __LABEL_TOKEN_ENV__: {% raw %}${{ secrets.__LABEL_TOKEN_ENV__ }}{% endraw %}
56
50
  __AUTHORS_ENV__: {% raw %}${{ vars.__AUTHORS_ENV__ }}{% endraw %}
57
- REVIEWER_ADAPTER: {% raw %}${{ github.event.inputs.adapter || '__ADAPTER__' }}{% endraw %}
51
+ REVIEWER_ADAPTER: __ADAPTER__
58
52
  run: tools/code_mower saas-reviewer-labeler --adapter "${REVIEWER_ADAPTER}"
@@ -4,12 +4,6 @@ name: __WORKFLOW_NAME__
4
4
  on:
5
5
  issue_comment:
6
6
  types: [created]
7
- workflow_dispatch:
8
- inputs:
9
- lane:
10
- description: "Trailer-comment lane to classify"
11
- required: false
12
- default: "__TRAILER_LANE__"
13
7
 
14
8
  permissions:
15
9
  contents: read
@@ -22,10 +16,10 @@ env:
22
16
  jobs:
23
17
  label:
24
18
  if: >-
25
- github.event_name == 'workflow_dispatch' ||
26
19
  (
27
20
  github.event_name == 'issue_comment' &&
28
21
  github.event.issue.pull_request &&
22
+ contains(format(',__BOT_AUTHORS__,{0},', vars.__AUTHORS_ENV__), format(',{0},', github.event.comment.user.login)) &&
29
23
  (
30
24
  contains(github.event.comment.body, '__TRAILER_PREFIX__') ||
31
25
  contains(github.event.comment.body, '__DISPLAY_NAME__ Audit') ||
@@ -53,5 +47,5 @@ jobs:
53
47
  GITHUB_TOKEN: {% raw %}${{ github.token }}{% endraw %}
54
48
  __LABEL_TOKEN_ENV__: {% raw %}${{ secrets.__LABEL_TOKEN_ENV__ }}{% endraw %}
55
49
  __AUTHORS_ENV__: {% raw %}${{ vars.__AUTHORS_ENV__ }}{% endraw %}
56
- TRAILER_LANE: {% raw %}${{ github.event.inputs.lane || '__TRAILER_LANE__' }}{% endraw %}
50
+ TRAILER_LANE: __TRAILER_LANE__
57
51
  run: tools/code_mower trailer-comment-labeler --lane "${TRAILER_LANE}"
@@ -477,6 +477,55 @@ def test_grok_build_runner_uses_configurable_audit_turn_budget(
477
477
  assert calls[1][calls[1].index("--max-turns") + 1] == "8"
478
478
 
479
479
 
480
+ def test_grok_build_parser_prefers_last_verdict_json() -> None:
481
+ response_text = """
482
+ I found a possible issue first.
483
+ {
484
+ "verdict": "blocked",
485
+ "summary": "Intermediate thought.",
486
+ "findings": [{"severity": "P1", "title": "old", "file": "a", "line": 1, "detail": "old"}]
487
+ }
488
+
489
+ After reading the rest of the diff:
490
+ {
491
+ "verdict": "pass",
492
+ "summary": "Final answer.",
493
+ "findings": []
494
+ }
495
+ """
496
+
497
+ _, parsed = grok_build_audit_pr._response_text_from_grok_payload(
498
+ {"text": response_text},
499
+ "",
500
+ )
501
+
502
+ assert parsed is not None
503
+ assert parsed["verdict"] == "pass"
504
+ assert parsed["findings"] == []
505
+
506
+
507
+ def test_grok_build_parser_ignores_nested_verdict_json() -> None:
508
+ response_text = """
509
+ {
510
+ "verdict": "pass",
511
+ "summary": {
512
+ "verdict": "blocked",
513
+ "summary": "Nested diagnostic text should not win."
514
+ },
515
+ "findings": []
516
+ }
517
+ """
518
+
519
+ _, parsed = grok_build_audit_pr._response_text_from_grok_payload(
520
+ {"text": response_text},
521
+ "",
522
+ )
523
+
524
+ assert parsed is not None
525
+ assert parsed["verdict"] == "pass"
526
+ assert parsed["findings"] == []
527
+
528
+
480
529
  def test_provider_lane_tool_provenance_marks_hosted_model_as_vendor_hidden() -> None:
481
530
  lane = {
482
531
  "driver": "saas_event",