code-mower 0.8.0b1__tar.gz → 0.9.1b1__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.1b1}/PKG-INFO +34 -11
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/README.md +33 -10
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/pyproject.toml +1 -1
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/__init__.py +1 -1
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/board.py +94 -26
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/cli.py +2 -1
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor.py +41 -1
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/__init__.py +4 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/adoption.py +176 -20
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/common.py +2 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/github.py +2 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/github_human_token.py +39 -7
- code_mower-0.9.1b1/src/code_mower/doctor_checks/github_trusted_authors.py +38 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/provider_review_hygiene.py +53 -30
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/providers.py +9 -4
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/runner.py +36 -1
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/self_hosted_runner.py +0 -3
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/lane_status.py +80 -12
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/migration.py +351 -1
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/migration_install.py +22 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/migration_rehearsal.py +30 -7
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/next_steps.py +4 -4
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/package_content.py +1 -1
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/package_manifest.py +5 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/release_readiness.py +3 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/workflows/builder-provenance.yml.j2 +1 -1
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower.egg-info/PKG-INFO +34 -11
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower.egg-info/SOURCES.txt +2 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/workflows/builder-provenance.yml.j2 +1 -1
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_board.py +83 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_doctor_github_checks.py +85 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_doctor_provider_review_hygiene.py +4 -6
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_doctor_registry.py +253 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_doctor_self_hosted_runner.py +31 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_lane_status.py +60 -0
- code_mower-0.9.1b1/tests/test_migration_setup_drift.py +82 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_release_hygiene.py +252 -39
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/CODE_OF_CONDUCT.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/LICENSE +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/MANIFEST.in +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/NOTICE +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/SUPPORT.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/requirements/requirements.txt +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/setup.cfg +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/adapters/__init__.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/adapters/_base.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/adapters/cursor_bugbot.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/adapters/gitar.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/adapters/greptile.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/adapters/qodo.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/antigravity_cli_audit_pr.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/antigravity_sdk_probe.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/audit_handoff_log.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/audit_labeler_lib.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/audit_limits.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/audit_progress.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/blind_review_artifacts.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/blind_review_coordinator.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/board_store.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/bootstrap.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/builder_experiment.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/builder_runs.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/__init__.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/arms.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/auto_discovery.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/commands.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/context_inputs.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/corpus.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/effect_report.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/evidence.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/evidence_report.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/identity.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/metrics.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/overlap.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/planning.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/policy.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/results.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/run_results.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/run_status.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/runner.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/truth.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/value_report.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/checks.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/claude_audit_pr.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/claude_cli_bounce.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/claude_cli_environment.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/clear_stale.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/cloud.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/cloud_client/__init__.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/cloud_client/bundle.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/cloud_client/doctor.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/cloud_client/dogfood.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/cloud_client/endpoints.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/cloud_client/errors.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/cloud_client/events.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/cloud_client/export.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/cloud_client/git_metadata.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/cloud_client/manifest.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/cloud_client/operations.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/cloud_client/reports.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/cloud_client/setup.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/cloud_client/tokens.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/cloud_client/upload.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/code_mower_calibration.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/code_mower_context_packs.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/code_mower_merge.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/code_mower_telemetry.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/coderabbit_cli_audit_pr.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/codex_audit_env_preflight.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/codex_audit_pr.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/codex_audit_schema_smoke.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/codex_audit_verdict.schema.json +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/config.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/decisions.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/audit_limits.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/cloud.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/github_actions.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/github_actions_cost.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/github_actions_cost_summary.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/github_actions_failure_annotations.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/github_actions_failure_models.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/github_actions_failure_scan.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/github_actions_failure_selection.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/github_actions_failures.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/github_actions_permissions.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/github_api.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/github_branch.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/github_config.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/github_provider.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/github_repo.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/groups.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/models.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/output.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/presets.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/privacy.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/provider_api_model.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/provider_api_model_openai.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/provider_api_model_profiles.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/provider_env.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/provider_env_required.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/provider_env_tokens.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/provider_local_audit_setup.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/provider_local_cli.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/provider_local_cli_commands.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/provider_local_cli_probe_config.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/provider_probe.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/provider_probe_auth.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/provider_probe_evaluation.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/provider_probe_json.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/provider_probe_remediation.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/registry.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/runtime.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/runtime_github_auth.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/gate_health.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/gemini_cli_audit_pr.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/git_identity.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/grok_build_audit_pr.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/hermes_cli_audit_pr.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/init.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/lane_configs/__init__.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/lane_configs/aider.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/lane_configs/antigravity_cli.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/lane_configs/claude.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/lane_configs/codex.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/lane_configs/devin.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/lane_configs/gemini_cli.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/lane_configs/grok_build.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/lane_configs/hermes_cli.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/lane_configs/local_llm.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/local_llm_audit_pr.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/local_llm_bakeoff.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/local_llm_calibration.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/local_llm_profiles.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/migration_mirror.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/migration_readiness.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/observe.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/package.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/package_paths.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/package_rendering.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/package_static.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/plan_context.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/prompts.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/provider_registry.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/provider_runners/__init__.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/provider_runners/comments.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/provider_runners/exit_codes.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/provider_runners/git.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/provider_runners/github_auth.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/provider_runners/github_pr.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/provider_runners/pr_worktree.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/provider_runners/process.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/provider_runners/repo_paths.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/provider_runners/text_schema.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/provider_runners/verdict_artifacts.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/provider_runners/workspace.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/providers/__init__.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/providers/local_cli.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/providers/provenance.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/reviewer_metrics.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/reviewer_spend.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/saas_reviewer_labeler.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/secrets.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/builder-experiment.example.json +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/calibration-corpus.example.json +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/calibration-corpus.json +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/code-mower.example.yml +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/context-packs.example.json +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/lane_prompts/base-audit.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/lane_prompts/calibration-policy.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/lane_prompts/context-driven-quality.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/lane_prompts/docs-design.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/lane_prompts/generic-programming.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/lane_prompts/operability.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/lane_prompts/package-runtime.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/lane_prompts/plan-conformance.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/lane_prompts/security-threat-model.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/lanes/README.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/lanes/claude.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/lanes/codex.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/lanes/cursor.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/lanes/generic.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/lanes/run_mac_lane.sh +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/product-support/code_mower +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/product-support/code_mower_standalone_pin.env +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/product-support/code_mower_standalone_shadow.sh +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/product-support/run_claude_audit_pr.sh +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/product-support/run_codex_audit_pr.sh +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/product-support/safe_gh_comment.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/product-support/status_report.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/providers.yml +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/reviewer-spend.example.json +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/reviewer-value-report.example.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/workflows/audit-label-cleanup.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/workflows/code-mower-agent-pr-labeler.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/workflows/code-mower-fix-round-dispatch.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/workflows/code-mower-gate-health.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/workflows/code-mower-gate.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/workflows/dispatch-lanes.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/workflows/hosted-bridge.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/workflows/lane-mac-runner.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/workflows/local-cli-audit.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/workflows/needs-owner-notify.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/workflows/private-standalone-shadow.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/workflows/review-clear-stale.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/workflows/saas-reviewer-labeler.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/workflows/self-hosted-local-audit.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/workflows/trailer-comment-labeler.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/workflows/weekly-status.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/trailer_comment_labeler.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/versioning.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/work_orders.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower/workflow_actionlint.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower.egg-info/dependency_links.txt +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower.egg-info/entry_points.txt +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower.egg-info/requires.txt +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/src/code_mower.egg-info/top_level.txt +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/builder-experiment.example.json +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/calibration-corpus.example.json +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/calibration-corpus.json +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/code-mower.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/context-packs.example.json +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/cursor/BUGBOT.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/lanes/README.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/lanes/claude.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/lanes/codex.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/lanes/cursor.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/lanes/generic.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/lanes/run_mac_lane.sh +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/providers/acp_bridge.yml +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/providers/aider.yml +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/providers/antigravity_cli.yml +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/providers/claude_audit.yml +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/providers/claude_review.yml +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/providers/coderabbit_cli.yml +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/providers/codex.yml +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/providers/cursor_bugbot.yml +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/providers/devin.yml +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/providers/gemini_cli.yml +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/providers/gitar.yml +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/providers/greptile.yml +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/providers/hermes_cli.yml +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/providers/local_llm.yml +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/providers/qodo.yml +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/providers.yml +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/reviewer-spend.example.json +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/reviewer-value-report.example.md +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/workflows/audit-label-cleanup.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/workflows/blind-review-artifacts-dry-run.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/workflows/code-mower-agent-pr-labeler.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/workflows/code-mower-fix-round-dispatch.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/workflows/code-mower-gate-health.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/workflows/code-mower-gate.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/workflows/dispatch-lanes.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/workflows/hosted-bridge.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/workflows/lane-mac-runner.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/workflows/local-cli-audit.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/workflows/private-standalone-shadow.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/workflows/review-clear-stale.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/workflows/saas-reviewer-labeler.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/workflows/self-hosted-local-audit.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/templates/workflows/trailer-comment-labeler.yml.j2 +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_antigravity_sdk_probe.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_audit_comment_posture.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_audit_limits.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_builder_experiment.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_builder_identity.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_builder_runs.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_calibration_effect_report.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_calibration_truth.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_checks.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_claude_audit_pr.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_claude_cli_bounce.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_clear_stale.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_cloud_client.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_cloud_git_metadata.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_cloud_manifest.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_cloud_reports.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_coderabbit_cli_audit_pr.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_codex_audit_env_preflight.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_codex_audit_pr.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_decision_audit_integration.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_decisions.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_doctor_actions_cost_summary.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_doctor_actions_failure_selection.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_doctor_boundaries.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_doctor_output.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_doctor_privacy.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_doctor_provider_env_required.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_doctor_provider_env_tokens.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_doctor_provider_local_audit_setup.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_doctor_provider_probe.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_doctor_runtime.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_gate_health.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_init_actionlint.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_init_build_loop.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_local_llm_github_helpers.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_observe.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_plan_context.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_prompts.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_provider_fixture_contracts.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_provider_local_cli.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_provider_runners_comments.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_provider_runners_git.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_provider_runners_github_pr.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_provider_runners_pr_worktree.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_provider_runners_process.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_provider_runners_repo_paths.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_provider_runners_text_schema.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_provider_runners_workspace.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_reviewer_metrics_core.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_reviewer_spend.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/tests/test_trailer_comment_labeler.py +0 -0
- {code_mower-0.8.0b1 → code_mower-0.9.1b1}/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.1b1
|
|
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,16 +90,29 @@ 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
|
+
Use [Upgrade An Existing Repository](docs/upgrade-existing-repo.md) for the
|
|
99
|
+
reviewed PR flow, repo-only file handling, builder identity checks, and
|
|
100
|
+
wrapper/pin drift checks.
|
|
101
|
+
|
|
91
102
|
After `init` and `doctor`, use `code-mower lanes status --repo OWNER/REPO` to
|
|
92
103
|
see active builder/reviewer lanes, gate/check state, recent Code Mower
|
|
93
104
|
workflows, local board/process hints when present, and the next operator
|
|
94
105
|
action. Text and JSON output redact local cwd paths by default; use
|
|
95
|
-
`--show-local-paths` only for local debugging.
|
|
106
|
+
`--show-local-paths` only for local debugging. Local Board discovery is
|
|
107
|
+
best-effort across common macOS and Linux listener tools; when a host restricts
|
|
108
|
+
listener inventory, remote PR/check status still reports normally.
|
|
96
109
|
|
|
97
110
|
For the same redacted metadata in a local browser view, run
|
|
98
111
|
`code-mower board serve --repo OWNER/REPO` and open the printed localhost URL.
|
|
99
|
-
Plain `board serve` is read-only.
|
|
100
|
-
|
|
112
|
+
Plain `board serve` is read-only. If the default Board port is busy, the CLI
|
|
113
|
+
uses a nearby free loopback port and prints the URL; an explicit `--port` stays
|
|
114
|
+
strict and reports a friendly conflict. To build local history while the browser
|
|
115
|
+
view is open, run `code-mower board serve --repo OWNER/REPO --record-events`; it
|
|
101
116
|
records at most one snapshot every 60 seconds by default. To append one snapshot
|
|
102
117
|
without serving the browser view, run
|
|
103
118
|
`code-mower board record --repo OWNER/REPO` from the repository checkout; it
|
|
@@ -143,7 +158,9 @@ observable.
|
|
|
143
158
|
|
|
144
159
|
Install first from the [Install And Bootstrap](docs/install.md) matrix: pipx for
|
|
145
160
|
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.
|
|
161
|
+
for Code Mower contributors. All paths require Python 3.12 or newer. For
|
|
162
|
+
upgrades, record `command -v code-mower` and `code-mower --version` before and
|
|
163
|
+
after reinstalling, especially when switching between pipx and uv.
|
|
147
164
|
|
|
148
165
|
| Path | Use When | Route | Guide |
|
|
149
166
|
| --- | --- | --- | --- |
|
|
@@ -152,9 +169,11 @@ for Code Mower contributors. All paths require Python 3.12 or newer.
|
|
|
152
169
|
| 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
170
|
|
|
154
171
|
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
|
-
|
|
172
|
+
[Try Code Mower In 10 Minutes](https://github.com/codemower-ai/code-mower/blob/v0.9.1-beta.1/docs/try-in-10-minutes.md)
|
|
173
|
+
guide. The v0.9 beta includes the completed native Board work plus the adoption
|
|
174
|
+
and upgrade hardening from recent install rehearsals; v0.9.1 adds a smaller
|
|
175
|
+
announcement-hardening pass on Board visibility, doctor guidance, and safer
|
|
176
|
+
setup docs. Package-only users can start from the public package rather than a
|
|
158
177
|
source checkout.
|
|
159
178
|
|
|
160
179
|
## What Calibration Does And Does Not Prove
|
|
@@ -178,13 +197,15 @@ review-request signals to propose known-clean and known-blocked cases. Review
|
|
|
178
197
|
every disposition before using it for lane promotion or merge policy.
|
|
179
198
|
|
|
180
199
|
Full walkthrough: [docs/try-in-10-minutes.md](docs/try-in-10-minutes.md).
|
|
200
|
+
Existing-repo upgrade flow:
|
|
201
|
+
[docs/upgrade-existing-repo.md](docs/upgrade-existing-repo.md).
|
|
181
202
|
First-time command map: [docs/launch-command-surface.md](docs/launch-command-surface.md).
|
|
182
203
|
Provider-contract baseline for the next release train:
|
|
183
204
|
[docs/v06-truth-baseline.md](docs/v06-truth-baseline.md).
|
|
184
205
|
|
|
185
206
|
For release verification,
|
|
186
207
|
[First-User Install Rehearsal](docs/first-user-install-rehearsal.md) records
|
|
187
|
-
the package-index procedure for `v0.
|
|
208
|
+
the package-index procedure for `v0.9.1-beta.1` / `code-mower==0.9.1b1`. The
|
|
188
209
|
GitHub release records the workflow and rehearsal evidence for the exact tag.
|
|
189
210
|
|
|
190
211
|
## Optional: Plan Before Coding
|
|
@@ -370,8 +391,8 @@ measurement work.
|
|
|
370
391
|
|
|
371
392
|
## Installation Status
|
|
372
393
|
|
|
373
|
-
The current package-index beta baseline is `v0.
|
|
374
|
-
install spec `code-mower==0.
|
|
394
|
+
The current package-index beta baseline is `v0.9.1-beta.1`, with pinned package
|
|
395
|
+
install spec `code-mower==0.9.1b1`. Release evidence is recorded on the GitHub
|
|
375
396
|
release and in the first-user install rehearsal. The public repository is
|
|
376
397
|
[codemower-ai/code-mower](https://github.com/codemower-ai/code-mower), and
|
|
377
398
|
GitHub releases remain the auditable source for tags, build artifacts, and
|
|
@@ -412,6 +433,7 @@ first so local work exercises the same package entrypoint users install.
|
|
|
412
433
|
## Docs Map
|
|
413
434
|
|
|
414
435
|
- [Install And Bootstrap](docs/install.md)
|
|
436
|
+
- [Upgrade An Existing Repository](docs/upgrade-existing-repo.md)
|
|
415
437
|
- [Try Code Mower In 10 Minutes](docs/try-in-10-minutes.md)
|
|
416
438
|
- [Build Loop In 30 Minutes](docs/build-loop-in-30-minutes.md)
|
|
417
439
|
- [Quickstart Reference](docs/quickstart.md)
|
|
@@ -434,6 +456,7 @@ first so local work exercises the same package entrypoint users install.
|
|
|
434
456
|
- [v0.6 Truth Baseline](docs/v06-truth-baseline.md)
|
|
435
457
|
- [v0.6 Release Notes](docs/v06-release-notes.md)
|
|
436
458
|
- [v0.8 Release Notes](docs/v08-release-notes.md)
|
|
459
|
+
- [v0.9 Release Notes](docs/v09-release-notes.md)
|
|
437
460
|
- [Post-v0.8 Effectiveness Assessment](docs/post-v08-effectiveness-assessment.md)
|
|
438
461
|
- [Demo Calibration Example](examples/demo-calibration/README.md)
|
|
439
462
|
- [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,16 +73,29 @@ 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
|
+
Use [Upgrade An Existing Repository](docs/upgrade-existing-repo.md) for the
|
|
82
|
+
reviewed PR flow, repo-only file handling, builder identity checks, and
|
|
83
|
+
wrapper/pin drift checks.
|
|
84
|
+
|
|
74
85
|
After `init` and `doctor`, use `code-mower lanes status --repo OWNER/REPO` to
|
|
75
86
|
see active builder/reviewer lanes, gate/check state, recent Code Mower
|
|
76
87
|
workflows, local board/process hints when present, and the next operator
|
|
77
88
|
action. Text and JSON output redact local cwd paths by default; use
|
|
78
|
-
`--show-local-paths` only for local debugging.
|
|
89
|
+
`--show-local-paths` only for local debugging. Local Board discovery is
|
|
90
|
+
best-effort across common macOS and Linux listener tools; when a host restricts
|
|
91
|
+
listener inventory, remote PR/check status still reports normally.
|
|
79
92
|
|
|
80
93
|
For the same redacted metadata in a local browser view, run
|
|
81
94
|
`code-mower board serve --repo OWNER/REPO` and open the printed localhost URL.
|
|
82
|
-
Plain `board serve` is read-only.
|
|
83
|
-
|
|
95
|
+
Plain `board serve` is read-only. If the default Board port is busy, the CLI
|
|
96
|
+
uses a nearby free loopback port and prints the URL; an explicit `--port` stays
|
|
97
|
+
strict and reports a friendly conflict. To build local history while the browser
|
|
98
|
+
view is open, run `code-mower board serve --repo OWNER/REPO --record-events`; it
|
|
84
99
|
records at most one snapshot every 60 seconds by default. To append one snapshot
|
|
85
100
|
without serving the browser view, run
|
|
86
101
|
`code-mower board record --repo OWNER/REPO` from the repository checkout; it
|
|
@@ -126,7 +141,9 @@ observable.
|
|
|
126
141
|
|
|
127
142
|
Install first from the [Install And Bootstrap](docs/install.md) matrix: pipx for
|
|
128
143
|
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.
|
|
144
|
+
for Code Mower contributors. All paths require Python 3.12 or newer. For
|
|
145
|
+
upgrades, record `command -v code-mower` and `code-mower --version` before and
|
|
146
|
+
after reinstalling, especially when switching between pipx and uv.
|
|
130
147
|
|
|
131
148
|
| Path | Use When | Route | Guide |
|
|
132
149
|
| --- | --- | --- | --- |
|
|
@@ -135,9 +152,11 @@ for Code Mower contributors. All paths require Python 3.12 or newer.
|
|
|
135
152
|
| 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
153
|
|
|
137
154
|
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
|
-
|
|
155
|
+
[Try Code Mower In 10 Minutes](https://github.com/codemower-ai/code-mower/blob/v0.9.1-beta.1/docs/try-in-10-minutes.md)
|
|
156
|
+
guide. The v0.9 beta includes the completed native Board work plus the adoption
|
|
157
|
+
and upgrade hardening from recent install rehearsals; v0.9.1 adds a smaller
|
|
158
|
+
announcement-hardening pass on Board visibility, doctor guidance, and safer
|
|
159
|
+
setup docs. Package-only users can start from the public package rather than a
|
|
141
160
|
source checkout.
|
|
142
161
|
|
|
143
162
|
## What Calibration Does And Does Not Prove
|
|
@@ -161,13 +180,15 @@ review-request signals to propose known-clean and known-blocked cases. Review
|
|
|
161
180
|
every disposition before using it for lane promotion or merge policy.
|
|
162
181
|
|
|
163
182
|
Full walkthrough: [docs/try-in-10-minutes.md](docs/try-in-10-minutes.md).
|
|
183
|
+
Existing-repo upgrade flow:
|
|
184
|
+
[docs/upgrade-existing-repo.md](docs/upgrade-existing-repo.md).
|
|
164
185
|
First-time command map: [docs/launch-command-surface.md](docs/launch-command-surface.md).
|
|
165
186
|
Provider-contract baseline for the next release train:
|
|
166
187
|
[docs/v06-truth-baseline.md](docs/v06-truth-baseline.md).
|
|
167
188
|
|
|
168
189
|
For release verification,
|
|
169
190
|
[First-User Install Rehearsal](docs/first-user-install-rehearsal.md) records
|
|
170
|
-
the package-index procedure for `v0.
|
|
191
|
+
the package-index procedure for `v0.9.1-beta.1` / `code-mower==0.9.1b1`. The
|
|
171
192
|
GitHub release records the workflow and rehearsal evidence for the exact tag.
|
|
172
193
|
|
|
173
194
|
## Optional: Plan Before Coding
|
|
@@ -353,8 +374,8 @@ measurement work.
|
|
|
353
374
|
|
|
354
375
|
## Installation Status
|
|
355
376
|
|
|
356
|
-
The current package-index beta baseline is `v0.
|
|
357
|
-
install spec `code-mower==0.
|
|
377
|
+
The current package-index beta baseline is `v0.9.1-beta.1`, with pinned package
|
|
378
|
+
install spec `code-mower==0.9.1b1`. Release evidence is recorded on the GitHub
|
|
358
379
|
release and in the first-user install rehearsal. The public repository is
|
|
359
380
|
[codemower-ai/code-mower](https://github.com/codemower-ai/code-mower), and
|
|
360
381
|
GitHub releases remain the auditable source for tags, build artifacts, and
|
|
@@ -395,6 +416,7 @@ first so local work exercises the same package entrypoint users install.
|
|
|
395
416
|
## Docs Map
|
|
396
417
|
|
|
397
418
|
- [Install And Bootstrap](docs/install.md)
|
|
419
|
+
- [Upgrade An Existing Repository](docs/upgrade-existing-repo.md)
|
|
398
420
|
- [Try Code Mower In 10 Minutes](docs/try-in-10-minutes.md)
|
|
399
421
|
- [Build Loop In 30 Minutes](docs/build-loop-in-30-minutes.md)
|
|
400
422
|
- [Quickstart Reference](docs/quickstart.md)
|
|
@@ -417,6 +439,7 @@ first so local work exercises the same package entrypoint users install.
|
|
|
417
439
|
- [v0.6 Truth Baseline](docs/v06-truth-baseline.md)
|
|
418
440
|
- [v0.6 Release Notes](docs/v06-release-notes.md)
|
|
419
441
|
- [v0.8 Release Notes](docs/v08-release-notes.md)
|
|
442
|
+
- [v0.9 Release Notes](docs/v09-release-notes.md)
|
|
420
443
|
- [Post-v0.8 Effectiveness Assessment](docs/post-v08-effectiveness-assessment.md)
|
|
421
444
|
- [Demo Calibration Example](examples/demo-calibration/README.md)
|
|
422
445
|
- [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
|
*,
|
|
@@ -613,6 +655,14 @@ def render_board_html(config: BoardConfig) -> str:
|
|
|
613
655
|
const stateClass = (value) => /fail|error|blocked/i.test(text(value)) ? "bad" : /warn|pending|waiting|queued|progress/i.test(text(value)) ? "warn" : "ok";
|
|
614
656
|
const seconds = (value) => Number.isFinite(Number(value)) ? `${{Number(value).toFixed(1)}}s` : "n/a";
|
|
615
657
|
const money = (value) => Number.isFinite(Number(value)) ? `$${{Number(value).toFixed(3)}}` : "n/a";
|
|
658
|
+
const localTime = (value) => {{
|
|
659
|
+
const raw = text(value);
|
|
660
|
+
if (!raw) return "";
|
|
661
|
+
const date = new Date(raw);
|
|
662
|
+
if (Number.isNaN(date.getTime())) return esc(raw);
|
|
663
|
+
const local = new Intl.DateTimeFormat(undefined, {{year:"numeric", month:"short", day:"numeric", hour:"numeric", minute:"2-digit", second:"2-digit", timeZoneName:"short"}}).format(date);
|
|
664
|
+
return `<time datetime="${{esc(raw)}}" title="UTC ${{esc(raw)}}">${{esc(local)}}</time>`;
|
|
665
|
+
}};
|
|
616
666
|
function labels(groups) {{
|
|
617
667
|
return Object.values(groups || {{}}).flat().map(pill).join(" ") || '<span class="muted">none</span>';
|
|
618
668
|
}}
|
|
@@ -621,7 +671,7 @@ def render_board_html(config: BoardConfig) -> str:
|
|
|
621
671
|
}}
|
|
622
672
|
function render(data) {{
|
|
623
673
|
document.getElementById("repo").textContent = REPO;
|
|
624
|
-
document.getElementById("generated").
|
|
674
|
+
document.getElementById("generated").innerHTML = data.generated_at ? `Generated ${{localTime(data.generated_at)}}` : "Loading...";
|
|
625
675
|
const prs = data.remote?.pull_requests || [];
|
|
626
676
|
const runs = data.remote?.workflow_runs || [];
|
|
627
677
|
const alerts = data.remote?.gate_health?.alerts || [];
|
|
@@ -639,18 +689,18 @@ def render_board_html(config: BoardConfig) -> str:
|
|
|
639
689
|
`<div class="metric"><span class="muted">Agent cards</span><b>${{agentCards.length}}</b></div>`,
|
|
640
690
|
`<div class="metric"><span class="muted">Gate alerts</span><b class="${{alerts.length ? "warn" : "ok"}}">${{alerts.length}}</b></div>`
|
|
641
691
|
].join(""));
|
|
642
|
-
put("owner", ownerQueue.length ? ownerQueue.map(item => `<div class="row"><div class="line"><a href="${{esc(href(item.url))}}">#${{esc(item.pr_number)}} ${{esc(item.kind)}}</a>${{pill(item.next_action)}}${{pill(item.head_sha_prefix)}}</div><div class="muted">${{esc(item.branch)}} by ${{esc(item.author)}} updated ${{
|
|
643
|
-
put("agents", agentCards.length ? agentCards.map(agent => `<div class="row"><div class="line"><b>${{esc(agent.provider)}}</b>${{pill(agent.role)}}${{pill(agent.status)}}${{agent.lane ? pill(agent.lane) : ""}}${{agent.pr_number ? pill(`#${{agent.pr_number}}`) : ""}}</div><div>${{esc(agent.title || agent.next_action || "local agent")}}</div><div class="muted">${{esc(agent.branch || agent.repo || "")}}${{agent.pid ? ` pid=${{esc(agent.pid)}}` : ""}}${{agent.cwd ? ` cwd=${{esc(agent.cwd)}}` : ""}}${{agent.updated_at ? ` updated ${{
|
|
692
|
+
put("owner", ownerQueue.length ? ownerQueue.map(item => `<div class="row"><div class="line"><a href="${{esc(href(item.url))}}">#${{esc(item.pr_number)}} ${{esc(item.kind)}}</a>${{pill(item.next_action)}}${{pill(item.head_sha_prefix)}}</div><div class="muted">${{esc(item.branch)}} by ${{esc(item.author)}}${{item.updated_at ? ` updated ${{localTime(item.updated_at)}}` : ""}}</div></div>`).join("") : empty(data.owner_queue?.message || "No owner queue items."));
|
|
693
|
+
put("agents", agentCards.length ? agentCards.map(agent => `<div class="row"><div class="line"><b>${{esc(agent.provider)}}</b>${{pill(agent.role)}}${{pill(agent.status)}}${{agent.lane ? pill(agent.lane) : ""}}${{agent.pr_number ? pill(`#${{agent.pr_number}}`) : ""}}</div><div>${{esc(agent.title || agent.next_action || "local agent")}}</div><div class="muted">${{esc(agent.branch || agent.repo || "")}}${{agent.pid ? ` pid=${{esc(agent.pid)}}` : ""}}${{agent.cwd ? ` cwd=${{esc(agent.cwd)}}` : ""}}${{agent.updated_at ? ` updated ${{localTime(agent.updated_at)}}` : ""}}</div></div>`).join("") : empty(data.agent_adapters?.message || "No local agent adapter cards."));
|
|
644
694
|
put("prs", prs.length ? prs.map(pr => `<div class="row">
|
|
645
695
|
<div class="line"><a href="${{esc(href(pr.url))}}">#${{esc(pr.number)}} ${{esc(pr.title)}}</a>${{pill(pr.merge_state)}}${{pr.is_draft ? pill("draft") : ""}}${{pr.stale ? pill("stale") : ""}}</div>
|
|
646
|
-
<div class="muted">${{esc(pr.branch)}} by ${{esc(pr.author)}} updated ${{
|
|
696
|
+
<div class="muted">${{esc(pr.branch)}} by ${{esc(pr.author)}}${{pr.updated_at ? ` updated ${{localTime(pr.updated_at)}}` : ""}}</div>
|
|
647
697
|
<div>labels: ${{labels(pr.labels)}}</div>
|
|
648
698
|
<div>checks: ${{checks(pr.checks)}}</div>
|
|
649
699
|
<div>next: <b>${{esc(pr.next_action)}}</b></div>
|
|
650
700
|
</div>`).join("") : empty("No open pull requests."));
|
|
651
701
|
put("alerts", alerts.length ? alerts.map(a => `<div class="row"><b class="warn">${{esc(a.kind)}}</b> ${{esc(a.message)}}</div>`).join("") : empty("No gate alerts."));
|
|
652
|
-
put("runs", runs.length ? runs.slice(0, 8).map(run => `<div class="row"><div class="line"><a href="${{esc(href(run.url))}}">${{esc(run.workflow || "workflow")}}</a>${{pill(run.conclusion || run.status || "unknown")}}</div><div class="muted">${{esc(run.branch)}} updated ${{
|
|
653
|
-
put("verdicts", verdicts.length ? verdicts.map(v => `<div class="row"><div class="line"><a href="${{esc(href(v.url))}}">#${{esc(v.pr_number)}} ${{esc(v.lane)}}</a>${{pill(v.verdict)}}${{pill(v.head_sha_prefix)}}</div><div class="muted">${{
|
|
702
|
+
put("runs", runs.length ? runs.slice(0, 8).map(run => `<div class="row"><div class="line"><a href="${{esc(href(run.url))}}">${{esc(run.workflow || "workflow")}}</a>${{pill(run.conclusion || run.status || "unknown")}}</div><div class="muted">${{esc(run.branch)}}${{run.updated_at ? ` updated ${{localTime(run.updated_at)}}` : ""}}</div></div>`).join("") : empty("No recent Code Mower workflow runs."));
|
|
703
|
+
put("verdicts", verdicts.length ? verdicts.map(v => `<div class="row"><div class="line"><a href="${{esc(href(v.url))}}">#${{esc(v.pr_number)}} ${{esc(v.lane)}}</a>${{pill(v.verdict)}}${{pill(v.head_sha_prefix)}}</div><div class="muted">${{localTime(v.created_at)}}</div></div>`).join("") : empty(timelines.verdicts?.message || "No local reviewer verdict history yet."));
|
|
654
704
|
const spendRows = [
|
|
655
705
|
...spendGroups.map(g => `<div class="row"><div class="line"><b>${{esc(g.lane)}}</b>${{pill(g.verdict)}}${{pill(`${{g.runs}} runs`)}}</div><div class="muted">${{seconds(g.wall_seconds_total)}} total / ${{seconds(g.wall_seconds_avg)}} avg / ${{money(g.cost_usd_total)}} / ${{esc(g.total_tokens || 0)}} tokens</div></div>`),
|
|
656
706
|
spend.skipped_rows ? `<div class="row muted">Skipped ${{esc(spend.skipped_rows)}} malformed spend row(s).</div>` : "",
|
|
@@ -666,7 +716,7 @@ def render_board_html(config: BoardConfig) -> str:
|
|
|
666
716
|
put("history", events.length ? events.slice().reverse().map(event => {{
|
|
667
717
|
const s = event.summary || {{}};
|
|
668
718
|
const remote = s.remote_available ? "remote available" : "remote unavailable";
|
|
669
|
-
return `<div class="row"><div class="line"><b>${{
|
|
719
|
+
return `<div class="row"><div class="line"><b>${{localTime(event.created_at)}}</b>${{pill(remote)}}</div><div>next: <b>${{esc(s.next_action || "inspect")}}</b></div><div class="muted">PRs ${{esc(s.open_prs ?? 0)}} / alerts ${{esc(s.gate_alerts ?? 0)}} / local ${{esc((s.local_boards ?? 0) + (s.local_processes ?? 0))}}</div></div>`;
|
|
670
720
|
}}).join("") : empty(history.message || "No local board events recorded yet."));
|
|
671
721
|
}}
|
|
672
722
|
async function load() {{
|
|
@@ -781,6 +831,9 @@ def serve(config: BoardConfig, *, open_browser: bool = False) -> int:
|
|
|
781
831
|
if not _is_loopback(config.host):
|
|
782
832
|
print("error: board host must be loopback; use 127.0.0.1 or localhost", file=sys.stderr)
|
|
783
833
|
return 2
|
|
834
|
+
if not 0 <= config.port <= 65535:
|
|
835
|
+
print("error: --port must be between 0 and 65535", file=sys.stderr)
|
|
836
|
+
return 2
|
|
784
837
|
if config.record_interval_seconds < 0:
|
|
785
838
|
print("error: --record-interval-seconds must be non-negative", file=sys.stderr)
|
|
786
839
|
return 2
|
|
@@ -791,10 +844,14 @@ def serve(config: BoardConfig, *, open_browser: bool = False) -> int:
|
|
|
791
844
|
print("error: --max-events must be at least 1", file=sys.stderr)
|
|
792
845
|
return 2
|
|
793
846
|
handler = make_handler(config)
|
|
794
|
-
|
|
795
|
-
|
|
847
|
+
server = _bind_board_server(config, handler)
|
|
848
|
+
if server is None:
|
|
849
|
+
return 2
|
|
850
|
+
with server:
|
|
796
851
|
port = int(server.server_address[1])
|
|
797
852
|
url = _server_url(config.host, port)
|
|
853
|
+
if config.port_was_default and port != config.port:
|
|
854
|
+
print(f"Code Mower Board: default port {config.port} was busy; using {port}", file=sys.stderr)
|
|
798
855
|
print(f"Code Mower Board: {url}", flush=True)
|
|
799
856
|
if open_browser:
|
|
800
857
|
webbrowser.open(url)
|
|
@@ -1057,22 +1114,32 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
1057
1114
|
subparsers = parser.add_subparsers(dest="command", required=True)
|
|
1058
1115
|
serve_parser = subparsers.add_parser("serve")
|
|
1059
1116
|
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("--
|
|
1117
|
+
serve_parser.add_argument("--host", default=DEFAULT_HOST, help="loopback host to bind; default: 127.0.0.1")
|
|
1118
|
+
serve_parser.add_argument(
|
|
1119
|
+
"--port",
|
|
1120
|
+
type=int,
|
|
1121
|
+
default=None,
|
|
1122
|
+
help="loopback port; the default auto-falls forward when busy",
|
|
1123
|
+
)
|
|
1124
|
+
serve_parser.add_argument("--pr-limit", type=int, default=50, help="open PRs to show")
|
|
1125
|
+
serve_parser.add_argument("--workflow-limit", type=int, default=20, help="recent Code Mower workflow runs to show")
|
|
1126
|
+
serve_parser.add_argument("--stale-minutes", type=int, default=30, help="minutes before gate evidence is stale")
|
|
1127
|
+
serve_parser.add_argument("--refresh-seconds", type=int, default=15, help="browser refresh interval")
|
|
1128
|
+
serve_parser.add_argument("--show-local-paths", action="store_true", help="show local cwd paths for debugging")
|
|
1129
|
+
serve_parser.add_argument("--repo-path", default=".", help="repository checkout used for local Board files")
|
|
1130
|
+
serve_parser.add_argument("--store-path", help="custom local Board event store path")
|
|
1131
|
+
serve_parser.add_argument("--spend-path", help="custom reviewer spend ledger path")
|
|
1132
|
+
serve_parser.add_argument("--agent-adapters-path", help="custom local agent card directory")
|
|
1133
|
+
serve_parser.add_argument("--event-limit", type=int, default=20, help="local history events to show")
|
|
1134
|
+
serve_parser.add_argument("--record-events", action="store_true", help="append local history while the Board is open")
|
|
1135
|
+
serve_parser.add_argument("--record-interval-seconds", type=int, default=60, help="minimum seconds between records")
|
|
1136
|
+
serve_parser.add_argument(
|
|
1137
|
+
"--retention-days",
|
|
1138
|
+
type=int,
|
|
1139
|
+
default=board_store.DEFAULT_RETENTION_DAYS,
|
|
1140
|
+
help="local history retention window",
|
|
1141
|
+
)
|
|
1142
|
+
serve_parser.add_argument("--max-events", type=int, default=board_store.DEFAULT_MAX_EVENTS, help="maximum local events")
|
|
1076
1143
|
serve_parser.add_argument("--open", action="store_true", help="open the local board in a browser")
|
|
1077
1144
|
record_parser = subparsers.add_parser("record")
|
|
1078
1145
|
record_parser.add_argument("--repo", required=True)
|
|
@@ -1115,7 +1182,8 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
1115
1182
|
BoardConfig(
|
|
1116
1183
|
repo=args.repo,
|
|
1117
1184
|
host=args.host,
|
|
1118
|
-
port=args.port,
|
|
1185
|
+
port=DEFAULT_PORT if args.port is None else args.port,
|
|
1186
|
+
port_was_default=args.port is None,
|
|
1119
1187
|
pr_limit=args.pr_limit,
|
|
1120
1188
|
workflow_limit=args.workflow_limit,
|
|
1121
1189
|
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,
|
|
@@ -13,6 +13,7 @@ from .cloud import (
|
|
|
13
13
|
token_file_mentions_cloud_token,
|
|
14
14
|
)
|
|
15
15
|
from .adoption import (
|
|
16
|
+
check_adoption_posture_guidance,
|
|
16
17
|
check_adoption_setup,
|
|
17
18
|
config_with_repository_target,
|
|
18
19
|
detect_repo_slug,
|
|
@@ -31,6 +32,7 @@ from .github_human_token import (
|
|
|
31
32
|
human_automation_token_config,
|
|
32
33
|
human_automation_token_required,
|
|
33
34
|
)
|
|
35
|
+
from .github_trusted_authors import trusted_author_variable_statuses
|
|
34
36
|
from .groups import GROUP_LABELS, doctor_check_group_id
|
|
35
37
|
from .models import (
|
|
36
38
|
STATUS_FAIL,
|
|
@@ -105,11 +107,13 @@ __all__ = [
|
|
|
105
107
|
"auth_probe_output_detail",
|
|
106
108
|
"build_doctor_run_plan",
|
|
107
109
|
"check_cloud_token_surface",
|
|
110
|
+
"check_adoption_posture_guidance",
|
|
108
111
|
"check_adoption_setup",
|
|
109
112
|
"check_github_auth_surface",
|
|
110
113
|
"check_macos_runner_launchagent",
|
|
111
114
|
"check_github_setup",
|
|
112
115
|
"check_human_automation_token",
|
|
116
|
+
"trusted_author_variable_statuses",
|
|
113
117
|
"check_repository_posture",
|
|
114
118
|
"check_lane_runtime",
|
|
115
119
|
"check_review_hygiene",
|