code-mower 1.0.12__tar.gz → 1.0.14__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.
- {code_mower-1.0.12 → code_mower-1.0.14}/PKG-INFO +19 -5
- {code_mower-1.0.12 → code_mower-1.0.14}/README.md +18 -4
- {code_mower-1.0.12 → code_mower-1.0.14}/pyproject.toml +1 -1
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/__init__.py +1 -1
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/devin_api.py +9 -7
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/release_campaigns.py +48 -25
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/workflows/builder-provenance.yml.j2 +1 -1
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower.egg-info/PKG-INFO +19 -5
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/workflows/builder-provenance.yml.j2 +1 -1
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_devin_api.py +55 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_release_campaigns.py +72 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_release_hygiene.py +48 -46
- {code_mower-1.0.12 → code_mower-1.0.14}/CODE_OF_CONDUCT.md +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/LICENSE +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/MANIFEST.in +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/NOTICE +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/SUPPORT.md +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/requirements/requirements.txt +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/setup.cfg +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/adapters/__init__.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/adapters/_base.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/adapters/cursor_bugbot.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/adapters/gitar.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/adapters/greptile.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/adapters/qodo.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/antigravity_cli_audit_pr.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/antigravity_sdk_probe.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/audit_handoff_log.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/audit_labeler_lib.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/audit_limits.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/audit_progress.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/blind_review_artifacts.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/blind_review_coordinator.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/board.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/board_store.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/bootstrap.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/builder_experiment.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/builder_runs.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/calibration/__init__.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/calibration/arms.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/calibration/auto_discovery.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/calibration/commands.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/calibration/context_inputs.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/calibration/corpus.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/calibration/effect_report.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/calibration/evidence.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/calibration/evidence_report.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/calibration/identity.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/calibration/metrics.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/calibration/overlap.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/calibration/planning.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/calibration/policy.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/calibration/results.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/calibration/run_results.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/calibration/run_status.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/calibration/runner.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/calibration/truth.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/calibration/value_report.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/campaign_adapters.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/campaign_discovery.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/checks.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/claude_audit_pr.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/claude_cli_bounce.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/claude_cli_environment.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/clear_stale.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/cli.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/cloud.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/cloud_client/__init__.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/cloud_client/adoption_runs.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/cloud_client/bundle.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/cloud_client/doctor.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/cloud_client/dogfood.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/cloud_client/endpoints.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/cloud_client/errors.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/cloud_client/events.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/cloud_client/export.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/cloud_client/git_metadata.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/cloud_client/manifest.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/cloud_client/operations.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/cloud_client/pr_outcomes.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/cloud_client/productivity.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/cloud_client/reports.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/cloud_client/setup.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/cloud_client/tokens.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/cloud_client/upload.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/cloud_client/work_types.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/code_mower_calibration.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/code_mower_context_packs.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/code_mower_merge.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/code_mower_telemetry.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/coderabbit_cli_audit_pr.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/codex_audit_env_preflight.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/codex_audit_pr.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/codex_audit_schema_smoke.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/codex_audit_verdict.schema.json +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/config.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/controller.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/decisions.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/devin_cli_audit_pr.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/__init__.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/adoption.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/audit_limits.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/campaign_auth.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/cloud.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/common.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/github.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/github_actions.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/github_actions_cost.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/github_actions_cost_summary.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/github_actions_failure_annotations.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/github_actions_failure_models.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/github_actions_failure_scan.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/github_actions_failure_selection.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/github_actions_failures.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/github_actions_permissions.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/github_api.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/github_branch.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/github_config.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/github_human_token.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/github_provider.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/github_repo.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/github_trusted_authors.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/groups.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/models.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/output.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/presets.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/privacy.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/provider_api_model.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/provider_api_model_openai.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/provider_api_model_profiles.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/provider_env.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/provider_env_required.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/provider_env_tokens.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/provider_local_audit_setup.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/provider_local_cli.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/provider_local_cli_commands.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/provider_local_cli_probe_config.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/provider_probe.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/provider_probe_auth.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/provider_probe_evaluation.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/provider_probe_json.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/provider_probe_remediation.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/provider_review_hygiene.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/providers.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/registry.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/runner.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/runtime.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/runtime_github_auth.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/self_hosted_runner.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/doctor_checks/supervised_pilot.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/file_locks.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/gate_health.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/gemini_cli_audit_pr.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/git_identity.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/grok_build_audit_pr.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/hermes_cli_audit_pr.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/init.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/lane_configs/__init__.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/lane_configs/aider.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/lane_configs/antigravity_cli.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/lane_configs/claude.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/lane_configs/codex.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/lane_configs/devin.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/lane_configs/devin_cli.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/lane_configs/gemini_cli.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/lane_configs/grok_build.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/lane_configs/hermes_cli.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/lane_configs/local_llm.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/lane_configs/muse_cli.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/lane_delivery.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/lane_status.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/local_llm_audit_pr.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/local_llm_bakeoff.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/local_llm_calibration.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/local_llm_profiles.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/migration.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/migration_install.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/migration_mirror.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/migration_readiness.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/migration_rehearsal.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/muse_cli_audit_pr.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/next_steps.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/package.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/package_content.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/package_manifest.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/package_paths.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/package_rendering.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/package_static.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/participants.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/plan_context.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/productivity_report.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/prompts.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/provider_registry.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/provider_runners/__init__.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/provider_runners/comments.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/provider_runners/exit_codes.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/provider_runners/git.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/provider_runners/github_auth.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/provider_runners/github_pr.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/provider_runners/pr_worktree.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/provider_runners/process.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/provider_runners/repo_paths.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/provider_runners/text_schema.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/provider_runners/verdict_artifacts.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/provider_runners/workspace.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/providers/__init__.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/providers/local_cli.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/providers/provenance.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/release_qualify.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/release_readiness.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/reviewer_metrics.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/reviewer_spend.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/saas_reviewer_labeler.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/secrets.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/session.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/builder-experiment.example.json +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/calibration-corpus.example.json +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/calibration-corpus.json +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/code-mower.example.yml +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/context-packs.example.json +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/lane_prompts/base-audit.md +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/lane_prompts/calibration-policy.md +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/lane_prompts/context-driven-quality.md +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/lane_prompts/docs-design.md +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/lane_prompts/generic-programming.md +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/lane_prompts/operability.md +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/lane_prompts/package-runtime.md +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/lane_prompts/plan-conformance.md +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/lane_prompts/security-threat-model.md +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/lanes/README.md +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/lanes/claude.md +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/lanes/codex.md +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/lanes/cursor.md +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/lanes/devin.md +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/lanes/generic.md +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/lanes/run_mac_lane.sh +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/product-support/code_mower +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/product-support/code_mower_standalone_pin.env +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/product-support/code_mower_standalone_shadow.sh +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/product-support/run_claude_audit_pr.sh +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/product-support/run_codex_audit_pr.sh +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/product-support/run_devin_cli_audit_pr.sh +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/product-support/safe_gh_comment.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/product-support/status_report.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/providers.yml +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/reviewer-spend.example.json +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/reviewer-value-report.example.md +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/workflows/audit-label-cleanup.yml.j2 +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/workflows/code-mower-agent-pr-labeler.yml.j2 +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/workflows/code-mower-fix-round-dispatch.yml.j2 +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/workflows/code-mower-gate-health.yml.j2 +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/workflows/code-mower-gate.yml.j2 +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/workflows/dispatch-lanes.yml.j2 +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/workflows/hosted-bridge.yml.j2 +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/workflows/lane-mac-runner.yml.j2 +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/workflows/local-cli-audit.yml.j2 +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/workflows/needs-owner-notify.yml.j2 +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/workflows/private-standalone-shadow.yml.j2 +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/workflows/review-clear-stale.yml.j2 +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/workflows/saas-reviewer-labeler.yml.j2 +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/workflows/self-hosted-local-audit.yml.j2 +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/workflows/trailer-comment-labeler.yml.j2 +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/templates/workflows/weekly-status.yml.j2 +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/trailer_comment_labeler.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/versioning.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/work_orders.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower/workflow_actionlint.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower.egg-info/SOURCES.txt +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower.egg-info/dependency_links.txt +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower.egg-info/entry_points.txt +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower.egg-info/requires.txt +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/src/code_mower.egg-info/top_level.txt +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/builder-experiment.example.json +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/calibration-corpus.example.json +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/calibration-corpus.json +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/code-mower.yml.j2 +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/context-packs.example.json +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/cursor/BUGBOT.md +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/lanes/README.md +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/lanes/claude.md +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/lanes/codex.md +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/lanes/cursor.md +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/lanes/devin.md +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/lanes/generic.md +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/lanes/run_mac_lane.sh +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/providers/acp_bridge.yml +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/providers/aider.yml +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/providers/antigravity_cli.yml +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/providers/claude_audit.yml +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/providers/claude_review.yml +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/providers/coderabbit_cli.yml +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/providers/codex.yml +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/providers/cursor_bugbot.yml +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/providers/cursor_cloud_agent.yml +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/providers/devin.yml +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/providers/devin_cli.yml +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/providers/gemini_cli.yml +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/providers/gitar.yml +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/providers/greptile.yml +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/providers/hermes_cli.yml +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/providers/local_llm.yml +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/providers/muse_cli.yml +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/providers/qodo.yml +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/providers.yml +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/reviewer-spend.example.json +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/reviewer-value-report.example.md +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/workflows/audit-label-cleanup.yml.j2 +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/workflows/blind-review-artifacts-dry-run.yml.j2 +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/workflows/code-mower-agent-pr-labeler.yml.j2 +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/workflows/code-mower-fix-round-dispatch.yml.j2 +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/workflows/code-mower-gate-health.yml.j2 +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/workflows/code-mower-gate.yml.j2 +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/workflows/dispatch-lanes.yml.j2 +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/workflows/hosted-bridge.yml.j2 +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/workflows/lane-mac-runner.yml.j2 +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/workflows/local-cli-audit.yml.j2 +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/workflows/private-standalone-shadow.yml.j2 +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/workflows/review-clear-stale.yml.j2 +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/workflows/saas-reviewer-labeler.yml.j2 +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/workflows/self-hosted-local-audit.yml.j2 +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/templates/workflows/trailer-comment-labeler.yml.j2 +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_adoption_diagnostics.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_adoption_result_semantics.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_adoption_run_contract.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_antigravity_sdk_probe.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_audit_comment_posture.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_audit_limits.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_board.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_builder_experiment.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_builder_identity.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_builder_runs.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_calibration_effect_report.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_calibration_truth.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_campaign_adapters.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_campaign_discovery.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_campaign_retry_evidence_711.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_checks.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_claude_audit_pr.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_claude_cli_bounce.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_clear_stale.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_cloud_client.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_cloud_git_metadata.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_cloud_manifest.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_cloud_reports.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_coderabbit_cli_audit_pr.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_codex_audit_env_preflight.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_codex_audit_pr.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_controller.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_decision_audit_integration.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_decisions.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_devin_builder_lane.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_devin_cli_audit_pr.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_devin_provider_contract.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_doctor_actions_cost_summary.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_doctor_actions_failure_selection.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_doctor_boundaries.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_doctor_campaign_auth.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_doctor_campaign_readiness.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_doctor_github_checks.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_doctor_output.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_doctor_privacy.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_doctor_provider_env_required.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_doctor_provider_env_tokens.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_doctor_provider_local_audit_setup.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_doctor_provider_probe.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_doctor_provider_review_hygiene.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_doctor_registry.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_doctor_runtime.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_doctor_self_hosted_runner.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_doctor_supervised_pilot.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_file_locks.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_fork_pr_guard.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_gate_automerge.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_gate_health.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_hosted_dispatch_profile.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_init_actionlint.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_init_build_loop.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_lane_delivery_contract.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_lane_status.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_local_llm_github_helpers.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_migration_rehearsal.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_migration_setup_drift.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_next_steps.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_package_install_failure_taxonomy.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_participant_sessions.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_plan_context.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_pr_outcome_contract.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_productivity_metrics_contract.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_productivity_report.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_prompts.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_provider_fixture_contracts.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_provider_local_cli.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_provider_runners_comments.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_provider_runners_git.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_provider_runners_github_pr.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_provider_runners_pr_worktree.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_provider_runners_process.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_provider_runners_repo_paths.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_provider_runners_text_schema.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_provider_runners_workspace.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_release_qualify.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_reviewer_metrics_core.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_reviewer_spend.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_supervised_pilot_contract.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_trailer_comment_labeler.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_work_orders.py +0 -0
- {code_mower-1.0.12 → code_mower-1.0.14}/tests/test_work_type_contract.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: code-mower
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.14
|
|
4
4
|
Summary: Multi-reviewer AI code audit orchestration
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
Project-URL: Homepage, https://github.com/codemower-ai/code-mower
|
|
@@ -241,7 +241,7 @@ agent report its actual host posture, exact installed version, doctor result,
|
|
|
241
241
|
Board URL, and any owner-only click-list before it mutates the repo.
|
|
242
242
|
|
|
243
243
|
The current package-index announcement entry point is the tagged
|
|
244
|
-
[Try Code Mower In 10 Minutes](https://github.com/codemower-ai/code-mower/blob/v1.0.
|
|
244
|
+
[Try Code Mower In 10 Minutes](https://github.com/codemower-ai/code-mower/blob/v1.0.14/docs/try-in-10-minutes.md)
|
|
245
245
|
guide. The v1.0 supervised-pilot release includes the native Board, the
|
|
246
246
|
controller dry-run and policy contract, adoption and upgrade hardening from
|
|
247
247
|
recent install rehearsals, package-index release checks, provider-diversity
|
|
@@ -294,6 +294,18 @@ provider qualification prompt no longer tells the agent to create its own
|
|
|
294
294
|
temporary directory, so it stays in the disposable workspace Code Mower
|
|
295
295
|
already created, and it states the existing contract that a result's total
|
|
296
296
|
`elapsed_seconds` is the sum of its step values.
|
|
297
|
+
The v1.0.13 patch makes automatic campaign runtime selection sandbox-safe:
|
|
298
|
+
when `CODE_MOWER_PYTHON` is not set, Code Mower now prefers a supported
|
|
299
|
+
versioned Python on `PATH` outside the user home before falling back to its
|
|
300
|
+
own running interpreter, so a pipx- or uv-installed CLI stops handing Claude's
|
|
301
|
+
strict macOS sandbox an interpreter under the denied home tree. An explicit
|
|
302
|
+
`CODE_MOWER_PYTHON` remains authoritative.
|
|
303
|
+
The v1.0.14 patch corrects hosted Devin qualification result precedence: a
|
|
304
|
+
valid closed structured result is accepted even while the session still
|
|
305
|
+
reports `running` / `waiting_for_user`, so a finished informational Devin
|
|
306
|
+
attempt is no longer recorded as owner-blocked. An explicit terminal API
|
|
307
|
+
failure and a `waiting_for_approval` session still take precedence over any
|
|
308
|
+
structured output.
|
|
297
309
|
Package-only users can start from the public package rather than a source
|
|
298
310
|
checkout.
|
|
299
311
|
|
|
@@ -326,7 +338,7 @@ Provider-contract baseline for the next release train:
|
|
|
326
338
|
|
|
327
339
|
For release verification,
|
|
328
340
|
[First-User Install Rehearsal](docs/first-user-install-rehearsal.md) records
|
|
329
|
-
the package-index procedure for `v1.0.
|
|
341
|
+
the package-index procedure for `v1.0.14` / `code-mower==1.0.14`. The
|
|
330
342
|
GitHub release records the workflow and rehearsal evidence for the exact tag.
|
|
331
343
|
After publication, [Release Qualification](docs/release-qualification.md)
|
|
332
344
|
coordinates provider-specific install and operational checks without treating
|
|
@@ -520,8 +532,8 @@ measurement work.
|
|
|
520
532
|
|
|
521
533
|
## Installation Status
|
|
522
534
|
|
|
523
|
-
The current package-index release baseline is `v1.0.
|
|
524
|
-
install spec `code-mower==1.0.
|
|
535
|
+
The current package-index release baseline is `v1.0.14`, with pinned package
|
|
536
|
+
install spec `code-mower==1.0.14`. Release evidence is recorded on the GitHub
|
|
525
537
|
release and in the first-user install rehearsal. The public repository is
|
|
526
538
|
[codemower-ai/code-mower](https://github.com/codemower-ai/code-mower), and
|
|
527
539
|
GitHub releases remain the auditable source for tags, build artifacts, and
|
|
@@ -602,6 +614,8 @@ first so local work exercises the same package entrypoint users install.
|
|
|
602
614
|
- [v1.0.10 Release Notes](docs/v1010-release-notes.md)
|
|
603
615
|
- [v1.0.11 Release Notes](docs/v1011-release-notes.md)
|
|
604
616
|
- [v1.0.12 Release Notes](docs/v1012-release-notes.md)
|
|
617
|
+
- [v1.0.13 Release Notes](docs/v1013-release-notes.md)
|
|
618
|
+
- [v1.0.14 Release Notes](docs/v1014-release-notes.md)
|
|
605
619
|
- [Post-v0.8 Effectiveness Assessment](docs/post-v08-effectiveness-assessment.md)
|
|
606
620
|
- [v1.0.1 Effectiveness Assessment](docs/v101-effectiveness-assessment.md)
|
|
607
621
|
- [Demo Calibration Example](examples/demo-calibration/README.md)
|
|
@@ -211,7 +211,7 @@ agent report its actual host posture, exact installed version, doctor result,
|
|
|
211
211
|
Board URL, and any owner-only click-list before it mutates the repo.
|
|
212
212
|
|
|
213
213
|
The current package-index announcement entry point is the tagged
|
|
214
|
-
[Try Code Mower In 10 Minutes](https://github.com/codemower-ai/code-mower/blob/v1.0.
|
|
214
|
+
[Try Code Mower In 10 Minutes](https://github.com/codemower-ai/code-mower/blob/v1.0.14/docs/try-in-10-minutes.md)
|
|
215
215
|
guide. The v1.0 supervised-pilot release includes the native Board, the
|
|
216
216
|
controller dry-run and policy contract, adoption and upgrade hardening from
|
|
217
217
|
recent install rehearsals, package-index release checks, provider-diversity
|
|
@@ -264,6 +264,18 @@ provider qualification prompt no longer tells the agent to create its own
|
|
|
264
264
|
temporary directory, so it stays in the disposable workspace Code Mower
|
|
265
265
|
already created, and it states the existing contract that a result's total
|
|
266
266
|
`elapsed_seconds` is the sum of its step values.
|
|
267
|
+
The v1.0.13 patch makes automatic campaign runtime selection sandbox-safe:
|
|
268
|
+
when `CODE_MOWER_PYTHON` is not set, Code Mower now prefers a supported
|
|
269
|
+
versioned Python on `PATH` outside the user home before falling back to its
|
|
270
|
+
own running interpreter, so a pipx- or uv-installed CLI stops handing Claude's
|
|
271
|
+
strict macOS sandbox an interpreter under the denied home tree. An explicit
|
|
272
|
+
`CODE_MOWER_PYTHON` remains authoritative.
|
|
273
|
+
The v1.0.14 patch corrects hosted Devin qualification result precedence: a
|
|
274
|
+
valid closed structured result is accepted even while the session still
|
|
275
|
+
reports `running` / `waiting_for_user`, so a finished informational Devin
|
|
276
|
+
attempt is no longer recorded as owner-blocked. An explicit terminal API
|
|
277
|
+
failure and a `waiting_for_approval` session still take precedence over any
|
|
278
|
+
structured output.
|
|
267
279
|
Package-only users can start from the public package rather than a source
|
|
268
280
|
checkout.
|
|
269
281
|
|
|
@@ -296,7 +308,7 @@ Provider-contract baseline for the next release train:
|
|
|
296
308
|
|
|
297
309
|
For release verification,
|
|
298
310
|
[First-User Install Rehearsal](docs/first-user-install-rehearsal.md) records
|
|
299
|
-
the package-index procedure for `v1.0.
|
|
311
|
+
the package-index procedure for `v1.0.14` / `code-mower==1.0.14`. The
|
|
300
312
|
GitHub release records the workflow and rehearsal evidence for the exact tag.
|
|
301
313
|
After publication, [Release Qualification](docs/release-qualification.md)
|
|
302
314
|
coordinates provider-specific install and operational checks without treating
|
|
@@ -490,8 +502,8 @@ measurement work.
|
|
|
490
502
|
|
|
491
503
|
## Installation Status
|
|
492
504
|
|
|
493
|
-
The current package-index release baseline is `v1.0.
|
|
494
|
-
install spec `code-mower==1.0.
|
|
505
|
+
The current package-index release baseline is `v1.0.14`, with pinned package
|
|
506
|
+
install spec `code-mower==1.0.14`. Release evidence is recorded on the GitHub
|
|
495
507
|
release and in the first-user install rehearsal. The public repository is
|
|
496
508
|
[codemower-ai/code-mower](https://github.com/codemower-ai/code-mower), and
|
|
497
509
|
GitHub releases remain the auditable source for tags, build artifacts, and
|
|
@@ -572,6 +584,8 @@ first so local work exercises the same package entrypoint users install.
|
|
|
572
584
|
- [v1.0.10 Release Notes](docs/v1010-release-notes.md)
|
|
573
585
|
- [v1.0.11 Release Notes](docs/v1011-release-notes.md)
|
|
574
586
|
- [v1.0.12 Release Notes](docs/v1012-release-notes.md)
|
|
587
|
+
- [v1.0.13 Release Notes](docs/v1013-release-notes.md)
|
|
588
|
+
- [v1.0.14 Release Notes](docs/v1014-release-notes.md)
|
|
575
589
|
- [Post-v0.8 Effectiveness Assessment](docs/post-v08-effectiveness-assessment.md)
|
|
576
590
|
- [v1.0.1 Effectiveness Assessment](docs/v101-effectiveness-assessment.md)
|
|
577
591
|
- [Demo Calibration Example](examples/demo-calibration/README.md)
|
|
@@ -238,13 +238,6 @@ def poll_devin_session(
|
|
|
238
238
|
return "failed", None, exc.code
|
|
239
239
|
status = str(data.get("status") or "")
|
|
240
240
|
detail = str(data.get("status_detail") or "")
|
|
241
|
-
if detail in {"waiting_for_user", "waiting_for_approval"}:
|
|
242
|
-
return "owner_action", None, "devin_waiting_for_owner"
|
|
243
|
-
if status == "exit" or detail == "finished":
|
|
244
|
-
result = data.get("structured_output")
|
|
245
|
-
if isinstance(result, dict):
|
|
246
|
-
return "complete", dict(result), ""
|
|
247
|
-
return "failed", None, "hosted_result_rejected"
|
|
248
241
|
if status in {"error", "suspended"} or detail in {
|
|
249
242
|
"error",
|
|
250
243
|
"usage_limit_exceeded",
|
|
@@ -256,4 +249,13 @@ def poll_devin_session(
|
|
|
256
249
|
"total_session_limit_exceeded",
|
|
257
250
|
}:
|
|
258
251
|
return "failed", None, "devin_session_failed"
|
|
252
|
+
if detail == "waiting_for_approval":
|
|
253
|
+
return "owner_action", None, "devin_waiting_for_owner"
|
|
254
|
+
result = data.get("structured_output")
|
|
255
|
+
if isinstance(result, dict):
|
|
256
|
+
return "complete", dict(result), ""
|
|
257
|
+
if detail == "waiting_for_user":
|
|
258
|
+
return "owner_action", None, "devin_waiting_for_owner"
|
|
259
|
+
if status == "exit" or detail == "finished":
|
|
260
|
+
return "failed", None, "hosted_result_rejected"
|
|
259
261
|
return "running", None, ""
|
|
@@ -2348,6 +2348,30 @@ def _versioned_python_candidates(path_value: str) -> tuple[str, ...]:
|
|
|
2348
2348
|
return tuple(f"python3.{minor}" for minor in sorted(minors, reverse=True))
|
|
2349
2349
|
|
|
2350
2350
|
|
|
2351
|
+
def _resolve_python_candidate(
|
|
2352
|
+
candidate: str,
|
|
2353
|
+
*,
|
|
2354
|
+
explicit: str,
|
|
2355
|
+
which_fn: Callable[[str], str | None],
|
|
2356
|
+
) -> str | None:
|
|
2357
|
+
candidate_path = Path(candidate).expanduser()
|
|
2358
|
+
is_path = bool(
|
|
2359
|
+
os.sep in candidate
|
|
2360
|
+
or (os.altsep and os.altsep in candidate)
|
|
2361
|
+
or candidate == sys.executable
|
|
2362
|
+
or (candidate == explicit and candidate_path.exists())
|
|
2363
|
+
)
|
|
2364
|
+
if is_path:
|
|
2365
|
+
if not candidate_path.exists():
|
|
2366
|
+
return None
|
|
2367
|
+
return str(candidate_path if candidate_path.is_absolute() else candidate_path.resolve())
|
|
2368
|
+
resolved = which_fn(candidate)
|
|
2369
|
+
if not resolved:
|
|
2370
|
+
return None
|
|
2371
|
+
resolved_path = Path(resolved).expanduser()
|
|
2372
|
+
return str(resolved_path if resolved_path.is_absolute() else resolved_path.resolve())
|
|
2373
|
+
|
|
2374
|
+
|
|
2351
2375
|
def resolve_supported_runtime(
|
|
2352
2376
|
*,
|
|
2353
2377
|
environ: Mapping[str, str] | None = None,
|
|
@@ -2361,43 +2385,42 @@ def resolve_supported_runtime(
|
|
|
2361
2385
|
"""
|
|
2362
2386
|
env = os.environ if environ is None else environ
|
|
2363
2387
|
explicit = env.get("CODE_MOWER_PYTHON", "").strip()
|
|
2388
|
+
which = shutil.which if which_fn is None else which_fn
|
|
2364
2389
|
if explicit:
|
|
2365
|
-
|
|
2390
|
+
resolved = _resolve_python_candidate(explicit, explicit=explicit, which_fn=which)
|
|
2391
|
+
candidates = (resolved,) if resolved else ()
|
|
2366
2392
|
else:
|
|
2367
2393
|
discovered = _versioned_python_candidates(str(env.get("PATH", "")))
|
|
2368
|
-
|
|
2369
|
-
sys.executable,
|
|
2394
|
+
raw_candidates = (
|
|
2370
2395
|
*discovered,
|
|
2371
|
-
"python3.12",
|
|
2372
|
-
"python3.13",
|
|
2373
2396
|
"python3.14",
|
|
2397
|
+
"python3.13",
|
|
2398
|
+
"python3.12",
|
|
2374
2399
|
"python3",
|
|
2400
|
+
sys.executable,
|
|
2375
2401
|
)
|
|
2376
|
-
|
|
2402
|
+
resolved_candidates: list[str] = []
|
|
2403
|
+
seen: set[str] = set()
|
|
2404
|
+
for candidate in raw_candidates:
|
|
2405
|
+
resolved = _resolve_python_candidate(candidate, explicit="", which_fn=which)
|
|
2406
|
+
if resolved and resolved not in seen:
|
|
2407
|
+
seen.add(resolved)
|
|
2408
|
+
resolved_candidates.append(resolved)
|
|
2409
|
+
|
|
2410
|
+
home = Path(str(env.get("HOME") or Path.home())).expanduser().resolve()
|
|
2411
|
+
outside_home = [
|
|
2412
|
+
candidate for candidate in resolved_candidates if not Path(candidate).resolve().is_relative_to(home)
|
|
2413
|
+
]
|
|
2414
|
+
inside_home = [candidate for candidate in resolved_candidates if Path(candidate).resolve().is_relative_to(home)]
|
|
2415
|
+
candidates = (*outside_home, *inside_home)
|
|
2416
|
+
|
|
2377
2417
|
run = subprocess.run if runner is None else runner
|
|
2378
2418
|
for cand in candidates:
|
|
2379
2419
|
if not cand:
|
|
2380
2420
|
continue
|
|
2381
|
-
cand_path = Path(cand).expanduser()
|
|
2382
|
-
if (
|
|
2383
|
-
os.sep in cand
|
|
2384
|
-
or (os.altsep and os.altsep in cand)
|
|
2385
|
-
or cand == sys.executable
|
|
2386
|
-
or (cand == explicit and cand_path.exists())
|
|
2387
|
-
):
|
|
2388
|
-
if cand_path.exists():
|
|
2389
|
-
resolved = str(cand_path.resolve()) if not cand_path.is_absolute() else cand
|
|
2390
|
-
else:
|
|
2391
|
-
resolved = None
|
|
2392
|
-
else:
|
|
2393
|
-
resolved = which(cand)
|
|
2394
|
-
if resolved and not Path(resolved).is_absolute():
|
|
2395
|
-
resolved = str(Path(resolved).resolve())
|
|
2396
|
-
if not resolved:
|
|
2397
|
-
continue
|
|
2398
2421
|
try:
|
|
2399
2422
|
completed = run(
|
|
2400
|
-
[
|
|
2423
|
+
[cand, "-c", "import sys; print(f'{sys.version_info[0]}.{sys.version_info[1]}')"],
|
|
2401
2424
|
text=True,
|
|
2402
2425
|
capture_output=True,
|
|
2403
2426
|
check=False,
|
|
@@ -2414,7 +2437,7 @@ def resolve_supported_runtime(
|
|
|
2414
2437
|
except (IndexError, ValueError):
|
|
2415
2438
|
continue
|
|
2416
2439
|
if (major, minor) >= (3, 12):
|
|
2417
|
-
return
|
|
2440
|
+
return cand, f"python_{major}.{minor}"
|
|
2418
2441
|
return None
|
|
2419
2442
|
|
|
2420
2443
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: code-mower
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.14
|
|
4
4
|
Summary: Multi-reviewer AI code audit orchestration
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
Project-URL: Homepage, https://github.com/codemower-ai/code-mower
|
|
@@ -241,7 +241,7 @@ agent report its actual host posture, exact installed version, doctor result,
|
|
|
241
241
|
Board URL, and any owner-only click-list before it mutates the repo.
|
|
242
242
|
|
|
243
243
|
The current package-index announcement entry point is the tagged
|
|
244
|
-
[Try Code Mower In 10 Minutes](https://github.com/codemower-ai/code-mower/blob/v1.0.
|
|
244
|
+
[Try Code Mower In 10 Minutes](https://github.com/codemower-ai/code-mower/blob/v1.0.14/docs/try-in-10-minutes.md)
|
|
245
245
|
guide. The v1.0 supervised-pilot release includes the native Board, the
|
|
246
246
|
controller dry-run and policy contract, adoption and upgrade hardening from
|
|
247
247
|
recent install rehearsals, package-index release checks, provider-diversity
|
|
@@ -294,6 +294,18 @@ provider qualification prompt no longer tells the agent to create its own
|
|
|
294
294
|
temporary directory, so it stays in the disposable workspace Code Mower
|
|
295
295
|
already created, and it states the existing contract that a result's total
|
|
296
296
|
`elapsed_seconds` is the sum of its step values.
|
|
297
|
+
The v1.0.13 patch makes automatic campaign runtime selection sandbox-safe:
|
|
298
|
+
when `CODE_MOWER_PYTHON` is not set, Code Mower now prefers a supported
|
|
299
|
+
versioned Python on `PATH` outside the user home before falling back to its
|
|
300
|
+
own running interpreter, so a pipx- or uv-installed CLI stops handing Claude's
|
|
301
|
+
strict macOS sandbox an interpreter under the denied home tree. An explicit
|
|
302
|
+
`CODE_MOWER_PYTHON` remains authoritative.
|
|
303
|
+
The v1.0.14 patch corrects hosted Devin qualification result precedence: a
|
|
304
|
+
valid closed structured result is accepted even while the session still
|
|
305
|
+
reports `running` / `waiting_for_user`, so a finished informational Devin
|
|
306
|
+
attempt is no longer recorded as owner-blocked. An explicit terminal API
|
|
307
|
+
failure and a `waiting_for_approval` session still take precedence over any
|
|
308
|
+
structured output.
|
|
297
309
|
Package-only users can start from the public package rather than a source
|
|
298
310
|
checkout.
|
|
299
311
|
|
|
@@ -326,7 +338,7 @@ Provider-contract baseline for the next release train:
|
|
|
326
338
|
|
|
327
339
|
For release verification,
|
|
328
340
|
[First-User Install Rehearsal](docs/first-user-install-rehearsal.md) records
|
|
329
|
-
the package-index procedure for `v1.0.
|
|
341
|
+
the package-index procedure for `v1.0.14` / `code-mower==1.0.14`. The
|
|
330
342
|
GitHub release records the workflow and rehearsal evidence for the exact tag.
|
|
331
343
|
After publication, [Release Qualification](docs/release-qualification.md)
|
|
332
344
|
coordinates provider-specific install and operational checks without treating
|
|
@@ -520,8 +532,8 @@ measurement work.
|
|
|
520
532
|
|
|
521
533
|
## Installation Status
|
|
522
534
|
|
|
523
|
-
The current package-index release baseline is `v1.0.
|
|
524
|
-
install spec `code-mower==1.0.
|
|
535
|
+
The current package-index release baseline is `v1.0.14`, with pinned package
|
|
536
|
+
install spec `code-mower==1.0.14`. Release evidence is recorded on the GitHub
|
|
525
537
|
release and in the first-user install rehearsal. The public repository is
|
|
526
538
|
[codemower-ai/code-mower](https://github.com/codemower-ai/code-mower), and
|
|
527
539
|
GitHub releases remain the auditable source for tags, build artifacts, and
|
|
@@ -602,6 +614,8 @@ first so local work exercises the same package entrypoint users install.
|
|
|
602
614
|
- [v1.0.10 Release Notes](docs/v1010-release-notes.md)
|
|
603
615
|
- [v1.0.11 Release Notes](docs/v1011-release-notes.md)
|
|
604
616
|
- [v1.0.12 Release Notes](docs/v1012-release-notes.md)
|
|
617
|
+
- [v1.0.13 Release Notes](docs/v1013-release-notes.md)
|
|
618
|
+
- [v1.0.14 Release Notes](docs/v1014-release-notes.md)
|
|
605
619
|
- [Post-v0.8 Effectiveness Assessment](docs/post-v08-effectiveness-assessment.md)
|
|
606
620
|
- [v1.0.1 Effectiveness Assessment](docs/v101-effectiveness-assessment.md)
|
|
607
621
|
- [Demo Calibration Example](examples/demo-calibration/README.md)
|
|
@@ -172,6 +172,61 @@ class DevinApiModuleTests(unittest.TestCase):
|
|
|
172
172
|
("failed", None, "devin_session_failed"),
|
|
173
173
|
)
|
|
174
174
|
|
|
175
|
+
def test_poll_accepts_structured_result_while_devin_waits_for_user(self) -> None:
|
|
176
|
+
result = _adoption_result()
|
|
177
|
+
runner = _FakeApiRunner(
|
|
178
|
+
[
|
|
179
|
+
{
|
|
180
|
+
"status": "running",
|
|
181
|
+
"status_detail": "waiting_for_user",
|
|
182
|
+
"structured_output": result,
|
|
183
|
+
}
|
|
184
|
+
]
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
self.assertEqual(
|
|
188
|
+
devin_api.poll_devin_session(
|
|
189
|
+
"org-test", "devin-1", "key", api_runner=runner
|
|
190
|
+
),
|
|
191
|
+
("complete", result, ""),
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
def test_poll_keeps_terminal_failure_ahead_of_structured_output(self) -> None:
|
|
195
|
+
runner = _FakeApiRunner(
|
|
196
|
+
[
|
|
197
|
+
{
|
|
198
|
+
"status": "error",
|
|
199
|
+
"status_detail": "out_of_credits",
|
|
200
|
+
"structured_output": _adoption_result(),
|
|
201
|
+
}
|
|
202
|
+
]
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
self.assertEqual(
|
|
206
|
+
devin_api.poll_devin_session(
|
|
207
|
+
"org-test", "devin-1", "key", api_runner=runner
|
|
208
|
+
),
|
|
209
|
+
("failed", None, "devin_session_failed"),
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
def test_poll_keeps_owner_approval_ahead_of_structured_output(self) -> None:
|
|
213
|
+
runner = _FakeApiRunner(
|
|
214
|
+
[
|
|
215
|
+
{
|
|
216
|
+
"status": "running",
|
|
217
|
+
"status_detail": "waiting_for_approval",
|
|
218
|
+
"structured_output": _adoption_result(),
|
|
219
|
+
}
|
|
220
|
+
]
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
self.assertEqual(
|
|
224
|
+
devin_api.poll_devin_session(
|
|
225
|
+
"org-test", "devin-1", "key", api_runner=runner
|
|
226
|
+
),
|
|
227
|
+
("owner_action", None, "devin_waiting_for_owner"),
|
|
228
|
+
)
|
|
229
|
+
|
|
175
230
|
|
|
176
231
|
class DevinCampaignApiTests(unittest.TestCase):
|
|
177
232
|
def _campaign(
|
|
@@ -12756,6 +12756,78 @@ class RuntimeReadinessCampaignTests(unittest.TestCase):
|
|
|
12756
12756
|
|
|
12757
12757
|
self.assertEqual(res, (str(python315), "python_3.15"))
|
|
12758
12758
|
|
|
12759
|
+
def test_resolve_supported_runtime_prefers_path_runtime_outside_home(self) -> None:
|
|
12760
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
12761
|
+
root = Path(tmp)
|
|
12762
|
+
home = root / "home"
|
|
12763
|
+
home_python = home / "pipx" / "python3.14"
|
|
12764
|
+
external_bin = root / "toolchain" / "bin"
|
|
12765
|
+
external_python = external_bin / "python3.12"
|
|
12766
|
+
home_python.parent.mkdir(parents=True)
|
|
12767
|
+
external_bin.mkdir(parents=True)
|
|
12768
|
+
home_python.touch()
|
|
12769
|
+
external_python.touch()
|
|
12770
|
+
|
|
12771
|
+
def fake_which(command: str) -> str | None:
|
|
12772
|
+
return str(external_python) if command == "python3.12" else None
|
|
12773
|
+
|
|
12774
|
+
def fake_runner(command: list[str], **kwargs: Any) -> subprocess.CompletedProcess[str]:
|
|
12775
|
+
version = "3.12.9\n" if command[0] == str(external_python) else "3.14.1\n"
|
|
12776
|
+
return subprocess.CompletedProcess(command, 0, stdout=version, stderr="")
|
|
12777
|
+
|
|
12778
|
+
with mock.patch.object(release_campaigns.sys, "executable", str(home_python)):
|
|
12779
|
+
result = release_campaigns.resolve_supported_runtime(
|
|
12780
|
+
environ={"HOME": str(home), "PATH": str(external_bin)},
|
|
12781
|
+
which_fn=fake_which,
|
|
12782
|
+
runner=fake_runner,
|
|
12783
|
+
)
|
|
12784
|
+
|
|
12785
|
+
self.assertEqual(result, (str(external_python), "python_3.12"))
|
|
12786
|
+
|
|
12787
|
+
def test_resolve_supported_runtime_falls_back_to_running_interpreter_in_home(self) -> None:
|
|
12788
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
12789
|
+
home = Path(tmp) / "home"
|
|
12790
|
+
home_python = home / "pipx" / "python3.14"
|
|
12791
|
+
home_python.parent.mkdir(parents=True)
|
|
12792
|
+
home_python.touch()
|
|
12793
|
+
|
|
12794
|
+
def fake_runner(command: list[str], **kwargs: Any) -> subprocess.CompletedProcess[str]:
|
|
12795
|
+
return subprocess.CompletedProcess(command, 0, stdout="3.14.1\n", stderr="")
|
|
12796
|
+
|
|
12797
|
+
with mock.patch.object(release_campaigns.sys, "executable", str(home_python)):
|
|
12798
|
+
result = release_campaigns.resolve_supported_runtime(
|
|
12799
|
+
environ={"HOME": str(home), "PATH": ""},
|
|
12800
|
+
which_fn=lambda _: None,
|
|
12801
|
+
runner=fake_runner,
|
|
12802
|
+
)
|
|
12803
|
+
|
|
12804
|
+
self.assertEqual(result, (str(home_python), "python_3.14"))
|
|
12805
|
+
|
|
12806
|
+
def test_resolve_supported_runtime_keeps_explicit_home_override_authoritative(self) -> None:
|
|
12807
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
12808
|
+
home = Path(tmp) / "home"
|
|
12809
|
+
explicit_python = home / "python3.12"
|
|
12810
|
+
external_python = Path(tmp) / "external" / "python3.14"
|
|
12811
|
+
explicit_python.parent.mkdir(parents=True)
|
|
12812
|
+
external_python.parent.mkdir(parents=True)
|
|
12813
|
+
explicit_python.touch()
|
|
12814
|
+
external_python.touch()
|
|
12815
|
+
|
|
12816
|
+
def fake_runner(command: list[str], **kwargs: Any) -> subprocess.CompletedProcess[str]:
|
|
12817
|
+
return subprocess.CompletedProcess(command, 0, stdout="3.12.9\n", stderr="")
|
|
12818
|
+
|
|
12819
|
+
result = release_campaigns.resolve_supported_runtime(
|
|
12820
|
+
environ={
|
|
12821
|
+
"CODE_MOWER_PYTHON": str(explicit_python),
|
|
12822
|
+
"HOME": str(home),
|
|
12823
|
+
"PATH": str(external_python.parent),
|
|
12824
|
+
},
|
|
12825
|
+
which_fn=lambda _: str(external_python),
|
|
12826
|
+
runner=fake_runner,
|
|
12827
|
+
)
|
|
12828
|
+
|
|
12829
|
+
self.assertEqual(result, (str(explicit_python), "python_3.12"))
|
|
12830
|
+
|
|
12759
12831
|
def test_invoke_local_adapter_fails_closed_when_runtime_unavailable(self) -> None:
|
|
12760
12832
|
invoked: list[str] = []
|
|
12761
12833
|
|