code-mower 1.0.8__tar.gz → 1.0.10__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.8 → code_mower-1.0.10}/PKG-INFO +48 -17
- {code_mower-1.0.8 → code_mower-1.0.10}/README.md +47 -16
- {code_mower-1.0.8 → code_mower-1.0.10}/pyproject.toml +1 -1
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/__init__.py +1 -1
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/board.py +83 -36
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/builder_runs.py +4 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/campaign_adapters.py +231 -20
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/cli.py +19 -12
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/cloud_client/__init__.py +2 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/cloud_client/adoption_runs.py +46 -20
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/code_mower_telemetry.py +2 -0
- code_mower-1.0.10/src/code_mower/devin_cli_audit_pr.py +1483 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/campaign_auth.py +34 -7
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/provider_local_cli.py +99 -20
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/init.py +76 -2
- code_mower-1.0.10/src/code_mower/lane_configs/devin_cli.py +36 -0
- code_mower-1.0.10/src/code_mower/lane_delivery.py +1375 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/lane_status.py +1 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/migration_install.py +160 -20
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/migration_rehearsal.py +7 -1
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/next_steps.py +161 -44
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/package_manifest.py +12 -0
- code_mower-1.0.10/src/code_mower/participants.py +179 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/provider_registry.py +52 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/release_campaigns.py +558 -70
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/release_qualify.py +82 -4
- code_mower-1.0.10/src/code_mower/session.py +154 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/code-mower.example.yml +9 -4
- code_mower-1.0.10/src/code_mower/templates/lanes/devin.md +41 -0
- code_mower-1.0.10/src/code_mower/templates/lanes/run_mac_lane.sh +1232 -0
- code_mower-1.0.10/src/code_mower/templates/product-support/run_devin_cli_audit_pr.sh +63 -0
- {code_mower-1.0.8 → code_mower-1.0.10/src/code_mower}/templates/providers.yml +74 -5
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/workflows/builder-provenance.yml.j2 +1 -1
- {code_mower-1.0.8 → code_mower-1.0.10/src/code_mower}/templates/workflows/local-cli-audit.yml.j2 +1 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower.egg-info/PKG-INFO +48 -17
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower.egg-info/SOURCES.txt +16 -0
- code_mower-1.0.10/templates/lanes/devin.md +41 -0
- code_mower-1.0.10/templates/lanes/run_mac_lane.sh +1232 -0
- code_mower-1.0.10/templates/providers/devin_cli.yml +70 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/providers/gitar.yml +1 -1
- {code_mower-1.0.8/src/code_mower → code_mower-1.0.10}/templates/providers.yml +74 -5
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/workflows/builder-provenance.yml.j2 +1 -1
- {code_mower-1.0.8/src/code_mower → code_mower-1.0.10}/templates/workflows/local-cli-audit.yml.j2 +1 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_adoption_run_contract.py +44 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_board.py +173 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_builder_identity.py +4 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_campaign_adapters.py +652 -6
- code_mower-1.0.10/tests/test_devin_builder_lane.py +1538 -0
- code_mower-1.0.10/tests/test_devin_cli_audit_pr.py +974 -0
- code_mower-1.0.10/tests/test_devin_provider_contract.py +743 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_doctor_campaign_auth.py +6 -2
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_init_build_loop.py +318 -15
- code_mower-1.0.10/tests/test_lane_delivery_contract.py +2175 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_migration_rehearsal.py +71 -16
- code_mower-1.0.10/tests/test_next_steps.py +147 -0
- code_mower-1.0.10/tests/test_package_install_failure_taxonomy.py +489 -0
- code_mower-1.0.10/tests/test_participant_sessions.py +210 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_provider_fixture_contracts.py +3 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_release_campaigns.py +1372 -48
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_release_hygiene.py +92 -78
- code_mower-1.0.8/src/code_mower/templates/lanes/run_mac_lane.sh +0 -532
- code_mower-1.0.8/templates/lanes/run_mac_lane.sh +0 -532
- {code_mower-1.0.8 → code_mower-1.0.10}/CODE_OF_CONDUCT.md +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/LICENSE +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/MANIFEST.in +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/NOTICE +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/SUPPORT.md +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/requirements/requirements.txt +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/setup.cfg +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/adapters/__init__.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/adapters/_base.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/adapters/cursor_bugbot.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/adapters/gitar.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/adapters/greptile.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/adapters/qodo.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/antigravity_cli_audit_pr.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/antigravity_sdk_probe.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/audit_handoff_log.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/audit_labeler_lib.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/audit_limits.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/audit_progress.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/blind_review_artifacts.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/blind_review_coordinator.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/board_store.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/bootstrap.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/builder_experiment.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/calibration/__init__.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/calibration/arms.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/calibration/auto_discovery.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/calibration/commands.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/calibration/context_inputs.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/calibration/corpus.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/calibration/effect_report.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/calibration/evidence.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/calibration/evidence_report.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/calibration/identity.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/calibration/metrics.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/calibration/overlap.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/calibration/planning.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/calibration/policy.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/calibration/results.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/calibration/run_results.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/calibration/run_status.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/calibration/runner.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/calibration/truth.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/calibration/value_report.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/campaign_discovery.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/checks.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/claude_audit_pr.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/claude_cli_bounce.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/claude_cli_environment.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/clear_stale.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/cloud.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/cloud_client/bundle.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/cloud_client/doctor.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/cloud_client/dogfood.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/cloud_client/endpoints.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/cloud_client/errors.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/cloud_client/events.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/cloud_client/export.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/cloud_client/git_metadata.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/cloud_client/manifest.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/cloud_client/operations.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/cloud_client/pr_outcomes.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/cloud_client/productivity.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/cloud_client/reports.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/cloud_client/setup.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/cloud_client/tokens.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/cloud_client/upload.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/cloud_client/work_types.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/code_mower_calibration.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/code_mower_context_packs.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/code_mower_merge.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/coderabbit_cli_audit_pr.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/codex_audit_env_preflight.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/codex_audit_pr.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/codex_audit_schema_smoke.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/codex_audit_verdict.schema.json +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/config.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/controller.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/decisions.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/__init__.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/adoption.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/audit_limits.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/cloud.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/common.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/github.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/github_actions.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/github_actions_cost.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/github_actions_cost_summary.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/github_actions_failure_annotations.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/github_actions_failure_models.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/github_actions_failure_scan.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/github_actions_failure_selection.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/github_actions_failures.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/github_actions_permissions.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/github_api.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/github_branch.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/github_config.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/github_human_token.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/github_provider.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/github_repo.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/github_trusted_authors.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/groups.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/models.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/output.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/presets.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/privacy.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/provider_api_model.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/provider_api_model_openai.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/provider_api_model_profiles.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/provider_env.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/provider_env_required.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/provider_env_tokens.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/provider_local_audit_setup.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/provider_local_cli_commands.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/provider_local_cli_probe_config.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/provider_probe.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/provider_probe_auth.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/provider_probe_evaluation.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/provider_probe_json.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/provider_probe_remediation.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/provider_review_hygiene.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/providers.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/registry.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/runner.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/runtime.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/runtime_github_auth.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/self_hosted_runner.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/doctor_checks/supervised_pilot.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/file_locks.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/gate_health.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/gemini_cli_audit_pr.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/git_identity.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/grok_build_audit_pr.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/hermes_cli_audit_pr.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/lane_configs/__init__.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/lane_configs/aider.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/lane_configs/antigravity_cli.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/lane_configs/claude.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/lane_configs/codex.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/lane_configs/devin.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/lane_configs/gemini_cli.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/lane_configs/grok_build.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/lane_configs/hermes_cli.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/lane_configs/local_llm.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/lane_configs/muse_cli.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/local_llm_audit_pr.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/local_llm_bakeoff.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/local_llm_calibration.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/local_llm_profiles.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/migration.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/migration_mirror.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/migration_readiness.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/muse_cli_audit_pr.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/package.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/package_content.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/package_paths.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/package_rendering.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/package_static.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/plan_context.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/productivity_report.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/prompts.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/provider_runners/__init__.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/provider_runners/comments.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/provider_runners/exit_codes.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/provider_runners/git.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/provider_runners/github_auth.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/provider_runners/github_pr.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/provider_runners/pr_worktree.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/provider_runners/process.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/provider_runners/repo_paths.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/provider_runners/text_schema.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/provider_runners/verdict_artifacts.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/provider_runners/workspace.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/providers/__init__.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/providers/local_cli.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/providers/provenance.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/release_readiness.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/reviewer_metrics.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/reviewer_spend.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/saas_reviewer_labeler.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/secrets.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/builder-experiment.example.json +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/calibration-corpus.example.json +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/calibration-corpus.json +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/context-packs.example.json +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/lane_prompts/base-audit.md +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/lane_prompts/calibration-policy.md +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/lane_prompts/context-driven-quality.md +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/lane_prompts/docs-design.md +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/lane_prompts/generic-programming.md +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/lane_prompts/operability.md +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/lane_prompts/package-runtime.md +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/lane_prompts/plan-conformance.md +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/lane_prompts/security-threat-model.md +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/lanes/README.md +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/lanes/claude.md +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/lanes/codex.md +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/lanes/cursor.md +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/lanes/generic.md +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/product-support/code_mower +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/product-support/code_mower_standalone_pin.env +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/product-support/code_mower_standalone_shadow.sh +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/product-support/run_claude_audit_pr.sh +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/product-support/run_codex_audit_pr.sh +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/product-support/safe_gh_comment.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/product-support/status_report.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/reviewer-spend.example.json +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/reviewer-value-report.example.md +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/workflows/audit-label-cleanup.yml.j2 +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/workflows/code-mower-agent-pr-labeler.yml.j2 +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/workflows/code-mower-fix-round-dispatch.yml.j2 +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/workflows/code-mower-gate-health.yml.j2 +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/workflows/code-mower-gate.yml.j2 +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/workflows/dispatch-lanes.yml.j2 +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/workflows/hosted-bridge.yml.j2 +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/workflows/lane-mac-runner.yml.j2 +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/workflows/needs-owner-notify.yml.j2 +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/workflows/private-standalone-shadow.yml.j2 +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/workflows/review-clear-stale.yml.j2 +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/workflows/saas-reviewer-labeler.yml.j2 +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/workflows/self-hosted-local-audit.yml.j2 +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/workflows/trailer-comment-labeler.yml.j2 +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/templates/workflows/weekly-status.yml.j2 +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/trailer_comment_labeler.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/versioning.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/work_orders.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower/workflow_actionlint.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower.egg-info/dependency_links.txt +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower.egg-info/entry_points.txt +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower.egg-info/requires.txt +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/src/code_mower.egg-info/top_level.txt +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/builder-experiment.example.json +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/calibration-corpus.example.json +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/calibration-corpus.json +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/code-mower.yml.j2 +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/context-packs.example.json +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/cursor/BUGBOT.md +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/lanes/README.md +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/lanes/claude.md +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/lanes/codex.md +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/lanes/cursor.md +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/lanes/generic.md +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/providers/acp_bridge.yml +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/providers/aider.yml +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/providers/antigravity_cli.yml +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/providers/claude_audit.yml +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/providers/claude_review.yml +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/providers/coderabbit_cli.yml +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/providers/codex.yml +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/providers/cursor_bugbot.yml +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/providers/cursor_cloud_agent.yml +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/providers/devin.yml +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/providers/gemini_cli.yml +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/providers/greptile.yml +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/providers/hermes_cli.yml +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/providers/local_llm.yml +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/providers/muse_cli.yml +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/providers/qodo.yml +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/reviewer-spend.example.json +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/reviewer-value-report.example.md +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/workflows/audit-label-cleanup.yml.j2 +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/workflows/blind-review-artifacts-dry-run.yml.j2 +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/workflows/code-mower-agent-pr-labeler.yml.j2 +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/workflows/code-mower-fix-round-dispatch.yml.j2 +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/workflows/code-mower-gate-health.yml.j2 +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/workflows/code-mower-gate.yml.j2 +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/workflows/dispatch-lanes.yml.j2 +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/workflows/hosted-bridge.yml.j2 +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/workflows/lane-mac-runner.yml.j2 +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/workflows/private-standalone-shadow.yml.j2 +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/workflows/review-clear-stale.yml.j2 +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/workflows/saas-reviewer-labeler.yml.j2 +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/workflows/self-hosted-local-audit.yml.j2 +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/templates/workflows/trailer-comment-labeler.yml.j2 +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_adoption_diagnostics.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_adoption_result_semantics.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_antigravity_sdk_probe.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_audit_comment_posture.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_audit_limits.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_builder_experiment.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_builder_runs.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_calibration_effect_report.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_calibration_truth.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_campaign_discovery.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_campaign_retry_evidence_711.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_checks.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_claude_audit_pr.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_claude_cli_bounce.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_clear_stale.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_cloud_client.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_cloud_git_metadata.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_cloud_manifest.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_cloud_reports.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_coderabbit_cli_audit_pr.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_codex_audit_env_preflight.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_codex_audit_pr.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_controller.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_decision_audit_integration.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_decisions.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_doctor_actions_cost_summary.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_doctor_actions_failure_selection.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_doctor_boundaries.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_doctor_campaign_readiness.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_doctor_github_checks.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_doctor_output.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_doctor_privacy.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_doctor_provider_env_required.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_doctor_provider_env_tokens.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_doctor_provider_local_audit_setup.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_doctor_provider_probe.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_doctor_provider_review_hygiene.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_doctor_registry.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_doctor_runtime.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_doctor_self_hosted_runner.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_doctor_supervised_pilot.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_file_locks.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_fork_pr_guard.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_gate_automerge.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_gate_health.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_hosted_dispatch_profile.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_init_actionlint.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_lane_status.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_local_llm_github_helpers.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_migration_setup_drift.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_plan_context.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_pr_outcome_contract.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_productivity_metrics_contract.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_productivity_report.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_prompts.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_provider_local_cli.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_provider_runners_comments.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_provider_runners_git.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_provider_runners_github_pr.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_provider_runners_pr_worktree.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_provider_runners_process.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_provider_runners_repo_paths.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_provider_runners_text_schema.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_provider_runners_workspace.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_release_qualify.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_reviewer_metrics_core.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_reviewer_spend.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_supervised_pilot_contract.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_trailer_comment_labeler.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/tests/test_work_orders.py +0 -0
- {code_mower-1.0.8 → code_mower-1.0.10}/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.10
|
|
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
|
|
@@ -40,8 +40,7 @@ gate.
|
|
|
40
40
|
|
|
41
41
|
The short version:
|
|
42
42
|
|
|
43
|
-
- create safe, manual-first
|
|
44
|
-
AI review tools;
|
|
43
|
+
- create safe, manual-first peer-review lanes for Codex and Claude;
|
|
45
44
|
- run setup diagnostics before a lane can surprise you with spend, source
|
|
46
45
|
exposure, or GitHub Actions churn;
|
|
47
46
|
- turn issue text, external docs, and project doctrine into local work orders
|
|
@@ -73,6 +72,18 @@ Code Mower should feel like an engineering tool, not a demo harness:
|
|
|
73
72
|
|
|
74
73
|
## What It Looks Like
|
|
75
74
|
|
|
75
|
+
Start with Claude Code and Codex, or choose your participants during setup with
|
|
76
|
+
`code-mower init --interactive`. For example, `code-mower init --with
|
|
77
|
+
claude,codex,devin` previews that selection. The generated configuration remembers
|
|
78
|
+
your choices for later sessions.
|
|
79
|
+
|
|
80
|
+
Ask the agent you are using to start a Code Mower session; that agent is the
|
|
81
|
+
default orchestrator. `code-mower session start --repo OWNER/REPO --with
|
|
82
|
+
claude,codex,devin --host codex` prepares the operating brief when invoked from
|
|
83
|
+
Codex. The host agent drives the work using available execution paths.
|
|
84
|
+
See [Participants And Sessions](docs/sessions.md) for setup, host identity,
|
|
85
|
+
and product-specific capabilities.
|
|
86
|
+
|
|
76
87
|
`code-mower doctor --adoption --repo OWNER/REPO` is the first useful command
|
|
77
88
|
for a real repository. It checks your runtime, GitHub setup, provider CLIs,
|
|
78
89
|
token posture, optional cloud setup, private-repo Actions cost traps, and
|
|
@@ -92,7 +103,7 @@ Example, shortened:
|
|
|
92
103
|
```text
|
|
93
104
|
$ code-mower doctor --adoption --repo OWNER/REPO
|
|
94
105
|
PASS config.validate config validates
|
|
95
|
-
PASS profile.select selected profile: codex, claude_audit
|
|
106
|
+
PASS profile.select selected profile: codex, claude_audit
|
|
96
107
|
PASS runtime.python Python 3.12 satisfies Code Mower requirements
|
|
97
108
|
PASS runtime.github_auth GitHub CLI auth probe succeeded
|
|
98
109
|
PASS runtime.local_cli codex codex found
|
|
@@ -205,6 +216,12 @@ Cold adopters should start with the reviewer gate, then add builders, then
|
|
|
205
216
|
measure builder experiments; provider experiments come after that base loop is
|
|
206
217
|
observable.
|
|
207
218
|
|
|
219
|
+
The initial reviewer and builder paths default to Claude + Codex. Other
|
|
220
|
+
participants require an explicit setup selection. `code-mower next-steps --repo
|
|
221
|
+
OWNER/REPO --pr NUMBER` shows setup, peer-audit requests, status, and local
|
|
222
|
+
evidence. Add `--advanced` for calibration, migration, package rehearsal, and
|
|
223
|
+
optional cloud guidance after the initial loop works.
|
|
224
|
+
|
|
208
225
|
Install first from the [Install And Bootstrap](docs/install.md) matrix: pipx for
|
|
209
226
|
laptops, uv tool installs for hosted agents or CI boxes, and an editable venv
|
|
210
227
|
for Code Mower contributors. All paths require Python 3.12 or newer. For
|
|
@@ -224,7 +241,7 @@ agent report its actual host posture, exact installed version, doctor result,
|
|
|
224
241
|
Board URL, and any owner-only click-list before it mutates the repo.
|
|
225
242
|
|
|
226
243
|
The current package-index announcement entry point is the tagged
|
|
227
|
-
[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.10/docs/try-in-10-minutes.md)
|
|
228
245
|
guide. The v1.0 supervised-pilot release includes the native Board, the
|
|
229
246
|
controller dry-run and policy contract, adoption and upgrade hardening from
|
|
230
247
|
recent install rehearsals, package-index release checks, provider-diversity
|
|
@@ -259,6 +276,15 @@ artifact, campaigns survive checkout changes, TestPyPI qualification is
|
|
|
259
276
|
closed, Cursor builder identity is distinct from Grok review, Antigravity uses
|
|
260
277
|
explicit project isolation, and hosted Cursor and Devin profiles require
|
|
261
278
|
verified dispatch and result transport.
|
|
279
|
+
The v1.0.9 patch makes Board refresh recovery deterministic, turns package
|
|
280
|
+
installation failures into bounded actionable diagnostics, and lets release
|
|
281
|
+
campaigns require established providers while retaining slower or experimental
|
|
282
|
+
providers as informational evidence.
|
|
283
|
+
The v1.0.10 patch makes local builder lanes deliverable and recoverable: a
|
|
284
|
+
provider-neutral delivery contract with bounded no-change and owner-action
|
|
285
|
+
outcomes, process-group cleanup so a finished provider is not reported as a
|
|
286
|
+
timeout, simpler first-run defaults, host-led participant sessions, and a
|
|
287
|
+
published 20-sample provider calibration scorecard.
|
|
262
288
|
Package-only users can start from the public package rather than a source
|
|
263
289
|
checkout.
|
|
264
290
|
|
|
@@ -291,7 +317,7 @@ Provider-contract baseline for the next release train:
|
|
|
291
317
|
|
|
292
318
|
For release verification,
|
|
293
319
|
[First-User Install Rehearsal](docs/first-user-install-rehearsal.md) records
|
|
294
|
-
the package-index procedure for `v1.0.
|
|
320
|
+
the package-index procedure for `v1.0.10` / `code-mower==1.0.10`. The
|
|
295
321
|
GitHub release records the workflow and rehearsal evidence for the exact tag.
|
|
296
322
|
After publication, [Release Qualification](docs/release-qualification.md)
|
|
297
323
|
coordinates provider-specific install and operational checks without treating
|
|
@@ -354,10 +380,11 @@ optional work order, single-writer branch, reviewer lanes, and fix rounds. Code
|
|
|
354
380
|
Mower's templates now support that loop end to end; humans still own
|
|
355
381
|
credentials, branch protection, calibration, and owner decisions.
|
|
356
382
|
|
|
357
|
-
The
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
383
|
+
The initial adoption shape uses Claude Code or Codex as orchestrator, builder,
|
|
384
|
+
and peer reviewer. The owning builder remains the only writer, and the other
|
|
385
|
+
provider supplies independent review. Other builders and reviewers are explicit
|
|
386
|
+
later additions; they follow the same lane policy with provider-specific
|
|
387
|
+
execution and authentication where needed.
|
|
361
388
|
|
|
362
389
|
## Why Not Just Run Codex Or Claude Yourself?
|
|
363
390
|
|
|
@@ -439,10 +466,10 @@ The first recommended lanes are local/manual:
|
|
|
439
466
|
| --- | --- | --- |
|
|
440
467
|
| Codex audit | structured local peer audit | merge-gating eligible after setup |
|
|
441
468
|
| Claude audit | structured local peer audit | merge-gating eligible after setup |
|
|
442
|
-
| Gitar | advisory third signal | informational until calibrated |
|
|
443
469
|
|
|
444
|
-
Everything else
|
|
445
|
-
proves it is useful:
|
|
470
|
+
Everything else is opt-in after the Claude + Codex loop works and stays manual
|
|
471
|
+
or informational until your own calibration data proves it is useful: Gitar,
|
|
472
|
+
Antigravity/Gemini, Muse, Hermes, CodeRabbit CLI, Cursor
|
|
446
473
|
BugBot, Qodo, Greptile, Devin, local LLMs, and future ACP bridges.
|
|
447
474
|
|
|
448
475
|
Gemini CLI and Antigravity are distinct lane ids even though both are Google
|
|
@@ -480,8 +507,8 @@ measurement work.
|
|
|
480
507
|
|
|
481
508
|
## Installation Status
|
|
482
509
|
|
|
483
|
-
The current package-index release baseline is `v1.0.
|
|
484
|
-
install spec `code-mower==1.0.
|
|
510
|
+
The current package-index release baseline is `v1.0.10`, with pinned package
|
|
511
|
+
install spec `code-mower==1.0.10`. Release evidence is recorded on the GitHub
|
|
485
512
|
release and in the first-user install rehearsal. The public repository is
|
|
486
513
|
[codemower-ai/code-mower](https://github.com/codemower-ai/code-mower), and
|
|
487
514
|
GitHub releases remain the auditable source for tags, build artifacts, and
|
|
@@ -516,8 +543,9 @@ first so local work exercises the same package entrypoint users install.
|
|
|
516
543
|
conservative and team-controlled while automated retention jobs are roadmap
|
|
517
544
|
work.
|
|
518
545
|
- Advanced/provider/operator commands remain available behind
|
|
519
|
-
`code-mower --help-all`. The default help path stays focused on
|
|
520
|
-
`
|
|
546
|
+
`code-mower --help-all`. The default help path stays focused on setup,
|
|
547
|
+
`next-steps`, lane status, and local evidence; calibration and cloud commands
|
|
548
|
+
remain available through `--help-all`.
|
|
521
549
|
|
|
522
550
|
## Docs Map
|
|
523
551
|
|
|
@@ -537,6 +565,7 @@ first so local work exercises the same package entrypoint users install.
|
|
|
537
565
|
- [Claude Lane Standing Instructions](docs/lanes/claude.md)
|
|
538
566
|
- [Cursor Hosted Lane Standing Instructions](docs/lanes/cursor.md)
|
|
539
567
|
- [Provider Matrix](docs/provider-matrix.md)
|
|
568
|
+
- [Provider Calibration Scorecard](docs/provider-calibration-scorecard.md)
|
|
540
569
|
- [GitHub Setup](docs/github-setup.md)
|
|
541
570
|
- [First Run Transcript](docs/first-run-transcript.md)
|
|
542
571
|
- [First-User Demo Transcript](docs/first-user-demo-transcript.md)
|
|
@@ -556,6 +585,8 @@ first so local work exercises the same package entrypoint users install.
|
|
|
556
585
|
- [v1.0.6 Release Notes](docs/v106-release-notes.md)
|
|
557
586
|
- [v1.0.7 Release Notes](docs/v107-release-notes.md)
|
|
558
587
|
- [v1.0.8 Release Notes](docs/v108-release-notes.md)
|
|
588
|
+
- [v1.0.9 Release Notes](docs/v109-release-notes.md)
|
|
589
|
+
- [v1.0.10 Release Notes](docs/v1010-release-notes.md)
|
|
559
590
|
- [Post-v0.8 Effectiveness Assessment](docs/post-v08-effectiveness-assessment.md)
|
|
560
591
|
- [v1.0.1 Effectiveness Assessment](docs/v101-effectiveness-assessment.md)
|
|
561
592
|
- [Demo Calibration Example](examples/demo-calibration/README.md)
|
|
@@ -10,8 +10,7 @@ gate.
|
|
|
10
10
|
|
|
11
11
|
The short version:
|
|
12
12
|
|
|
13
|
-
- create safe, manual-first
|
|
14
|
-
AI review tools;
|
|
13
|
+
- create safe, manual-first peer-review lanes for Codex and Claude;
|
|
15
14
|
- run setup diagnostics before a lane can surprise you with spend, source
|
|
16
15
|
exposure, or GitHub Actions churn;
|
|
17
16
|
- turn issue text, external docs, and project doctrine into local work orders
|
|
@@ -43,6 +42,18 @@ Code Mower should feel like an engineering tool, not a demo harness:
|
|
|
43
42
|
|
|
44
43
|
## What It Looks Like
|
|
45
44
|
|
|
45
|
+
Start with Claude Code and Codex, or choose your participants during setup with
|
|
46
|
+
`code-mower init --interactive`. For example, `code-mower init --with
|
|
47
|
+
claude,codex,devin` previews that selection. The generated configuration remembers
|
|
48
|
+
your choices for later sessions.
|
|
49
|
+
|
|
50
|
+
Ask the agent you are using to start a Code Mower session; that agent is the
|
|
51
|
+
default orchestrator. `code-mower session start --repo OWNER/REPO --with
|
|
52
|
+
claude,codex,devin --host codex` prepares the operating brief when invoked from
|
|
53
|
+
Codex. The host agent drives the work using available execution paths.
|
|
54
|
+
See [Participants And Sessions](docs/sessions.md) for setup, host identity,
|
|
55
|
+
and product-specific capabilities.
|
|
56
|
+
|
|
46
57
|
`code-mower doctor --adoption --repo OWNER/REPO` is the first useful command
|
|
47
58
|
for a real repository. It checks your runtime, GitHub setup, provider CLIs,
|
|
48
59
|
token posture, optional cloud setup, private-repo Actions cost traps, and
|
|
@@ -62,7 +73,7 @@ Example, shortened:
|
|
|
62
73
|
```text
|
|
63
74
|
$ code-mower doctor --adoption --repo OWNER/REPO
|
|
64
75
|
PASS config.validate config validates
|
|
65
|
-
PASS profile.select selected profile: codex, claude_audit
|
|
76
|
+
PASS profile.select selected profile: codex, claude_audit
|
|
66
77
|
PASS runtime.python Python 3.12 satisfies Code Mower requirements
|
|
67
78
|
PASS runtime.github_auth GitHub CLI auth probe succeeded
|
|
68
79
|
PASS runtime.local_cli codex codex found
|
|
@@ -175,6 +186,12 @@ Cold adopters should start with the reviewer gate, then add builders, then
|
|
|
175
186
|
measure builder experiments; provider experiments come after that base loop is
|
|
176
187
|
observable.
|
|
177
188
|
|
|
189
|
+
The initial reviewer and builder paths default to Claude + Codex. Other
|
|
190
|
+
participants require an explicit setup selection. `code-mower next-steps --repo
|
|
191
|
+
OWNER/REPO --pr NUMBER` shows setup, peer-audit requests, status, and local
|
|
192
|
+
evidence. Add `--advanced` for calibration, migration, package rehearsal, and
|
|
193
|
+
optional cloud guidance after the initial loop works.
|
|
194
|
+
|
|
178
195
|
Install first from the [Install And Bootstrap](docs/install.md) matrix: pipx for
|
|
179
196
|
laptops, uv tool installs for hosted agents or CI boxes, and an editable venv
|
|
180
197
|
for Code Mower contributors. All paths require Python 3.12 or newer. For
|
|
@@ -194,7 +211,7 @@ agent report its actual host posture, exact installed version, doctor result,
|
|
|
194
211
|
Board URL, and any owner-only click-list before it mutates the repo.
|
|
195
212
|
|
|
196
213
|
The current package-index announcement entry point is the tagged
|
|
197
|
-
[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.10/docs/try-in-10-minutes.md)
|
|
198
215
|
guide. The v1.0 supervised-pilot release includes the native Board, the
|
|
199
216
|
controller dry-run and policy contract, adoption and upgrade hardening from
|
|
200
217
|
recent install rehearsals, package-index release checks, provider-diversity
|
|
@@ -229,6 +246,15 @@ artifact, campaigns survive checkout changes, TestPyPI qualification is
|
|
|
229
246
|
closed, Cursor builder identity is distinct from Grok review, Antigravity uses
|
|
230
247
|
explicit project isolation, and hosted Cursor and Devin profiles require
|
|
231
248
|
verified dispatch and result transport.
|
|
249
|
+
The v1.0.9 patch makes Board refresh recovery deterministic, turns package
|
|
250
|
+
installation failures into bounded actionable diagnostics, and lets release
|
|
251
|
+
campaigns require established providers while retaining slower or experimental
|
|
252
|
+
providers as informational evidence.
|
|
253
|
+
The v1.0.10 patch makes local builder lanes deliverable and recoverable: a
|
|
254
|
+
provider-neutral delivery contract with bounded no-change and owner-action
|
|
255
|
+
outcomes, process-group cleanup so a finished provider is not reported as a
|
|
256
|
+
timeout, simpler first-run defaults, host-led participant sessions, and a
|
|
257
|
+
published 20-sample provider calibration scorecard.
|
|
232
258
|
Package-only users can start from the public package rather than a source
|
|
233
259
|
checkout.
|
|
234
260
|
|
|
@@ -261,7 +287,7 @@ Provider-contract baseline for the next release train:
|
|
|
261
287
|
|
|
262
288
|
For release verification,
|
|
263
289
|
[First-User Install Rehearsal](docs/first-user-install-rehearsal.md) records
|
|
264
|
-
the package-index procedure for `v1.0.
|
|
290
|
+
the package-index procedure for `v1.0.10` / `code-mower==1.0.10`. The
|
|
265
291
|
GitHub release records the workflow and rehearsal evidence for the exact tag.
|
|
266
292
|
After publication, [Release Qualification](docs/release-qualification.md)
|
|
267
293
|
coordinates provider-specific install and operational checks without treating
|
|
@@ -324,10 +350,11 @@ optional work order, single-writer branch, reviewer lanes, and fix rounds. Code
|
|
|
324
350
|
Mower's templates now support that loop end to end; humans still own
|
|
325
351
|
credentials, branch protection, calibration, and owner decisions.
|
|
326
352
|
|
|
327
|
-
The
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
353
|
+
The initial adoption shape uses Claude Code or Codex as orchestrator, builder,
|
|
354
|
+
and peer reviewer. The owning builder remains the only writer, and the other
|
|
355
|
+
provider supplies independent review. Other builders and reviewers are explicit
|
|
356
|
+
later additions; they follow the same lane policy with provider-specific
|
|
357
|
+
execution and authentication where needed.
|
|
331
358
|
|
|
332
359
|
## Why Not Just Run Codex Or Claude Yourself?
|
|
333
360
|
|
|
@@ -409,10 +436,10 @@ The first recommended lanes are local/manual:
|
|
|
409
436
|
| --- | --- | --- |
|
|
410
437
|
| Codex audit | structured local peer audit | merge-gating eligible after setup |
|
|
411
438
|
| Claude audit | structured local peer audit | merge-gating eligible after setup |
|
|
412
|
-
| Gitar | advisory third signal | informational until calibrated |
|
|
413
439
|
|
|
414
|
-
Everything else
|
|
415
|
-
proves it is useful:
|
|
440
|
+
Everything else is opt-in after the Claude + Codex loop works and stays manual
|
|
441
|
+
or informational until your own calibration data proves it is useful: Gitar,
|
|
442
|
+
Antigravity/Gemini, Muse, Hermes, CodeRabbit CLI, Cursor
|
|
416
443
|
BugBot, Qodo, Greptile, Devin, local LLMs, and future ACP bridges.
|
|
417
444
|
|
|
418
445
|
Gemini CLI and Antigravity are distinct lane ids even though both are Google
|
|
@@ -450,8 +477,8 @@ measurement work.
|
|
|
450
477
|
|
|
451
478
|
## Installation Status
|
|
452
479
|
|
|
453
|
-
The current package-index release baseline is `v1.0.
|
|
454
|
-
install spec `code-mower==1.0.
|
|
480
|
+
The current package-index release baseline is `v1.0.10`, with pinned package
|
|
481
|
+
install spec `code-mower==1.0.10`. Release evidence is recorded on the GitHub
|
|
455
482
|
release and in the first-user install rehearsal. The public repository is
|
|
456
483
|
[codemower-ai/code-mower](https://github.com/codemower-ai/code-mower), and
|
|
457
484
|
GitHub releases remain the auditable source for tags, build artifacts, and
|
|
@@ -486,8 +513,9 @@ first so local work exercises the same package entrypoint users install.
|
|
|
486
513
|
conservative and team-controlled while automated retention jobs are roadmap
|
|
487
514
|
work.
|
|
488
515
|
- Advanced/provider/operator commands remain available behind
|
|
489
|
-
`code-mower --help-all`. The default help path stays focused on
|
|
490
|
-
`
|
|
516
|
+
`code-mower --help-all`. The default help path stays focused on setup,
|
|
517
|
+
`next-steps`, lane status, and local evidence; calibration and cloud commands
|
|
518
|
+
remain available through `--help-all`.
|
|
491
519
|
|
|
492
520
|
## Docs Map
|
|
493
521
|
|
|
@@ -507,6 +535,7 @@ first so local work exercises the same package entrypoint users install.
|
|
|
507
535
|
- [Claude Lane Standing Instructions](docs/lanes/claude.md)
|
|
508
536
|
- [Cursor Hosted Lane Standing Instructions](docs/lanes/cursor.md)
|
|
509
537
|
- [Provider Matrix](docs/provider-matrix.md)
|
|
538
|
+
- [Provider Calibration Scorecard](docs/provider-calibration-scorecard.md)
|
|
510
539
|
- [GitHub Setup](docs/github-setup.md)
|
|
511
540
|
- [First Run Transcript](docs/first-run-transcript.md)
|
|
512
541
|
- [First-User Demo Transcript](docs/first-user-demo-transcript.md)
|
|
@@ -526,6 +555,8 @@ first so local work exercises the same package entrypoint users install.
|
|
|
526
555
|
- [v1.0.6 Release Notes](docs/v106-release-notes.md)
|
|
527
556
|
- [v1.0.7 Release Notes](docs/v107-release-notes.md)
|
|
528
557
|
- [v1.0.8 Release Notes](docs/v108-release-notes.md)
|
|
558
|
+
- [v1.0.9 Release Notes](docs/v109-release-notes.md)
|
|
559
|
+
- [v1.0.10 Release Notes](docs/v1010-release-notes.md)
|
|
529
560
|
- [Post-v0.8 Effectiveness Assessment](docs/post-v08-effectiveness-assessment.md)
|
|
530
561
|
- [v1.0.1 Effectiveness Assessment](docs/v101-effectiveness-assessment.md)
|
|
531
562
|
- [Demo Calibration Example](examples/demo-calibration/README.md)
|
|
@@ -297,6 +297,8 @@ def _format_timestamp(value: datetime) -> str:
|
|
|
297
297
|
|
|
298
298
|
STATUS_CACHE_RETRY_BASE_SECONDS = 5.0
|
|
299
299
|
STATUS_CACHE_RETRY_MAX_SECONDS = 60.0
|
|
300
|
+
STATUS_CACHE_REFRESH_TIMEOUT_SECONDS = 120.0
|
|
301
|
+
STATUS_CACHE_TIMEOUT_SECONDS = STATUS_CACHE_REFRESH_TIMEOUT_SECONDS
|
|
300
302
|
|
|
301
303
|
|
|
302
304
|
class StatusCache:
|
|
@@ -314,16 +316,20 @@ class StatusCache:
|
|
|
314
316
|
consumers can identify *which* completed snapshot they are holding
|
|
315
317
|
independently of whether that snapshot is still fresh.
|
|
316
318
|
|
|
317
|
-
A failed refresh (
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
319
|
+
A failed refresh (including abnormal thread exits or non-``Exception``
|
|
320
|
+
terminations), a dead/abandoned refresh that exceeds the recovery timeout,
|
|
321
|
+
or a failed refresh thread start opens a bounded retry backoff window.
|
|
322
|
+
Without it the cached snapshot stays stale while ``refresh_in_progress``
|
|
323
|
+
returns to false the instant the failure is recorded, so the very next
|
|
324
|
+
request would start another expensive GitHub/local recomputation -- once
|
|
325
|
+
per fast poll (~750ms) for as long as the failure persists. During the
|
|
326
|
+
window ``get()`` still answers immediately from cold/stale metadata but
|
|
327
|
+
starts nothing and reports ``refresh_in_progress`` false, so the browser
|
|
328
|
+
drops back to its normal interval. The window doubles per consecutive
|
|
329
|
+
failure from ``retry_base_seconds`` up to ``retry_max_seconds`` and is
|
|
330
|
+
cleared by the first success. Ownership tokens ensure that late-exiting or
|
|
331
|
+
abandoned threads cannot overwrite newer generations or clear the
|
|
332
|
+
in-progress flag of a replacement refresh.
|
|
327
333
|
"""
|
|
328
334
|
|
|
329
335
|
def __init__(
|
|
@@ -336,6 +342,8 @@ class StatusCache:
|
|
|
336
342
|
start_thread: Any = None,
|
|
337
343
|
retry_base_seconds: float = STATUS_CACHE_RETRY_BASE_SECONDS,
|
|
338
344
|
retry_max_seconds: float = STATUS_CACHE_RETRY_MAX_SECONDS,
|
|
345
|
+
refresh_timeout_seconds: float = STATUS_CACHE_REFRESH_TIMEOUT_SECONDS,
|
|
346
|
+
timeout_seconds: float | None = None,
|
|
339
347
|
) -> None:
|
|
340
348
|
self._compute = compute
|
|
341
349
|
self._ttl_seconds = max(float(ttl_seconds), 0.0)
|
|
@@ -344,11 +352,16 @@ class StatusCache:
|
|
|
344
352
|
self._start_thread = start_thread or self._default_start_thread
|
|
345
353
|
self._retry_base_seconds = max(float(retry_base_seconds), 0.0)
|
|
346
354
|
self._retry_max_seconds = max(float(retry_max_seconds), self._retry_base_seconds)
|
|
355
|
+
if timeout_seconds is not None:
|
|
356
|
+
refresh_timeout_seconds = timeout_seconds
|
|
357
|
+
self._refresh_timeout_seconds = max(float(refresh_timeout_seconds), 0.0)
|
|
347
358
|
self._lock = Lock()
|
|
348
359
|
self._snapshot: dict[str, Any] | None = None
|
|
349
360
|
self._computed_at: datetime | None = None
|
|
350
361
|
self._computed_monotonic: float | None = None
|
|
351
362
|
self._refreshing = False
|
|
363
|
+
self._refresh_started_monotonic: float | None = None
|
|
364
|
+
self._refresh_owner = 0
|
|
352
365
|
self._generation = 0
|
|
353
366
|
self._last_error: str = ""
|
|
354
367
|
self._last_error_at: datetime | None = None
|
|
@@ -403,6 +416,8 @@ class StatusCache:
|
|
|
403
416
|
so nothing here can leak paths, output, or credentials.
|
|
404
417
|
"""
|
|
405
418
|
self._refreshing = False
|
|
419
|
+
self._refresh_started_monotonic = None
|
|
420
|
+
self._refresh_owner += 1
|
|
406
421
|
self._last_error = _cache_error_summary(exc)
|
|
407
422
|
self._last_error_at = self._now()
|
|
408
423
|
self._consecutive_failures += 1
|
|
@@ -418,6 +433,13 @@ class StatusCache:
|
|
|
418
433
|
else None
|
|
419
434
|
)
|
|
420
435
|
is_stale = snapshot is None or age is None or age >= self._ttl_seconds
|
|
436
|
+
if (
|
|
437
|
+
self._refreshing
|
|
438
|
+
and self._refresh_started_monotonic is not None
|
|
439
|
+
and self._refresh_timeout_seconds > 0.0
|
|
440
|
+
and max(elapsed - self._refresh_started_monotonic, 0.0) >= self._refresh_timeout_seconds
|
|
441
|
+
):
|
|
442
|
+
self._record_failure_locked(TimeoutError("status refresh timed out"))
|
|
421
443
|
retry_in = (
|
|
422
444
|
max(self._retry_after_monotonic - elapsed, 0.0)
|
|
423
445
|
if self._retry_after_monotonic is not None
|
|
@@ -425,8 +447,12 @@ class StatusCache:
|
|
|
425
447
|
)
|
|
426
448
|
in_backoff = retry_in > 0.0
|
|
427
449
|
should_start = is_stale and not self._refreshing and not in_backoff
|
|
450
|
+
owner: int | None = None
|
|
428
451
|
if should_start:
|
|
429
452
|
self._refreshing = True
|
|
453
|
+
self._refresh_owner += 1
|
|
454
|
+
owner = self._refresh_owner
|
|
455
|
+
self._refresh_started_monotonic = elapsed
|
|
430
456
|
self._retry_after_monotonic = None
|
|
431
457
|
metadata_snapshot = {
|
|
432
458
|
"state": "cold" if snapshot is None else ("stale" if is_stale else "fresh"),
|
|
@@ -439,35 +465,54 @@ class StatusCache:
|
|
|
439
465
|
"last_error": self._last_error,
|
|
440
466
|
"last_error_at": _format_timestamp(self._last_error_at) if self._last_error_at else "",
|
|
441
467
|
}
|
|
442
|
-
if should_start:
|
|
468
|
+
if should_start and owner is not None:
|
|
469
|
+
def refresh_worker() -> None:
|
|
470
|
+
self._refresh(owner)
|
|
471
|
+
|
|
443
472
|
try:
|
|
444
|
-
self._start_thread(
|
|
445
|
-
except Exception as exc: # noqa: BLE001 - a failed thread start must never crash the endpoint
|
|
473
|
+
self._start_thread(refresh_worker)
|
|
474
|
+
except (Exception, SystemExit) as exc: # noqa: BLE001 - a failed thread start must never crash the endpoint
|
|
446
475
|
with self._lock:
|
|
447
|
-
self.
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
476
|
+
if self._refresh_owner == owner:
|
|
477
|
+
self._record_failure_locked(exc)
|
|
478
|
+
metadata_snapshot["refresh_in_progress"] = False
|
|
479
|
+
metadata_snapshot["retry_in_seconds"] = round(self._retry_delay_locked(), 3)
|
|
480
|
+
metadata_snapshot["last_error"] = self._last_error
|
|
481
|
+
metadata_snapshot["last_error_at"] = _format_timestamp(self._last_error_at)
|
|
452
482
|
return snapshot, metadata_snapshot
|
|
453
483
|
|
|
454
|
-
def _refresh(self) -> None:
|
|
484
|
+
def _refresh(self, owner: int | None = None) -> None:
|
|
485
|
+
if owner is None:
|
|
486
|
+
with self._lock:
|
|
487
|
+
owner = self._refresh_owner
|
|
488
|
+
completed = False
|
|
455
489
|
try:
|
|
456
490
|
result = self._compute()
|
|
457
|
-
except Exception as exc: # noqa: BLE001 - a background refresh must never crash the server
|
|
458
491
|
with self._lock:
|
|
459
|
-
self.
|
|
492
|
+
if self._refresh_owner == owner:
|
|
493
|
+
self._snapshot = result
|
|
494
|
+
self._computed_at = self._now()
|
|
495
|
+
self._computed_monotonic = self._clock()
|
|
496
|
+
self._generation += 1
|
|
497
|
+
self._refreshing = False
|
|
498
|
+
self._refresh_started_monotonic = None
|
|
499
|
+
self._last_error = ""
|
|
500
|
+
self._last_error_at = None
|
|
501
|
+
self._consecutive_failures = 0
|
|
502
|
+
self._retry_after_monotonic = None
|
|
503
|
+
self._refresh_owner += 1
|
|
504
|
+
completed = True
|
|
505
|
+
except BaseException as exc: # noqa: BLE001 - a background refresh must never crash the server
|
|
506
|
+
with self._lock:
|
|
507
|
+
if self._refresh_owner == owner:
|
|
508
|
+
self._record_failure_locked(exc)
|
|
509
|
+
completed = True
|
|
460
510
|
return
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
self._refreshing = False
|
|
467
|
-
self._last_error = ""
|
|
468
|
-
self._last_error_at = None
|
|
469
|
-
self._consecutive_failures = 0
|
|
470
|
-
self._retry_after_monotonic = None
|
|
511
|
+
finally:
|
|
512
|
+
if not completed:
|
|
513
|
+
with self._lock:
|
|
514
|
+
if self._refresh_owner == owner and self._refreshing:
|
|
515
|
+
self._record_failure_locked(RuntimeError("refresh thread exited abnormally"))
|
|
471
516
|
|
|
472
517
|
|
|
473
518
|
def _pending_status_payload(config: BoardConfig) -> dict[str, Any]:
|
|
@@ -1370,7 +1415,7 @@ def render_board_html(config: BoardConfig) -> str:
|
|
|
1370
1415
|
const campaigns = campaignsData.campaigns || [];
|
|
1371
1416
|
const campaignRows = campaigns.flatMap(c => {{
|
|
1372
1417
|
const header = `<div class="row"><div class="line"><b>Release ${{esc(c.release_tag)}}</b>${{pill(c.status)}}${{c.dry_run ? pill("dry-run") : pill("applied")}}${{pill(c.qualification_context)}}<span>${{seconds(c.elapsed_seconds)}}</span></div><div>next: <b>${{esc(c.next_action)}}</b></div></div>`;
|
|
1373
|
-
const cardRows = (c.cards || []).map(card => `<div class="row" style="margin-left:16px"><div class="line"><b>${{esc(card.provider)}}</b
|
|
1418
|
+
const cardRows = (c.cards || []).map(card => `<div class="row" style="margin-left:16px"><div class="line"><b>${{esc(card.provider)}}</b>${{pill(card.posture || "required")}}<span class="${{stateClass(card.state)}}">${{esc(card.state)}}</span>${{pill(card.environment)}}${{card.transport_verified === false ? pill("transport unverified") : ""}}<span>${{seconds(card.elapsed_seconds)}}</span></div><div>next: <b>${{esc(card.next_action)}}</b></div>${{card.next_detail ? `<div class="muted">${{esc(card.next_detail)}}</div>` : ""}}${{card.response_deadline_at ? `<div class="muted" title="${{esc(card.response_deadline_at)}}">response deadline ${{localTime(card.response_deadline_at)}}</div>` : ""}}</div>`);
|
|
1374
1419
|
return [header, ...cardRows];
|
|
1375
1420
|
}}).join("");
|
|
1376
1421
|
put("campaigns", campaignRows || empty(campaignsData.message || "No release campaigns."));
|
|
@@ -1815,14 +1860,16 @@ def make_handler(
|
|
|
1815
1860
|
*,
|
|
1816
1861
|
gh_json_runner: lane_status.GitHubJsonRunner = lane_status.run_gh_json,
|
|
1817
1862
|
command_runner: lane_status.CommandRunner = lane_status.run_command,
|
|
1863
|
+
status_cache: StatusCache | None = None,
|
|
1818
1864
|
) -> type[BaseHTTPRequestHandler]:
|
|
1819
1865
|
last_recorded_at: datetime | None = None
|
|
1820
1866
|
last_recorded_generation = 0
|
|
1821
1867
|
recording_lock = Lock()
|
|
1822
|
-
status_cache
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1868
|
+
if status_cache is None:
|
|
1869
|
+
status_cache = StatusCache(
|
|
1870
|
+
lambda: status_payload(config, gh_json_runner=gh_json_runner, command_runner=command_runner),
|
|
1871
|
+
ttl_seconds=config.refresh_seconds,
|
|
1872
|
+
)
|
|
1826
1873
|
|
|
1827
1874
|
class BoardHandler(BaseHTTPRequestHandler):
|
|
1828
1875
|
server_version = "CodeMowerBoard/0.1"
|
|
@@ -39,6 +39,8 @@ AUTHOR_INFERENCE_RULES = {
|
|
|
39
39
|
"claude-bot": ("claude", "claude_code_action"),
|
|
40
40
|
"cursor[bot]": ("cursor_cloud_agent", "cursor_cloud_agent"),
|
|
41
41
|
"cursor": ("cursor_cloud_agent", "cursor_cloud_agent"),
|
|
42
|
+
"devin-ai-integration": ("devin", "devin"),
|
|
43
|
+
"devin-ai-integration[bot]": ("devin", "devin"),
|
|
42
44
|
}
|
|
43
45
|
BRANCH_PREFIX_INFERENCE_RULES = (
|
|
44
46
|
("cursor/", "cursor_cloud_agent", "cursor_cloud_agent"),
|
|
@@ -49,6 +51,8 @@ BRANCH_PREFIX_INFERENCE_RULES = (
|
|
|
49
51
|
("chatgpt-codex-", "codex", "chatgpt-codex-connector"),
|
|
50
52
|
("claude/", "claude", "claude_code_action"),
|
|
51
53
|
("claude-", "claude", "claude_code_action"),
|
|
54
|
+
("devin/", "devin_cli", "devin_cli"),
|
|
55
|
+
("devin-", "devin_cli", "devin_cli"),
|
|
52
56
|
)
|
|
53
57
|
|
|
54
58
|
|