code-mower 0.8.0b1__tar.gz → 0.9.0b1__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-0.8.0b1 → code_mower-0.9.0b1}/PKG-INFO +24 -11
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/README.md +23 -10
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/pyproject.toml +1 -1
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/__init__.py +1 -1
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/board.py +79 -19
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/cli.py +2 -1
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor.py +41 -1
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/adoption.py +20 -12
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/common.py +2 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/github.py +2 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/github_human_token.py +39 -7
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/provider_review_hygiene.py +53 -30
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/providers.py +9 -4
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/runner.py +3 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/self_hosted_runner.py +0 -3
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/lane_status.py +21 -5
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/migration.py +351 -1
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/migration_install.py +22 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/migration_rehearsal.py +30 -7
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/next_steps.py +4 -4
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/package_content.py +1 -1
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/release_readiness.py +3 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/workflows/builder-provenance.yml.j2 +1 -1
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower.egg-info/PKG-INFO +24 -11
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower.egg-info/SOURCES.txt +1 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/workflows/builder-provenance.yml.j2 +1 -1
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_board.py +80 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_doctor_github_checks.py +30 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_doctor_provider_review_hygiene.py +4 -6
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_doctor_registry.py +45 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_doctor_self_hosted_runner.py +31 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_lane_status.py +22 -0
- code_mower-0.9.0b1/tests/test_migration_setup_drift.py +82 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_release_hygiene.py +199 -39
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/CODE_OF_CONDUCT.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/LICENSE +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/MANIFEST.in +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/NOTICE +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/SUPPORT.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/requirements/requirements.txt +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/setup.cfg +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/adapters/__init__.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/adapters/_base.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/adapters/cursor_bugbot.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/adapters/gitar.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/adapters/greptile.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/adapters/qodo.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/antigravity_cli_audit_pr.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/antigravity_sdk_probe.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/audit_handoff_log.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/audit_labeler_lib.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/audit_limits.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/audit_progress.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/blind_review_artifacts.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/blind_review_coordinator.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/board_store.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/bootstrap.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/builder_experiment.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/builder_runs.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/calibration/__init__.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/calibration/arms.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/calibration/auto_discovery.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/calibration/commands.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/calibration/context_inputs.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/calibration/corpus.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/calibration/effect_report.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/calibration/evidence.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/calibration/evidence_report.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/calibration/identity.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/calibration/metrics.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/calibration/overlap.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/calibration/planning.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/calibration/policy.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/calibration/results.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/calibration/run_results.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/calibration/run_status.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/calibration/runner.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/calibration/truth.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/calibration/value_report.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/checks.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/claude_audit_pr.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/claude_cli_bounce.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/claude_cli_environment.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/clear_stale.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/cloud.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/cloud_client/__init__.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/cloud_client/bundle.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/cloud_client/doctor.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/cloud_client/dogfood.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/cloud_client/endpoints.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/cloud_client/errors.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/cloud_client/events.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/cloud_client/export.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/cloud_client/git_metadata.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/cloud_client/manifest.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/cloud_client/operations.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/cloud_client/reports.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/cloud_client/setup.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/cloud_client/tokens.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/cloud_client/upload.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/code_mower_calibration.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/code_mower_context_packs.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/code_mower_merge.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/code_mower_telemetry.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/coderabbit_cli_audit_pr.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/codex_audit_env_preflight.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/codex_audit_pr.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/codex_audit_schema_smoke.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/codex_audit_verdict.schema.json +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/config.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/decisions.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/__init__.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/audit_limits.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/cloud.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/github_actions.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/github_actions_cost.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/github_actions_cost_summary.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/github_actions_failure_annotations.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/github_actions_failure_models.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/github_actions_failure_scan.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/github_actions_failure_selection.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/github_actions_failures.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/github_actions_permissions.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/github_api.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/github_branch.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/github_config.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/github_provider.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/github_repo.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/groups.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/models.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/output.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/presets.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/privacy.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/provider_api_model.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/provider_api_model_openai.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/provider_api_model_profiles.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/provider_env.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/provider_env_required.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/provider_env_tokens.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/provider_local_audit_setup.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/provider_local_cli.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/provider_local_cli_commands.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/provider_local_cli_probe_config.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/provider_probe.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/provider_probe_auth.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/provider_probe_evaluation.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/provider_probe_json.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/provider_probe_remediation.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/registry.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/runtime.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/runtime_github_auth.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/gate_health.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/gemini_cli_audit_pr.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/git_identity.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/grok_build_audit_pr.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/hermes_cli_audit_pr.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/init.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/lane_configs/__init__.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/lane_configs/aider.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/lane_configs/antigravity_cli.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/lane_configs/claude.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/lane_configs/codex.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/lane_configs/devin.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/lane_configs/gemini_cli.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/lane_configs/grok_build.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/lane_configs/hermes_cli.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/lane_configs/local_llm.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/local_llm_audit_pr.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/local_llm_bakeoff.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/local_llm_calibration.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/local_llm_profiles.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/migration_mirror.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/migration_readiness.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/observe.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/package.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/package_manifest.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/package_paths.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/package_rendering.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/package_static.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/plan_context.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/prompts.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/provider_registry.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/provider_runners/__init__.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/provider_runners/comments.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/provider_runners/exit_codes.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/provider_runners/git.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/provider_runners/github_auth.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/provider_runners/github_pr.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/provider_runners/pr_worktree.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/provider_runners/process.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/provider_runners/repo_paths.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/provider_runners/text_schema.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/provider_runners/verdict_artifacts.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/provider_runners/workspace.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/providers/__init__.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/providers/local_cli.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/providers/provenance.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/reviewer_metrics.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/reviewer_spend.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/saas_reviewer_labeler.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/secrets.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/builder-experiment.example.json +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/calibration-corpus.example.json +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/calibration-corpus.json +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/code-mower.example.yml +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/context-packs.example.json +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/lane_prompts/base-audit.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/lane_prompts/calibration-policy.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/lane_prompts/context-driven-quality.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/lane_prompts/docs-design.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/lane_prompts/generic-programming.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/lane_prompts/operability.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/lane_prompts/package-runtime.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/lane_prompts/plan-conformance.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/lane_prompts/security-threat-model.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/lanes/README.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/lanes/claude.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/lanes/codex.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/lanes/cursor.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/lanes/generic.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/lanes/run_mac_lane.sh +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/product-support/code_mower +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/product-support/code_mower_standalone_pin.env +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/product-support/code_mower_standalone_shadow.sh +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/product-support/run_claude_audit_pr.sh +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/product-support/run_codex_audit_pr.sh +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/product-support/safe_gh_comment.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/product-support/status_report.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/providers.yml +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/reviewer-spend.example.json +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/reviewer-value-report.example.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/workflows/audit-label-cleanup.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/workflows/code-mower-agent-pr-labeler.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/workflows/code-mower-fix-round-dispatch.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/workflows/code-mower-gate-health.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/workflows/code-mower-gate.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/workflows/dispatch-lanes.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/workflows/hosted-bridge.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/workflows/lane-mac-runner.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/workflows/local-cli-audit.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/workflows/needs-owner-notify.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/workflows/private-standalone-shadow.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/workflows/review-clear-stale.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/workflows/saas-reviewer-labeler.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/workflows/self-hosted-local-audit.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/workflows/trailer-comment-labeler.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/templates/workflows/weekly-status.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/trailer_comment_labeler.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/versioning.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/work_orders.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/workflow_actionlint.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower.egg-info/dependency_links.txt +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower.egg-info/entry_points.txt +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower.egg-info/requires.txt +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower.egg-info/top_level.txt +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/builder-experiment.example.json +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/calibration-corpus.example.json +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/calibration-corpus.json +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/code-mower.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/context-packs.example.json +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/cursor/BUGBOT.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/lanes/README.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/lanes/claude.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/lanes/codex.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/lanes/cursor.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/lanes/generic.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/lanes/run_mac_lane.sh +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/providers/acp_bridge.yml +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/providers/aider.yml +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/providers/antigravity_cli.yml +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/providers/claude_audit.yml +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/providers/claude_review.yml +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/providers/coderabbit_cli.yml +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/providers/codex.yml +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/providers/cursor_bugbot.yml +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/providers/devin.yml +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/providers/gemini_cli.yml +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/providers/gitar.yml +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/providers/greptile.yml +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/providers/hermes_cli.yml +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/providers/local_llm.yml +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/providers/qodo.yml +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/providers.yml +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/reviewer-spend.example.json +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/reviewer-value-report.example.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/workflows/audit-label-cleanup.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/workflows/blind-review-artifacts-dry-run.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/workflows/code-mower-agent-pr-labeler.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/workflows/code-mower-fix-round-dispatch.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/workflows/code-mower-gate-health.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/workflows/code-mower-gate.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/workflows/dispatch-lanes.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/workflows/hosted-bridge.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/workflows/lane-mac-runner.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/workflows/local-cli-audit.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/workflows/private-standalone-shadow.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/workflows/review-clear-stale.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/workflows/saas-reviewer-labeler.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/workflows/self-hosted-local-audit.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/templates/workflows/trailer-comment-labeler.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_antigravity_sdk_probe.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_audit_comment_posture.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_audit_limits.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_builder_experiment.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_builder_identity.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_builder_runs.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_calibration_effect_report.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_calibration_truth.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_checks.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_claude_audit_pr.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_claude_cli_bounce.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_clear_stale.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_cloud_client.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_cloud_git_metadata.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_cloud_manifest.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_cloud_reports.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_coderabbit_cli_audit_pr.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_codex_audit_env_preflight.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_codex_audit_pr.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_decision_audit_integration.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_decisions.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_doctor_actions_cost_summary.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_doctor_actions_failure_selection.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_doctor_boundaries.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_doctor_output.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_doctor_privacy.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_doctor_provider_env_required.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_doctor_provider_env_tokens.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_doctor_provider_local_audit_setup.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_doctor_provider_probe.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_doctor_runtime.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_gate_health.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_init_actionlint.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_init_build_loop.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_local_llm_github_helpers.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_observe.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_plan_context.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_prompts.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_provider_fixture_contracts.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_provider_local_cli.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_provider_runners_comments.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_provider_runners_git.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_provider_runners_github_pr.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_provider_runners_pr_worktree.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_provider_runners_process.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_provider_runners_repo_paths.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_provider_runners_text_schema.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_provider_runners_workspace.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_reviewer_metrics_core.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_reviewer_spend.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_trailer_comment_labeler.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.0b1}/tests/test_work_orders.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: code-mower
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.9.0b1
|
|
4
4
|
Summary: Multi-reviewer AI code audit orchestration
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
Requires-Python: >=3.12
|
|
@@ -64,6 +64,8 @@ for a real repository. It checks your runtime, GitHub setup, provider CLIs,
|
|
|
64
64
|
token posture, optional cloud setup, private-repo Actions cost traps, and
|
|
65
65
|
first-run adoption gaps. `--preflight` remains the compatibility preset for
|
|
66
66
|
older scripts; `--adoption` adds explicit repo targeting and setup guidance.
|
|
67
|
+
Use `--hosted-builders` or `--orchestrator-only` when the current machine is
|
|
68
|
+
observing/coordinating lanes and will not run local Codex or Claude wrappers.
|
|
67
69
|
|
|
68
70
|
Example, shortened:
|
|
69
71
|
|
|
@@ -88,6 +90,12 @@ boundaries visible before you promote any reviewer lane.
|
|
|
88
90
|
|
|
89
91
|
See a fuller static transcript: [docs/first-run-transcript.md](docs/first-run-transcript.md).
|
|
90
92
|
|
|
93
|
+
For an existing repository that already has Code Mower generated workflows or
|
|
94
|
+
wrappers, run `code-mower migration setup-drift --repo-path .` before copying a
|
|
95
|
+
fresh `.code-mower.generated` tree. It is read-only and reports path-level
|
|
96
|
+
classifications (`same`, `differs`, `new`, `repo-only`,
|
|
97
|
+
`missing-from-output`) without file contents or diffs.
|
|
98
|
+
|
|
91
99
|
After `init` and `doctor`, use `code-mower lanes status --repo OWNER/REPO` to
|
|
92
100
|
see active builder/reviewer lanes, gate/check state, recent Code Mower
|
|
93
101
|
workflows, local board/process hints when present, and the next operator
|
|
@@ -96,8 +104,10 @@ action. Text and JSON output redact local cwd paths by default; use
|
|
|
96
104
|
|
|
97
105
|
For the same redacted metadata in a local browser view, run
|
|
98
106
|
`code-mower board serve --repo OWNER/REPO` and open the printed localhost URL.
|
|
99
|
-
Plain `board serve` is read-only.
|
|
100
|
-
|
|
107
|
+
Plain `board serve` is read-only. If the default Board port is busy, the CLI
|
|
108
|
+
uses a nearby free loopback port and prints the URL; an explicit `--port` stays
|
|
109
|
+
strict and reports a friendly conflict. To build local history while the browser
|
|
110
|
+
view is open, run `code-mower board serve --repo OWNER/REPO --record-events`; it
|
|
101
111
|
records at most one snapshot every 60 seconds by default. To append one snapshot
|
|
102
112
|
without serving the browser view, run
|
|
103
113
|
`code-mower board record --repo OWNER/REPO` from the repository checkout; it
|
|
@@ -143,7 +153,9 @@ observable.
|
|
|
143
153
|
|
|
144
154
|
Install first from the [Install And Bootstrap](docs/install.md) matrix: pipx for
|
|
145
155
|
laptops, uv tool installs for hosted agents or CI boxes, and an editable venv
|
|
146
|
-
for Code Mower contributors. All paths require Python 3.12 or newer.
|
|
156
|
+
for Code Mower contributors. All paths require Python 3.12 or newer. For
|
|
157
|
+
upgrades, record `command -v code-mower` and `code-mower --version` before and
|
|
158
|
+
after reinstalling, especially when switching between pipx and uv.
|
|
147
159
|
|
|
148
160
|
| Path | Use When | Route | Guide |
|
|
149
161
|
| --- | --- | --- | --- |
|
|
@@ -152,10 +164,10 @@ for Code Mower contributors. All paths require Python 3.12 or newer.
|
|
|
152
164
|
| C. Builder experiment | You want to compare authoring loops before trusting them broadly. | Use a work order or experiment spec, run `code-mower builder-experiment run` around an explicit command, then review the source-free `authoringRun` artifact and normal audit evidence. | [Builder Experiments](docs/builder-experiments.md) |
|
|
153
165
|
|
|
154
166
|
The current package-index announcement entry point is the tagged
|
|
155
|
-
[Try Code Mower In 10 Minutes](https://github.com/codemower-ai/code-mower/blob/v0.
|
|
156
|
-
guide. The v0.
|
|
157
|
-
|
|
158
|
-
source checkout.
|
|
167
|
+
[Try Code Mower In 10 Minutes](https://github.com/codemower-ai/code-mower/blob/v0.9.0-beta.1/docs/try-in-10-minutes.md)
|
|
168
|
+
guide. The v0.9 beta includes the completed native Board work plus the adoption
|
|
169
|
+
and upgrade hardening from recent install rehearsals, so package-only users can
|
|
170
|
+
start from the public package rather than a source checkout.
|
|
159
171
|
|
|
160
172
|
## What Calibration Does And Does Not Prove
|
|
161
173
|
|
|
@@ -184,7 +196,7 @@ Provider-contract baseline for the next release train:
|
|
|
184
196
|
|
|
185
197
|
For release verification,
|
|
186
198
|
[First-User Install Rehearsal](docs/first-user-install-rehearsal.md) records
|
|
187
|
-
the package-index procedure for `v0.
|
|
199
|
+
the package-index procedure for `v0.9.0-beta.1` / `code-mower==0.9.0b1`. The
|
|
188
200
|
GitHub release records the workflow and rehearsal evidence for the exact tag.
|
|
189
201
|
|
|
190
202
|
## Optional: Plan Before Coding
|
|
@@ -370,8 +382,8 @@ measurement work.
|
|
|
370
382
|
|
|
371
383
|
## Installation Status
|
|
372
384
|
|
|
373
|
-
The current package-index beta baseline is `v0.
|
|
374
|
-
install spec `code-mower==0.
|
|
385
|
+
The current package-index beta baseline is `v0.9.0-beta.1`, with pinned package
|
|
386
|
+
install spec `code-mower==0.9.0b1`. Release evidence is recorded on the GitHub
|
|
375
387
|
release and in the first-user install rehearsal. The public repository is
|
|
376
388
|
[codemower-ai/code-mower](https://github.com/codemower-ai/code-mower), and
|
|
377
389
|
GitHub releases remain the auditable source for tags, build artifacts, and
|
|
@@ -434,6 +446,7 @@ first so local work exercises the same package entrypoint users install.
|
|
|
434
446
|
- [v0.6 Truth Baseline](docs/v06-truth-baseline.md)
|
|
435
447
|
- [v0.6 Release Notes](docs/v06-release-notes.md)
|
|
436
448
|
- [v0.8 Release Notes](docs/v08-release-notes.md)
|
|
449
|
+
- [v0.9 Release Notes](docs/v09-release-notes.md)
|
|
437
450
|
- [Post-v0.8 Effectiveness Assessment](docs/post-v08-effectiveness-assessment.md)
|
|
438
451
|
- [Demo Calibration Example](examples/demo-calibration/README.md)
|
|
439
452
|
- [Board Demo Rehearsal](examples/board-demo/README.md)
|
|
@@ -47,6 +47,8 @@ for a real repository. It checks your runtime, GitHub setup, provider CLIs,
|
|
|
47
47
|
token posture, optional cloud setup, private-repo Actions cost traps, and
|
|
48
48
|
first-run adoption gaps. `--preflight` remains the compatibility preset for
|
|
49
49
|
older scripts; `--adoption` adds explicit repo targeting and setup guidance.
|
|
50
|
+
Use `--hosted-builders` or `--orchestrator-only` when the current machine is
|
|
51
|
+
observing/coordinating lanes and will not run local Codex or Claude wrappers.
|
|
50
52
|
|
|
51
53
|
Example, shortened:
|
|
52
54
|
|
|
@@ -71,6 +73,12 @@ boundaries visible before you promote any reviewer lane.
|
|
|
71
73
|
|
|
72
74
|
See a fuller static transcript: [docs/first-run-transcript.md](docs/first-run-transcript.md).
|
|
73
75
|
|
|
76
|
+
For an existing repository that already has Code Mower generated workflows or
|
|
77
|
+
wrappers, run `code-mower migration setup-drift --repo-path .` before copying a
|
|
78
|
+
fresh `.code-mower.generated` tree. It is read-only and reports path-level
|
|
79
|
+
classifications (`same`, `differs`, `new`, `repo-only`,
|
|
80
|
+
`missing-from-output`) without file contents or diffs.
|
|
81
|
+
|
|
74
82
|
After `init` and `doctor`, use `code-mower lanes status --repo OWNER/REPO` to
|
|
75
83
|
see active builder/reviewer lanes, gate/check state, recent Code Mower
|
|
76
84
|
workflows, local board/process hints when present, and the next operator
|
|
@@ -79,8 +87,10 @@ action. Text and JSON output redact local cwd paths by default; use
|
|
|
79
87
|
|
|
80
88
|
For the same redacted metadata in a local browser view, run
|
|
81
89
|
`code-mower board serve --repo OWNER/REPO` and open the printed localhost URL.
|
|
82
|
-
Plain `board serve` is read-only.
|
|
83
|
-
|
|
90
|
+
Plain `board serve` is read-only. If the default Board port is busy, the CLI
|
|
91
|
+
uses a nearby free loopback port and prints the URL; an explicit `--port` stays
|
|
92
|
+
strict and reports a friendly conflict. To build local history while the browser
|
|
93
|
+
view is open, run `code-mower board serve --repo OWNER/REPO --record-events`; it
|
|
84
94
|
records at most one snapshot every 60 seconds by default. To append one snapshot
|
|
85
95
|
without serving the browser view, run
|
|
86
96
|
`code-mower board record --repo OWNER/REPO` from the repository checkout; it
|
|
@@ -126,7 +136,9 @@ observable.
|
|
|
126
136
|
|
|
127
137
|
Install first from the [Install And Bootstrap](docs/install.md) matrix: pipx for
|
|
128
138
|
laptops, uv tool installs for hosted agents or CI boxes, and an editable venv
|
|
129
|
-
for Code Mower contributors. All paths require Python 3.12 or newer.
|
|
139
|
+
for Code Mower contributors. All paths require Python 3.12 or newer. For
|
|
140
|
+
upgrades, record `command -v code-mower` and `code-mower --version` before and
|
|
141
|
+
after reinstalling, especially when switching between pipx and uv.
|
|
130
142
|
|
|
131
143
|
| Path | Use When | Route | Guide |
|
|
132
144
|
| --- | --- | --- | --- |
|
|
@@ -135,10 +147,10 @@ for Code Mower contributors. All paths require Python 3.12 or newer.
|
|
|
135
147
|
| C. Builder experiment | You want to compare authoring loops before trusting them broadly. | Use a work order or experiment spec, run `code-mower builder-experiment run` around an explicit command, then review the source-free `authoringRun` artifact and normal audit evidence. | [Builder Experiments](docs/builder-experiments.md) |
|
|
136
148
|
|
|
137
149
|
The current package-index announcement entry point is the tagged
|
|
138
|
-
[Try Code Mower In 10 Minutes](https://github.com/codemower-ai/code-mower/blob/v0.
|
|
139
|
-
guide. The v0.
|
|
140
|
-
|
|
141
|
-
source checkout.
|
|
150
|
+
[Try Code Mower In 10 Minutes](https://github.com/codemower-ai/code-mower/blob/v0.9.0-beta.1/docs/try-in-10-minutes.md)
|
|
151
|
+
guide. The v0.9 beta includes the completed native Board work plus the adoption
|
|
152
|
+
and upgrade hardening from recent install rehearsals, so package-only users can
|
|
153
|
+
start from the public package rather than a source checkout.
|
|
142
154
|
|
|
143
155
|
## What Calibration Does And Does Not Prove
|
|
144
156
|
|
|
@@ -167,7 +179,7 @@ Provider-contract baseline for the next release train:
|
|
|
167
179
|
|
|
168
180
|
For release verification,
|
|
169
181
|
[First-User Install Rehearsal](docs/first-user-install-rehearsal.md) records
|
|
170
|
-
the package-index procedure for `v0.
|
|
182
|
+
the package-index procedure for `v0.9.0-beta.1` / `code-mower==0.9.0b1`. The
|
|
171
183
|
GitHub release records the workflow and rehearsal evidence for the exact tag.
|
|
172
184
|
|
|
173
185
|
## Optional: Plan Before Coding
|
|
@@ -353,8 +365,8 @@ measurement work.
|
|
|
353
365
|
|
|
354
366
|
## Installation Status
|
|
355
367
|
|
|
356
|
-
The current package-index beta baseline is `v0.
|
|
357
|
-
install spec `code-mower==0.
|
|
368
|
+
The current package-index beta baseline is `v0.9.0-beta.1`, with pinned package
|
|
369
|
+
install spec `code-mower==0.9.0b1`. Release evidence is recorded on the GitHub
|
|
358
370
|
release and in the first-user install rehearsal. The public repository is
|
|
359
371
|
[codemower-ai/code-mower](https://github.com/codemower-ai/code-mower), and
|
|
360
372
|
GitHub releases remain the auditable source for tags, build artifacts, and
|
|
@@ -417,6 +429,7 @@ first so local work exercises the same package entrypoint users install.
|
|
|
417
429
|
- [v0.6 Truth Baseline](docs/v06-truth-baseline.md)
|
|
418
430
|
- [v0.6 Release Notes](docs/v06-release-notes.md)
|
|
419
431
|
- [v0.8 Release Notes](docs/v08-release-notes.md)
|
|
432
|
+
- [v0.9 Release Notes](docs/v09-release-notes.md)
|
|
420
433
|
- [Post-v0.8 Effectiveness Assessment](docs/post-v08-effectiveness-assessment.md)
|
|
421
434
|
- [Demo Calibration Example](examples/demo-calibration/README.md)
|
|
422
435
|
- [Board Demo Rehearsal](examples/board-demo/README.md)
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
from __future__ import annotations
|
|
5
5
|
|
|
6
6
|
import argparse
|
|
7
|
+
import errno
|
|
7
8
|
import json
|
|
8
9
|
import re
|
|
9
10
|
import socket
|
|
@@ -41,6 +42,7 @@ class BoardConfig:
|
|
|
41
42
|
repo: str
|
|
42
43
|
host: str = DEFAULT_HOST
|
|
43
44
|
port: int = DEFAULT_PORT
|
|
45
|
+
port_was_default: bool = True
|
|
44
46
|
pr_limit: int = 50
|
|
45
47
|
workflow_limit: int = 20
|
|
46
48
|
stale_minutes: int = 30
|
|
@@ -111,6 +113,46 @@ def _server_url(host: str, port: int) -> str:
|
|
|
111
113
|
return f"http://{display_host}:{port}/"
|
|
112
114
|
|
|
113
115
|
|
|
116
|
+
def _candidate_ports(config: BoardConfig) -> list[int]:
|
|
117
|
+
if not config.port_was_default:
|
|
118
|
+
return [config.port]
|
|
119
|
+
last_port = min(65535, config.port + 9)
|
|
120
|
+
return list(range(config.port, last_port + 1))
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def _explicit_port_conflict_message(host: str, port: int) -> str:
|
|
124
|
+
suggestions = list(range(port + 1, min(65535, port + 3) + 1))
|
|
125
|
+
suggestion_text = f" such as {', '.join(str(candidate) for candidate in suggestions)}" if suggestions else ""
|
|
126
|
+
return (
|
|
127
|
+
f"error: Code Mower Board port {port} is already in use on {host}. "
|
|
128
|
+
f"Pass --port with a free loopback port{suggestion_text}."
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def _bind_board_server(
|
|
133
|
+
config: BoardConfig,
|
|
134
|
+
handler: type[BaseHTTPRequestHandler],
|
|
135
|
+
) -> ThreadingHTTPServer | None:
|
|
136
|
+
server_type = _server_class(config.host)
|
|
137
|
+
tried: list[int] = []
|
|
138
|
+
for port in _candidate_ports(config):
|
|
139
|
+
tried.append(port)
|
|
140
|
+
try:
|
|
141
|
+
return server_type((config.host, port), handler)
|
|
142
|
+
except OSError as exc:
|
|
143
|
+
if exc.errno != errno.EADDRINUSE:
|
|
144
|
+
raise
|
|
145
|
+
if not config.port_was_default:
|
|
146
|
+
print(_explicit_port_conflict_message(config.host, port), file=sys.stderr)
|
|
147
|
+
return None
|
|
148
|
+
print(
|
|
149
|
+
"error: Code Mower Board could not find a free loopback port in "
|
|
150
|
+
f"{tried[0]}-{tried[-1]}; pass --port with a free port.",
|
|
151
|
+
file=sys.stderr,
|
|
152
|
+
)
|
|
153
|
+
return None
|
|
154
|
+
|
|
155
|
+
|
|
114
156
|
def status_payload(
|
|
115
157
|
config: BoardConfig,
|
|
116
158
|
*,
|
|
@@ -781,6 +823,9 @@ def serve(config: BoardConfig, *, open_browser: bool = False) -> int:
|
|
|
781
823
|
if not _is_loopback(config.host):
|
|
782
824
|
print("error: board host must be loopback; use 127.0.0.1 or localhost", file=sys.stderr)
|
|
783
825
|
return 2
|
|
826
|
+
if not 0 <= config.port <= 65535:
|
|
827
|
+
print("error: --port must be between 0 and 65535", file=sys.stderr)
|
|
828
|
+
return 2
|
|
784
829
|
if config.record_interval_seconds < 0:
|
|
785
830
|
print("error: --record-interval-seconds must be non-negative", file=sys.stderr)
|
|
786
831
|
return 2
|
|
@@ -791,10 +836,14 @@ def serve(config: BoardConfig, *, open_browser: bool = False) -> int:
|
|
|
791
836
|
print("error: --max-events must be at least 1", file=sys.stderr)
|
|
792
837
|
return 2
|
|
793
838
|
handler = make_handler(config)
|
|
794
|
-
|
|
795
|
-
|
|
839
|
+
server = _bind_board_server(config, handler)
|
|
840
|
+
if server is None:
|
|
841
|
+
return 2
|
|
842
|
+
with server:
|
|
796
843
|
port = int(server.server_address[1])
|
|
797
844
|
url = _server_url(config.host, port)
|
|
845
|
+
if config.port_was_default and port != config.port:
|
|
846
|
+
print(f"Code Mower Board: default port {config.port} was busy; using {port}", file=sys.stderr)
|
|
798
847
|
print(f"Code Mower Board: {url}", flush=True)
|
|
799
848
|
if open_browser:
|
|
800
849
|
webbrowser.open(url)
|
|
@@ -1057,22 +1106,32 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
1057
1106
|
subparsers = parser.add_subparsers(dest="command", required=True)
|
|
1058
1107
|
serve_parser = subparsers.add_parser("serve")
|
|
1059
1108
|
serve_parser.add_argument("--repo", required=True)
|
|
1060
|
-
serve_parser.add_argument("--host", default=DEFAULT_HOST)
|
|
1061
|
-
serve_parser.add_argument(
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
serve_parser.add_argument("--
|
|
1068
|
-
serve_parser.add_argument("--
|
|
1069
|
-
serve_parser.add_argument("--
|
|
1070
|
-
serve_parser.add_argument("--
|
|
1071
|
-
serve_parser.add_argument("--
|
|
1072
|
-
serve_parser.add_argument("--
|
|
1073
|
-
serve_parser.add_argument("--
|
|
1074
|
-
serve_parser.add_argument("--
|
|
1075
|
-
serve_parser.add_argument("--
|
|
1109
|
+
serve_parser.add_argument("--host", default=DEFAULT_HOST, help="loopback host to bind; default: 127.0.0.1")
|
|
1110
|
+
serve_parser.add_argument(
|
|
1111
|
+
"--port",
|
|
1112
|
+
type=int,
|
|
1113
|
+
default=None,
|
|
1114
|
+
help="loopback port; the default auto-falls forward when busy",
|
|
1115
|
+
)
|
|
1116
|
+
serve_parser.add_argument("--pr-limit", type=int, default=50, help="open PRs to show")
|
|
1117
|
+
serve_parser.add_argument("--workflow-limit", type=int, default=20, help="recent Code Mower workflow runs to show")
|
|
1118
|
+
serve_parser.add_argument("--stale-minutes", type=int, default=30, help="minutes before gate evidence is stale")
|
|
1119
|
+
serve_parser.add_argument("--refresh-seconds", type=int, default=15, help="browser refresh interval")
|
|
1120
|
+
serve_parser.add_argument("--show-local-paths", action="store_true", help="show local cwd paths for debugging")
|
|
1121
|
+
serve_parser.add_argument("--repo-path", default=".", help="repository checkout used for local Board files")
|
|
1122
|
+
serve_parser.add_argument("--store-path", help="custom local Board event store path")
|
|
1123
|
+
serve_parser.add_argument("--spend-path", help="custom reviewer spend ledger path")
|
|
1124
|
+
serve_parser.add_argument("--agent-adapters-path", help="custom local agent card directory")
|
|
1125
|
+
serve_parser.add_argument("--event-limit", type=int, default=20, help="local history events to show")
|
|
1126
|
+
serve_parser.add_argument("--record-events", action="store_true", help="append local history while the Board is open")
|
|
1127
|
+
serve_parser.add_argument("--record-interval-seconds", type=int, default=60, help="minimum seconds between records")
|
|
1128
|
+
serve_parser.add_argument(
|
|
1129
|
+
"--retention-days",
|
|
1130
|
+
type=int,
|
|
1131
|
+
default=board_store.DEFAULT_RETENTION_DAYS,
|
|
1132
|
+
help="local history retention window",
|
|
1133
|
+
)
|
|
1134
|
+
serve_parser.add_argument("--max-events", type=int, default=board_store.DEFAULT_MAX_EVENTS, help="maximum local events")
|
|
1076
1135
|
serve_parser.add_argument("--open", action="store_true", help="open the local board in a browser")
|
|
1077
1136
|
record_parser = subparsers.add_parser("record")
|
|
1078
1137
|
record_parser.add_argument("--repo", required=True)
|
|
@@ -1115,7 +1174,8 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
1115
1174
|
BoardConfig(
|
|
1116
1175
|
repo=args.repo,
|
|
1117
1176
|
host=args.host,
|
|
1118
|
-
port=args.port,
|
|
1177
|
+
port=DEFAULT_PORT if args.port is None else args.port,
|
|
1178
|
+
port_was_default=args.port is None,
|
|
1119
1179
|
pr_limit=args.pr_limit,
|
|
1120
1180
|
workflow_limit=args.workflow_limit,
|
|
1121
1181
|
stale_minutes=args.stale_minutes,
|
|
@@ -556,7 +556,8 @@ def _top_level_help(show_all: bool) -> str:
|
|
|
556
556
|
" code-mower board serve --repo OWNER/REPO",
|
|
557
557
|
(
|
|
558
558
|
" code-mower migration package-install-rehearsal "
|
|
559
|
-
f"--package-spec {code_mower_next_steps.current_alpha_package_spec()}
|
|
559
|
+
f"--package-spec {code_mower_next_steps.current_alpha_package_spec()} "
|
|
560
|
+
"--allow-package-index --json"
|
|
560
561
|
),
|
|
561
562
|
]
|
|
562
563
|
)
|
|
@@ -51,6 +51,39 @@ detect_repo_slug = _doctor_checks.detect_repo_slug
|
|
|
51
51
|
normalize_repo_slug = _doctor_checks.normalize_repo_slug
|
|
52
52
|
|
|
53
53
|
|
|
54
|
+
def _source_repo_uses_starter_config(cwd: Path, config_path: Path) -> bool:
|
|
55
|
+
"""Return true when doctor is running from Code Mower's source tree."""
|
|
56
|
+
|
|
57
|
+
try:
|
|
58
|
+
config_path.resolve().relative_to(cwd.resolve())
|
|
59
|
+
except ValueError:
|
|
60
|
+
return False
|
|
61
|
+
return (
|
|
62
|
+
config_path.name == "code-mower.example.yml"
|
|
63
|
+
and (cwd / "pyproject.toml").is_file()
|
|
64
|
+
and (cwd / "src" / "code_mower" / "templates" / "code-mower.example.yml").is_file()
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _doctor_config_source_label(
|
|
69
|
+
*,
|
|
70
|
+
config_arg: str,
|
|
71
|
+
config_path: Path,
|
|
72
|
+
easy: bool,
|
|
73
|
+
cwd: Path | None = None,
|
|
74
|
+
) -> str:
|
|
75
|
+
"""Classify the config source for adoption-facing doctor output."""
|
|
76
|
+
|
|
77
|
+
cwd = cwd or Path.cwd()
|
|
78
|
+
if config_arg != "code-mower.yml":
|
|
79
|
+
return "explicit_config"
|
|
80
|
+
if config_path.name == "code-mower.example.yml" and easy:
|
|
81
|
+
if _source_repo_uses_starter_config(cwd, config_path):
|
|
82
|
+
return "source_tree_starter"
|
|
83
|
+
return "packaged_starter"
|
|
84
|
+
return "repository_config"
|
|
85
|
+
|
|
86
|
+
|
|
54
87
|
_DOCTOR_COMPAT_EXPORTS = (
|
|
55
88
|
DEFAULT_CLOUD_TOKEN_DIR,
|
|
56
89
|
DEFAULT_CLOUD_TOKEN_ENV,
|
|
@@ -68,6 +101,7 @@ _DOCTOR_COMPAT_EXPORTS = (
|
|
|
68
101
|
resolve_doctor_config_path_for_script,
|
|
69
102
|
resolve_doctor_provider_templates_path,
|
|
70
103
|
_token_file_mentions_cloud_token,
|
|
104
|
+
_doctor_config_source_label,
|
|
71
105
|
)
|
|
72
106
|
|
|
73
107
|
|
|
@@ -202,12 +236,18 @@ def main(argv: Sequence[str] | None = None) -> int:
|
|
|
202
236
|
repo_slug = detect_repo_slug(Path.cwd())
|
|
203
237
|
repo_source = "git_remote" if repo_slug else ""
|
|
204
238
|
provider_templates_path = resolve_doctor_provider_templates_path(args.provider_templates)
|
|
239
|
+
config_path = resolve_doctor_config_path(args.config, easy=args.easy)
|
|
205
240
|
report = run_doctor(
|
|
206
|
-
config_path=
|
|
241
|
+
config_path=config_path,
|
|
207
242
|
provider_templates_path=provider_templates_path,
|
|
208
243
|
profile=args.profile,
|
|
209
244
|
repo_slug=repo_slug,
|
|
210
245
|
repo_source=repo_source,
|
|
246
|
+
config_source=_doctor_config_source_label(
|
|
247
|
+
config_arg=args.config,
|
|
248
|
+
config_path=config_path,
|
|
249
|
+
easy=args.easy,
|
|
250
|
+
),
|
|
211
251
|
adoption=args.adoption,
|
|
212
252
|
adoption_posture=args.adoption_posture,
|
|
213
253
|
probe_runtime=args.probe_runtime,
|
|
@@ -111,6 +111,7 @@ def check_adoption_setup(
|
|
|
111
111
|
repo_slug: str,
|
|
112
112
|
repo_source: str,
|
|
113
113
|
using_packaged_example: bool,
|
|
114
|
+
config_source: str = "",
|
|
114
115
|
) -> tuple[DoctorCheck, ...]:
|
|
115
116
|
"""Return first-run adoption posture checks."""
|
|
116
117
|
|
|
@@ -144,17 +145,28 @@ def check_adoption_setup(
|
|
|
144
145
|
)
|
|
145
146
|
|
|
146
147
|
repositories = _configured_repositories(config)
|
|
148
|
+
source = config_source or (
|
|
149
|
+
"packaged_starter" if using_packaged_example else "repository_config"
|
|
150
|
+
)
|
|
151
|
+
source_messages = {
|
|
152
|
+
"explicit_config": "using explicit Code Mower config",
|
|
153
|
+
"packaged_starter": "using packaged starter config for adoption checks",
|
|
154
|
+
"repository_config": "using repository Code Mower config",
|
|
155
|
+
"source_tree_starter": "using source-tree starter config for adoption checks",
|
|
156
|
+
}
|
|
157
|
+
detail = {
|
|
158
|
+
"config_path": str(config_path),
|
|
159
|
+
"config_source": source,
|
|
160
|
+
"configured_repositories": repositories,
|
|
161
|
+
"effective_repository": repo_slug,
|
|
162
|
+
}
|
|
147
163
|
if using_packaged_example:
|
|
148
164
|
checks.append(
|
|
149
165
|
DoctorCheck(
|
|
150
166
|
name="doctor.adoption.config_source",
|
|
151
167
|
status=STATUS_WARN,
|
|
152
|
-
message=
|
|
153
|
-
detail=
|
|
154
|
-
"config_path": str(config_path),
|
|
155
|
-
"configured_repositories": repositories,
|
|
156
|
-
"effective_repository": repo_slug,
|
|
157
|
-
},
|
|
168
|
+
message=source_messages.get(source, source_messages["packaged_starter"]),
|
|
169
|
+
detail=detail,
|
|
158
170
|
remediation=(
|
|
159
171
|
"Run `code-mower init --easy --apply`, review the generated "
|
|
160
172
|
"setup, and commit an edited code-mower.yml before relying "
|
|
@@ -167,12 +179,8 @@ def check_adoption_setup(
|
|
|
167
179
|
DoctorCheck(
|
|
168
180
|
name="doctor.adoption.config_source",
|
|
169
181
|
status=STATUS_PASS,
|
|
170
|
-
message=
|
|
171
|
-
detail=
|
|
172
|
-
"config_path": str(config_path),
|
|
173
|
-
"configured_repositories": repositories,
|
|
174
|
-
"effective_repository": repo_slug,
|
|
175
|
-
},
|
|
182
|
+
message=source_messages.get(source, source_messages["repository_config"]),
|
|
183
|
+
detail=detail,
|
|
176
184
|
)
|
|
177
185
|
)
|
|
178
186
|
|
|
@@ -66,6 +66,7 @@ ACTIONS_METADATA_WORKFLOW_MARKERS = (
|
|
|
66
66
|
"audit-label-cleanup",
|
|
67
67
|
"devin-audit-bridge",
|
|
68
68
|
)
|
|
69
|
+
OBSERVER_ADOPTION_POSTURES = frozenset({"hosted-builders", "orchestrator-only"})
|
|
69
70
|
|
|
70
71
|
__all__ = [
|
|
71
72
|
"ACTIONS_BILLING_BLOCK_PATTERNS",
|
|
@@ -76,6 +77,7 @@ __all__ = [
|
|
|
76
77
|
"DoctorCheck",
|
|
77
78
|
"MAX_ACTIONS_FAILED_JOBS_TO_INSPECT",
|
|
78
79
|
"MAX_ACTIONS_FAILED_RUNS_TO_INSPECT",
|
|
80
|
+
"OBSERVER_ADOPTION_POSTURES",
|
|
79
81
|
"STATUS_FAIL",
|
|
80
82
|
"STATUS_PASS",
|
|
81
83
|
"STATUS_SKIP",
|
|
@@ -36,6 +36,7 @@ def check_github_setup(
|
|
|
36
36
|
lanes: Sequence[tuple[str, Mapping[str, Any]]],
|
|
37
37
|
http_timeout: int,
|
|
38
38
|
actions_cost_sample: int = ACTIONS_COST_SAMPLE_DEFAULT,
|
|
39
|
+
adoption_posture: str = "reviewer-gate",
|
|
39
40
|
) -> list[DoctorCheck]:
|
|
40
41
|
checks: list[DoctorCheck] = []
|
|
41
42
|
gh_path = shutil.which("gh")
|
|
@@ -142,6 +143,7 @@ def check_github_setup(
|
|
|
142
143
|
config=config,
|
|
143
144
|
lanes=lanes,
|
|
144
145
|
http_timeout=http_timeout,
|
|
146
|
+
adoption_posture=adoption_posture,
|
|
145
147
|
)
|
|
146
148
|
)
|
|
147
149
|
if has_merge_authority:
|
{code_mower-0.8.0b1 → code_mower-0.9.0b1}/src/code_mower/doctor_checks/github_human_token.py
RENAMED
|
@@ -5,7 +5,14 @@ from __future__ import annotations
|
|
|
5
5
|
from datetime import UTC, date, datetime
|
|
6
6
|
from typing import Any, Mapping, Sequence
|
|
7
7
|
|
|
8
|
-
from .common import
|
|
8
|
+
from .common import (
|
|
9
|
+
OBSERVER_ADOPTION_POSTURES,
|
|
10
|
+
DoctorCheck,
|
|
11
|
+
STATUS_FAIL,
|
|
12
|
+
STATUS_PASS,
|
|
13
|
+
STATUS_SKIP,
|
|
14
|
+
STATUS_WARN,
|
|
15
|
+
)
|
|
9
16
|
from .github_api import _github_api_json
|
|
10
17
|
|
|
11
18
|
DEFAULT_HUMAN_TOKEN_SECRET = "DISPATCH_TOKEN"
|
|
@@ -93,6 +100,18 @@ def _is_expiry_placeholder(value: str) -> bool:
|
|
|
93
100
|
return value.strip().upper() in EXPIRY_PLACEHOLDER_VALUES
|
|
94
101
|
|
|
95
102
|
|
|
103
|
+
def _blocking_status_for_posture(adoption_posture: str) -> str:
|
|
104
|
+
return STATUS_WARN if adoption_posture in OBSERVER_ADOPTION_POSTURES else STATUS_FAIL
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def _token_readiness_context(adoption_posture: str) -> str:
|
|
108
|
+
if adoption_posture == "hosted-builders":
|
|
109
|
+
return "hosted-builder observer posture"
|
|
110
|
+
if adoption_posture == "orchestrator-only":
|
|
111
|
+
return "orchestrator-only posture"
|
|
112
|
+
return "reviewer-gate posture"
|
|
113
|
+
|
|
114
|
+
|
|
96
115
|
def check_human_automation_token(
|
|
97
116
|
*,
|
|
98
117
|
gh_path: str,
|
|
@@ -100,6 +119,7 @@ def check_human_automation_token(
|
|
|
100
119
|
config: Mapping[str, Any],
|
|
101
120
|
lanes: Sequence[tuple[str, Mapping[str, Any]]],
|
|
102
121
|
http_timeout: int,
|
|
122
|
+
adoption_posture: str = "reviewer-gate",
|
|
103
123
|
now: datetime | None = None,
|
|
104
124
|
) -> DoctorCheck:
|
|
105
125
|
token = human_automation_token_config(config)
|
|
@@ -110,6 +130,7 @@ def check_human_automation_token(
|
|
|
110
130
|
"secret": secret_name,
|
|
111
131
|
"expires_var": expires_var,
|
|
112
132
|
"required": human_automation_token_required(config, lanes),
|
|
133
|
+
"adoption_posture": adoption_posture,
|
|
113
134
|
}
|
|
114
135
|
if not detail["required"]:
|
|
115
136
|
return DoctorCheck(
|
|
@@ -125,15 +146,24 @@ def check_human_automation_token(
|
|
|
125
146
|
http_timeout=http_timeout,
|
|
126
147
|
)
|
|
127
148
|
if secret_payload is None:
|
|
149
|
+
status = _blocking_status_for_posture(adoption_posture)
|
|
128
150
|
return DoctorCheck(
|
|
129
151
|
name="github.human_automation_token",
|
|
130
|
-
status=
|
|
131
|
-
message=
|
|
152
|
+
status=status,
|
|
153
|
+
message=(
|
|
154
|
+
f"{slug} is missing the {secret_name} human automation token secret"
|
|
155
|
+
+ (
|
|
156
|
+
f" for {_token_readiness_context(adoption_posture)}"
|
|
157
|
+
if status == STATUS_WARN
|
|
158
|
+
else ""
|
|
159
|
+
)
|
|
160
|
+
),
|
|
132
161
|
detail={**detail, "secret_check": secret_detail},
|
|
133
162
|
remediation=(
|
|
134
163
|
f"Create one human-owned fine-grained PAT secret with "
|
|
135
164
|
f"`gh secret set {secret_name}`. Grant repository Contents read, "
|
|
136
|
-
"Issues read/write, and Pull requests read/write
|
|
165
|
+
"Issues read/write, and Pull requests read/write before relying "
|
|
166
|
+
"on unattended dispatch, labels, or fix-round mentions."
|
|
137
167
|
),
|
|
138
168
|
)
|
|
139
169
|
|
|
@@ -143,9 +173,10 @@ def check_human_automation_token(
|
|
|
143
173
|
http_timeout=http_timeout,
|
|
144
174
|
)
|
|
145
175
|
if variable_payload is None:
|
|
176
|
+
status = _blocking_status_for_posture(adoption_posture)
|
|
146
177
|
return DoctorCheck(
|
|
147
178
|
name="github.human_automation_token",
|
|
148
|
-
status=
|
|
179
|
+
status=status,
|
|
149
180
|
message=f"{slug} is missing the {expires_var} human token expiry variable",
|
|
150
181
|
detail={
|
|
151
182
|
**detail,
|
|
@@ -188,9 +219,10 @@ def check_human_automation_token(
|
|
|
188
219
|
)
|
|
189
220
|
expiry = _parse_expiry(expiry_text)
|
|
190
221
|
if expiry is None:
|
|
222
|
+
status = _blocking_status_for_posture(adoption_posture)
|
|
191
223
|
return DoctorCheck(
|
|
192
224
|
name="github.human_automation_token",
|
|
193
|
-
status=
|
|
225
|
+
status=status,
|
|
194
226
|
message=f"{slug} has an invalid {expires_var} value",
|
|
195
227
|
detail={**detail, "expires_at": expiry_text},
|
|
196
228
|
remediation=(
|
|
@@ -203,7 +235,7 @@ def check_human_automation_token(
|
|
|
203
235
|
days_remaining = (expiry - today).days
|
|
204
236
|
status = STATUS_PASS
|
|
205
237
|
if days_remaining < 0:
|
|
206
|
-
status =
|
|
238
|
+
status = _blocking_status_for_posture(adoption_posture)
|
|
207
239
|
elif days_remaining <= EXPIRY_WARNING_DAYS:
|
|
208
240
|
status = STATUS_WARN
|
|
209
241
|
|