code-mower 0.5.0b6__tar.gz → 0.5.0b8__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.5.0b6/src/code_mower.egg-info → code_mower-0.5.0b8}/PKG-INFO +13 -6
- code_mower-0.5.0b6/PKG-INFO → code_mower-0.5.0b8/README.md +12 -17
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/pyproject.toml +1 -1
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/__init__.py +1 -1
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/cloud.py +1 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/cloud_client/operations.py +60 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/models.py +25 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/output.py +13 -0
- code_mower-0.5.0b6/README.md → code_mower-0.5.0b8/src/code_mower.egg-info/PKG-INFO +24 -5
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/tests/test_cloud_client.py +54 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/tests/test_doctor_output.py +13 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/tests/test_doctor_registry.py +8 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/tests/test_release_hygiene.py +39 -34
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/CODE_OF_CONDUCT.md +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/LICENSE +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/MANIFEST.in +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/NOTICE +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/SUPPORT.md +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/requirements/requirements.txt +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/setup.cfg +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/adapters/__init__.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/adapters/_base.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/adapters/cursor_bugbot.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/adapters/gitar.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/adapters/greptile.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/adapters/qodo.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/antigravity_cli_audit_pr.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/audit_handoff_log.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/audit_labeler_lib.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/audit_progress.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/blind_review_artifacts.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/blind_review_coordinator.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/bootstrap.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/builder_experiment.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/calibration/__init__.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/calibration/arms.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/calibration/auto_discovery.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/calibration/commands.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/calibration/context_inputs.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/calibration/corpus.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/calibration/evidence.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/calibration/evidence_report.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/calibration/identity.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/calibration/metrics.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/calibration/overlap.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/calibration/planning.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/calibration/policy.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/calibration/results.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/calibration/run_results.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/calibration/run_status.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/calibration/runner.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/calibration/truth.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/calibration/value_report.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/checks.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/claude_audit_pr.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/claude_cli_bounce.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/claude_cli_environment.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/clear_stale.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/cli.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/cloud_client/__init__.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/cloud_client/bundle.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/cloud_client/doctor.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/cloud_client/dogfood.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/cloud_client/endpoints.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/cloud_client/errors.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/cloud_client/events.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/cloud_client/export.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/cloud_client/git_metadata.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/cloud_client/manifest.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/cloud_client/reports.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/cloud_client/setup.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/cloud_client/upload.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/code_mower_calibration.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/code_mower_context_packs.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/code_mower_merge.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/code_mower_telemetry.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/coderabbit_cli_audit_pr.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/codex_audit_env_preflight.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/codex_audit_pr.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/codex_audit_schema_smoke.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/codex_audit_verdict.schema.json +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/config.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/__init__.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/cloud.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/common.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/github.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/github_actions.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/github_actions_cost.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/github_actions_cost_summary.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/github_actions_failure_annotations.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/github_actions_failure_models.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/github_actions_failure_scan.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/github_actions_failure_selection.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/github_actions_failures.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/github_actions_permissions.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/github_api.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/github_branch.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/github_config.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/github_provider.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/github_repo.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/groups.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/presets.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/privacy.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/provider_api_model.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/provider_api_model_openai.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/provider_api_model_profiles.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/provider_env.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/provider_env_required.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/provider_env_tokens.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/provider_local_cli.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/provider_local_cli_commands.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/provider_local_cli_probe_config.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/provider_probe.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/provider_probe_auth.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/provider_probe_evaluation.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/provider_probe_json.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/provider_probe_remediation.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/providers.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/registry.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/runner.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/runtime.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/doctor_checks/runtime_github_auth.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/gemini_cli_audit_pr.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/hermes_cli_audit_pr.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/init.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/lane_configs/__init__.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/lane_configs/aider.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/lane_configs/antigravity_cli.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/lane_configs/claude.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/lane_configs/codex.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/lane_configs/devin.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/lane_configs/gemini_cli.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/lane_configs/hermes_cli.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/lane_configs/local_llm.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/local_llm_audit_pr.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/local_llm_bakeoff.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/local_llm_calibration.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/local_llm_profiles.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/migration.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/migration_install.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/migration_mirror.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/migration_readiness.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/migration_rehearsal.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/next_steps.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/package.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/package_content.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/package_manifest.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/package_paths.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/package_rendering.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/package_static.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/prompts.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/provider_registry.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/provider_runners/__init__.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/provider_runners/comments.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/provider_runners/git.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/provider_runners/github_auth.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/provider_runners/github_pr.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/provider_runners/process.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/provider_runners/repo_paths.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/provider_runners/text_schema.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/provider_runners/verdict_artifacts.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/provider_runners/workspace.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/release_readiness.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/reviewer_metrics.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/saas_reviewer_labeler.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/secrets.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/templates/builder-experiment.example.json +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/templates/calibration-corpus.example.json +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/templates/calibration-corpus.json +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/templates/code-mower.example.yml +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/templates/context-packs.example.json +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/templates/lane_prompts/base-audit.md +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/templates/lane_prompts/calibration-policy.md +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/templates/lane_prompts/context-driven-quality.md +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/templates/lane_prompts/docs-design.md +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/templates/lane_prompts/generic-programming.md +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/templates/lane_prompts/operability.md +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/templates/lane_prompts/package-runtime.md +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/templates/lane_prompts/security-threat-model.md +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/templates/product-support/code_mower +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/templates/product-support/code_mower_standalone_pin.env +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/templates/product-support/code_mower_standalone_shadow.sh +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/templates/product-support/run_claude_audit_pr.sh +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/templates/product-support/run_codex_audit_pr.sh +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/templates/product-support/safe_gh_comment.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/templates/providers.yml +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/templates/reviewer-spend.example.json +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/templates/reviewer-value-report.example.md +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/templates/workflows/private-standalone-shadow.yml.j2 +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/templates/workflows/review-clear-stale.yml.j2 +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/trailer_comment_labeler.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower/versioning.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower.egg-info/SOURCES.txt +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower.egg-info/dependency_links.txt +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower.egg-info/entry_points.txt +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower.egg-info/requires.txt +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/src/code_mower.egg-info/top_level.txt +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/templates/builder-experiment.example.json +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/templates/calibration-corpus.example.json +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/templates/calibration-corpus.json +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/templates/code-mower.yml.j2 +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/templates/context-packs.example.json +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/templates/cursor/BUGBOT.md +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/templates/providers/acp_bridge.yml +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/templates/providers/aider.yml +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/templates/providers/antigravity_cli.yml +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/templates/providers/claude_audit.yml +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/templates/providers/claude_review.yml +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/templates/providers/coderabbit_cli.yml +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/templates/providers/codex.yml +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/templates/providers/cursor_bugbot.yml +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/templates/providers/devin.yml +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/templates/providers/gemini_cli.yml +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/templates/providers/gitar.yml +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/templates/providers/greptile.yml +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/templates/providers/hermes_cli.yml +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/templates/providers/local_llm.yml +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/templates/providers/qodo.yml +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/templates/providers.yml +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/templates/reviewer-spend.example.json +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/templates/reviewer-value-report.example.md +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/templates/workflows/audit-label-cleanup.yml.j2 +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/templates/workflows/blind-review-artifacts-dry-run.yml.j2 +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/templates/workflows/hosted-bridge.yml.j2 +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/templates/workflows/local-cli-audit.yml.j2 +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/templates/workflows/private-standalone-shadow.yml.j2 +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/templates/workflows/review-clear-stale.yml.j2 +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/templates/workflows/saas-reviewer-labeler.yml.j2 +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/templates/workflows/trailer-comment-labeler.yml.j2 +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/tests/test_calibration_truth.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/tests/test_checks.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/tests/test_claude_cli_bounce.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/tests/test_clear_stale.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/tests/test_cloud_git_metadata.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/tests/test_cloud_manifest.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/tests/test_cloud_reports.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/tests/test_coderabbit_cli_audit_pr.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/tests/test_doctor_actions_cost_summary.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/tests/test_doctor_actions_failure_selection.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/tests/test_doctor_boundaries.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/tests/test_doctor_github_checks.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/tests/test_doctor_privacy.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/tests/test_doctor_provider_env_required.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/tests/test_doctor_provider_env_tokens.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/tests/test_doctor_provider_probe.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/tests/test_local_llm_github_helpers.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/tests/test_provider_runners_comments.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/tests/test_provider_runners_git.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/tests/test_provider_runners_github_pr.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/tests/test_provider_runners_process.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/tests/test_provider_runners_repo_paths.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/tests/test_provider_runners_text_schema.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/tests/test_provider_runners_workspace.py +0 -0
- {code_mower-0.5.0b6 → code_mower-0.5.0b8}/tests/test_reviewer_metrics_core.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: code-mower
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.0b8
|
|
4
4
|
Summary: Multi-reviewer AI code audit orchestration
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
Requires-Python: >=3.11
|
|
@@ -98,11 +98,11 @@ Code Mower currently targets Python 3.11+; Python 3.12 is recommended.
|
|
|
98
98
|
|
|
99
99
|
```bash
|
|
100
100
|
python3.12 --version
|
|
101
|
-
pipx install --python python3.12 code-mower==0.5.
|
|
101
|
+
pipx install --python python3.12 code-mower==0.5.0b8
|
|
102
102
|
code-mower --version
|
|
103
103
|
```
|
|
104
104
|
|
|
105
|
-
`0.5.
|
|
105
|
+
`0.5.0b8` is a beta release. Until Code Mower publishes a stable `1.0`
|
|
106
106
|
line, use the explicit beta version above or allow prereleases with:
|
|
107
107
|
|
|
108
108
|
```bash
|
|
@@ -174,7 +174,8 @@ The cloud value loop is:
|
|
|
174
174
|
2. inspect the metadata-only bundle or dogfood preview;
|
|
175
175
|
3. upload only with `--yes`; and
|
|
176
176
|
4. use [CodeMower.com](https://codemower.com) to see repo rollups, provider/lens
|
|
177
|
-
signal, cost/latency, noisy lanes,
|
|
177
|
+
signal, cost/latency, noisy lanes, next-lane recommendations, and
|
|
178
|
+
token-safe evidence/detail pages over time.
|
|
178
179
|
|
|
179
180
|
Start with a dry run:
|
|
180
181
|
|
|
@@ -184,6 +185,12 @@ code-mower cloud dogfood --json
|
|
|
184
185
|
|
|
185
186
|
Nothing uploads unless you pass `--yes`.
|
|
186
187
|
|
|
188
|
+
Current dogfood uploads, historical catch-up imports, and calibrated
|
|
189
|
+
reviewer/lens evidence are intentionally separate. Imported GitHub Actions
|
|
190
|
+
history can prove activity and upload health; it should not be treated as
|
|
191
|
+
reviewer-quality evidence until it is calibrated against known-clean and
|
|
192
|
+
known-blocked cases.
|
|
193
|
+
|
|
187
194
|
To connect to [CodeMower.com](https://codemower.com), sign in at
|
|
188
195
|
[https://codemower.com/login](https://codemower.com/login), create or receive a
|
|
189
196
|
team token, then run:
|
|
@@ -239,9 +246,9 @@ best?" to "which AI builder plus reviewer loop ships best on this product?" See
|
|
|
239
246
|
|
|
240
247
|
## Installation Status
|
|
241
248
|
|
|
242
|
-
The current public beta is `v0.5.0-beta.
|
|
249
|
+
The current public beta is `v0.5.0-beta.8` from
|
|
243
250
|
[codemower-ai/code-mower](https://github.com/codemower-ai/code-mower), and it
|
|
244
|
-
is published as `code-mower==0.5.
|
|
251
|
+
is published as `code-mower==0.5.0b8` on
|
|
245
252
|
[PyPI](https://pypi.org/project/code-mower/). GitHub releases remain the
|
|
246
253
|
auditable source for tags, build artifacts, and release notes.
|
|
247
254
|
|
|
@@ -1,15 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: code-mower
|
|
3
|
-
Version: 0.5.0b6
|
|
4
|
-
Summary: Multi-reviewer AI code audit orchestration
|
|
5
|
-
License-Expression: Apache-2.0
|
|
6
|
-
Requires-Python: >=3.11
|
|
7
|
-
Description-Content-Type: text/markdown
|
|
8
|
-
License-File: LICENSE
|
|
9
|
-
License-File: NOTICE
|
|
10
|
-
Requires-Dist: PyYAML>=6.0
|
|
11
|
-
Dynamic: license-file
|
|
12
|
-
|
|
13
1
|
# Code Mower
|
|
14
2
|
|
|
15
3
|
Code Mower helps teams set up AI peer-programmer and reviewer lanes on real
|
|
@@ -98,11 +86,11 @@ Code Mower currently targets Python 3.11+; Python 3.12 is recommended.
|
|
|
98
86
|
|
|
99
87
|
```bash
|
|
100
88
|
python3.12 --version
|
|
101
|
-
pipx install --python python3.12 code-mower==0.5.
|
|
89
|
+
pipx install --python python3.12 code-mower==0.5.0b8
|
|
102
90
|
code-mower --version
|
|
103
91
|
```
|
|
104
92
|
|
|
105
|
-
`0.5.
|
|
93
|
+
`0.5.0b8` is a beta release. Until Code Mower publishes a stable `1.0`
|
|
106
94
|
line, use the explicit beta version above or allow prereleases with:
|
|
107
95
|
|
|
108
96
|
```bash
|
|
@@ -174,7 +162,8 @@ The cloud value loop is:
|
|
|
174
162
|
2. inspect the metadata-only bundle or dogfood preview;
|
|
175
163
|
3. upload only with `--yes`; and
|
|
176
164
|
4. use [CodeMower.com](https://codemower.com) to see repo rollups, provider/lens
|
|
177
|
-
signal, cost/latency, noisy lanes,
|
|
165
|
+
signal, cost/latency, noisy lanes, next-lane recommendations, and
|
|
166
|
+
token-safe evidence/detail pages over time.
|
|
178
167
|
|
|
179
168
|
Start with a dry run:
|
|
180
169
|
|
|
@@ -184,6 +173,12 @@ code-mower cloud dogfood --json
|
|
|
184
173
|
|
|
185
174
|
Nothing uploads unless you pass `--yes`.
|
|
186
175
|
|
|
176
|
+
Current dogfood uploads, historical catch-up imports, and calibrated
|
|
177
|
+
reviewer/lens evidence are intentionally separate. Imported GitHub Actions
|
|
178
|
+
history can prove activity and upload health; it should not be treated as
|
|
179
|
+
reviewer-quality evidence until it is calibrated against known-clean and
|
|
180
|
+
known-blocked cases.
|
|
181
|
+
|
|
187
182
|
To connect to [CodeMower.com](https://codemower.com), sign in at
|
|
188
183
|
[https://codemower.com/login](https://codemower.com/login), create or receive a
|
|
189
184
|
team token, then run:
|
|
@@ -239,9 +234,9 @@ best?" to "which AI builder plus reviewer loop ships best on this product?" See
|
|
|
239
234
|
|
|
240
235
|
## Installation Status
|
|
241
236
|
|
|
242
|
-
The current public beta is `v0.5.0-beta.
|
|
237
|
+
The current public beta is `v0.5.0-beta.8` from
|
|
243
238
|
[codemower-ai/code-mower](https://github.com/codemower-ai/code-mower), and it
|
|
244
|
-
is published as `code-mower==0.5.
|
|
239
|
+
is published as `code-mower==0.5.0b8` on
|
|
245
240
|
[PyPI](https://pypi.org/project/code-mower/). GitHub releases remain the
|
|
246
241
|
auditable source for tags, build artifacts, and release notes.
|
|
247
242
|
|
|
@@ -601,6 +601,7 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
601
601
|
print(f"Status: {result['status']}")
|
|
602
602
|
print(f"Repository: {result['repo_slug']}")
|
|
603
603
|
print(f"Runs: {result['run_count']}")
|
|
604
|
+
print("Provenance: imported history (not calibration evidence)")
|
|
604
605
|
print(f"Bundle: {result['export']['output_dir']}")
|
|
605
606
|
print(f"Events: {result['export']['event_count']}")
|
|
606
607
|
if result["status"] == "uploaded":
|
|
@@ -23,6 +23,56 @@ from .setup import DEFAULT_INSTALL_ID_ENV, DEFAULT_TEAM_ID_ENV
|
|
|
23
23
|
from .upload import build_upload_payload, post_upload_payload
|
|
24
24
|
|
|
25
25
|
|
|
26
|
+
def build_catch_up_summary(
|
|
27
|
+
*,
|
|
28
|
+
repo_slug: str,
|
|
29
|
+
runs: list[dict[str, Any]],
|
|
30
|
+
events: list[dict[str, Any]],
|
|
31
|
+
requested_limit: int,
|
|
32
|
+
include_git_ref: bool,
|
|
33
|
+
) -> dict[str, Any]:
|
|
34
|
+
"""Summarize imported GitHub Actions history without exposing ref details."""
|
|
35
|
+
|
|
36
|
+
def increment(target: dict[str, int], raw: object) -> None:
|
|
37
|
+
value = str(raw or "").strip() or "unknown"
|
|
38
|
+
target[value] = target.get(value, 0) + 1
|
|
39
|
+
|
|
40
|
+
workflow_counts: dict[str, int] = {}
|
|
41
|
+
status_counts: dict[str, int] = {}
|
|
42
|
+
conclusion_counts: dict[str, int] = {}
|
|
43
|
+
created_values: list[str] = []
|
|
44
|
+
updated_values: list[str] = []
|
|
45
|
+
|
|
46
|
+
for run in runs:
|
|
47
|
+
increment(workflow_counts, run.get("name"))
|
|
48
|
+
increment(status_counts, run.get("status"))
|
|
49
|
+
increment(conclusion_counts, run.get("conclusion"))
|
|
50
|
+
created_at = str(run.get("createdAt") or "").strip()
|
|
51
|
+
updated_at = str(run.get("updatedAt") or "").strip()
|
|
52
|
+
if created_at:
|
|
53
|
+
created_values.append(created_at)
|
|
54
|
+
if updated_at:
|
|
55
|
+
updated_values.append(updated_at)
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
"repo_slug": repo_slug,
|
|
59
|
+
"requested_limit": requested_limit,
|
|
60
|
+
"run_count": len(runs),
|
|
61
|
+
"event_count": len(events),
|
|
62
|
+
"provenance": "imported_history",
|
|
63
|
+
"source_category": "history",
|
|
64
|
+
"history_only": True,
|
|
65
|
+
"calibration_evidence": False,
|
|
66
|
+
"git_ref_included": include_git_ref,
|
|
67
|
+
"workflow_counts": dict(sorted(workflow_counts.items())),
|
|
68
|
+
"status_counts": dict(sorted(status_counts.items())),
|
|
69
|
+
"conclusion_counts": dict(sorted(conclusion_counts.items())),
|
|
70
|
+
"oldest_run_at": min(created_values) if created_values else "",
|
|
71
|
+
"newest_run_at": max(created_values) if created_values else "",
|
|
72
|
+
"last_updated_at": max(updated_values) if updated_values else "",
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
|
|
26
76
|
def dogfood_upload(
|
|
27
77
|
*,
|
|
28
78
|
repo_path: Path,
|
|
@@ -157,6 +207,13 @@ def catch_up_upload(
|
|
|
157
207
|
)
|
|
158
208
|
for run in runs
|
|
159
209
|
]
|
|
210
|
+
catch_up_summary = build_catch_up_summary(
|
|
211
|
+
repo_slug=detected_repo_slug,
|
|
212
|
+
runs=runs,
|
|
213
|
+
events=events,
|
|
214
|
+
requested_limit=limit,
|
|
215
|
+
include_git_ref=include_git_ref,
|
|
216
|
+
)
|
|
160
217
|
export_result = build_cloud_bundle(
|
|
161
218
|
reports=[],
|
|
162
219
|
events=events,
|
|
@@ -178,6 +235,7 @@ def catch_up_upload(
|
|
|
178
235
|
"status": "doctor_failed",
|
|
179
236
|
"repo_slug": detected_repo_slug,
|
|
180
237
|
"run_count": len(runs),
|
|
238
|
+
"catch_up": catch_up_summary,
|
|
181
239
|
"export": export_result,
|
|
182
240
|
"doctor": doctor_result,
|
|
183
241
|
}
|
|
@@ -188,6 +246,7 @@ def catch_up_upload(
|
|
|
188
246
|
"status": "dry_run",
|
|
189
247
|
"repo_slug": detected_repo_slug,
|
|
190
248
|
"run_count": len(runs),
|
|
249
|
+
"catch_up": catch_up_summary,
|
|
191
250
|
"export": export_result,
|
|
192
251
|
"doctor": doctor_result,
|
|
193
252
|
"upload": build_dogfood_dry_run_preview(endpoint=endpoint, payload=payload),
|
|
@@ -202,6 +261,7 @@ def catch_up_upload(
|
|
|
202
261
|
"status": "uploaded",
|
|
203
262
|
"repo_slug": detected_repo_slug,
|
|
204
263
|
"run_count": len(runs),
|
|
264
|
+
"catch_up": catch_up_summary,
|
|
205
265
|
"export": export_result,
|
|
206
266
|
"doctor": doctor_result,
|
|
207
267
|
"upload": post_upload_payload(
|
|
@@ -57,6 +57,30 @@ class DoctorReport:
|
|
|
57
57
|
return STATUS_WARN
|
|
58
58
|
return STATUS_PASS
|
|
59
59
|
|
|
60
|
+
@property
|
|
61
|
+
def run_plan(self) -> tuple[dict[str, Any], ...]:
|
|
62
|
+
"""Return the structured doctor run plan when a report contains one."""
|
|
63
|
+
|
|
64
|
+
for check in self.checks:
|
|
65
|
+
if check.name != "doctor.plan" or not isinstance(check.detail, Mapping):
|
|
66
|
+
continue
|
|
67
|
+
stages = check.detail.get("stages")
|
|
68
|
+
if not isinstance(stages, list):
|
|
69
|
+
return ()
|
|
70
|
+
plan: list[dict[str, Any]] = []
|
|
71
|
+
for stage in stages:
|
|
72
|
+
if not isinstance(stage, Mapping):
|
|
73
|
+
continue
|
|
74
|
+
plan.append(
|
|
75
|
+
{
|
|
76
|
+
"id": str(stage.get("id", "")),
|
|
77
|
+
"group": str(stage.get("group", "")),
|
|
78
|
+
"optional": bool(stage.get("optional", False)),
|
|
79
|
+
}
|
|
80
|
+
)
|
|
81
|
+
return tuple(plan)
|
|
82
|
+
return ()
|
|
83
|
+
|
|
60
84
|
def group_summary(self) -> dict[str, dict[str, int | str]]:
|
|
61
85
|
summary: dict[str, dict[str, int | str]] = {}
|
|
62
86
|
for group_id, label in GROUP_LABELS.items():
|
|
@@ -91,6 +115,7 @@ class DoctorReport:
|
|
|
91
115
|
"failures": self.failures,
|
|
92
116
|
"warnings": self.warnings,
|
|
93
117
|
},
|
|
118
|
+
"run_plan": list(self.run_plan),
|
|
94
119
|
"groups": self.group_summary(),
|
|
95
120
|
"checks": [check.as_dict() for check in self.checks],
|
|
96
121
|
}
|
|
@@ -39,6 +39,16 @@ def _format_status_summary(report: DoctorReport) -> str:
|
|
|
39
39
|
return ", ".join(parts)
|
|
40
40
|
|
|
41
41
|
|
|
42
|
+
def _format_run_plan(report: DoctorReport) -> str | None:
|
|
43
|
+
if not report.run_plan:
|
|
44
|
+
return None
|
|
45
|
+
stages = []
|
|
46
|
+
for stage in report.run_plan:
|
|
47
|
+
suffix = " optional" if stage.get("optional") else ""
|
|
48
|
+
stages.append(f"{stage.get('id', '')} ({stage.get('group', '')}{suffix})")
|
|
49
|
+
return ", ".join(stages)
|
|
50
|
+
|
|
51
|
+
|
|
42
52
|
def _format_check(check: DoctorCheck) -> list[str]:
|
|
43
53
|
lane = f" [{check.lane}]" if check.lane else ""
|
|
44
54
|
lines = [f"- {check.status.upper()} {check.name}{lane}: {check.message}"]
|
|
@@ -57,6 +67,9 @@ def render_doctor_text(report: DoctorReport) -> str:
|
|
|
57
67
|
]
|
|
58
68
|
if report.profile:
|
|
59
69
|
lines.append(f"Profile: {report.profile}")
|
|
70
|
+
run_plan = _format_run_plan(report)
|
|
71
|
+
if run_plan:
|
|
72
|
+
lines.append(f"Run plan: {run_plan}")
|
|
60
73
|
lines.append(f"Checks: {_format_status_summary(report)}")
|
|
61
74
|
lines.append("")
|
|
62
75
|
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: code-mower
|
|
3
|
+
Version: 0.5.0b8
|
|
4
|
+
Summary: Multi-reviewer AI code audit orchestration
|
|
5
|
+
License-Expression: Apache-2.0
|
|
6
|
+
Requires-Python: >=3.11
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
License-File: NOTICE
|
|
10
|
+
Requires-Dist: PyYAML>=6.0
|
|
11
|
+
Dynamic: license-file
|
|
12
|
+
|
|
1
13
|
# Code Mower
|
|
2
14
|
|
|
3
15
|
Code Mower helps teams set up AI peer-programmer and reviewer lanes on real
|
|
@@ -86,11 +98,11 @@ Code Mower currently targets Python 3.11+; Python 3.12 is recommended.
|
|
|
86
98
|
|
|
87
99
|
```bash
|
|
88
100
|
python3.12 --version
|
|
89
|
-
pipx install --python python3.12 code-mower==0.5.
|
|
101
|
+
pipx install --python python3.12 code-mower==0.5.0b8
|
|
90
102
|
code-mower --version
|
|
91
103
|
```
|
|
92
104
|
|
|
93
|
-
`0.5.
|
|
105
|
+
`0.5.0b8` is a beta release. Until Code Mower publishes a stable `1.0`
|
|
94
106
|
line, use the explicit beta version above or allow prereleases with:
|
|
95
107
|
|
|
96
108
|
```bash
|
|
@@ -162,7 +174,8 @@ The cloud value loop is:
|
|
|
162
174
|
2. inspect the metadata-only bundle or dogfood preview;
|
|
163
175
|
3. upload only with `--yes`; and
|
|
164
176
|
4. use [CodeMower.com](https://codemower.com) to see repo rollups, provider/lens
|
|
165
|
-
signal, cost/latency, noisy lanes,
|
|
177
|
+
signal, cost/latency, noisy lanes, next-lane recommendations, and
|
|
178
|
+
token-safe evidence/detail pages over time.
|
|
166
179
|
|
|
167
180
|
Start with a dry run:
|
|
168
181
|
|
|
@@ -172,6 +185,12 @@ code-mower cloud dogfood --json
|
|
|
172
185
|
|
|
173
186
|
Nothing uploads unless you pass `--yes`.
|
|
174
187
|
|
|
188
|
+
Current dogfood uploads, historical catch-up imports, and calibrated
|
|
189
|
+
reviewer/lens evidence are intentionally separate. Imported GitHub Actions
|
|
190
|
+
history can prove activity and upload health; it should not be treated as
|
|
191
|
+
reviewer-quality evidence until it is calibrated against known-clean and
|
|
192
|
+
known-blocked cases.
|
|
193
|
+
|
|
175
194
|
To connect to [CodeMower.com](https://codemower.com), sign in at
|
|
176
195
|
[https://codemower.com/login](https://codemower.com/login), create or receive a
|
|
177
196
|
team token, then run:
|
|
@@ -227,9 +246,9 @@ best?" to "which AI builder plus reviewer loop ships best on this product?" See
|
|
|
227
246
|
|
|
228
247
|
## Installation Status
|
|
229
248
|
|
|
230
|
-
The current public beta is `v0.5.0-beta.
|
|
249
|
+
The current public beta is `v0.5.0-beta.8` from
|
|
231
250
|
[codemower-ai/code-mower](https://github.com/codemower-ai/code-mower), and it
|
|
232
|
-
is published as `code-mower==0.5.
|
|
251
|
+
is published as `code-mower==0.5.0b8` on
|
|
233
252
|
[PyPI](https://pypi.org/project/code-mower/). GitHub releases remain the
|
|
234
253
|
auditable source for tags, build artifacts, and release notes.
|
|
235
254
|
|
|
@@ -28,6 +28,60 @@ from code_mower.cloud_client import (
|
|
|
28
28
|
from code_mower import cloud as cloud_cli
|
|
29
29
|
|
|
30
30
|
|
|
31
|
+
def test_cloud_catch_up_summary_separates_history_from_calibration() -> None:
|
|
32
|
+
runs = [
|
|
33
|
+
{
|
|
34
|
+
"name": "CI",
|
|
35
|
+
"status": "completed",
|
|
36
|
+
"conclusion": "success",
|
|
37
|
+
"createdAt": "2026-06-15T00:00:00Z",
|
|
38
|
+
"updatedAt": "2026-06-15T00:01:00Z",
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"name": "CI",
|
|
42
|
+
"status": "completed",
|
|
43
|
+
"conclusion": "failure",
|
|
44
|
+
"createdAt": "2026-06-16T00:00:00Z",
|
|
45
|
+
"updatedAt": "2026-06-16T00:02:00Z",
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"name": "Dogfood",
|
|
49
|
+
"status": "in_progress",
|
|
50
|
+
"conclusion": "",
|
|
51
|
+
"createdAt": "2026-06-17T00:00:00Z",
|
|
52
|
+
"updatedAt": "2026-06-17T00:03:00Z",
|
|
53
|
+
},
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
summary = cloud_operations.build_catch_up_summary(
|
|
57
|
+
repo_slug="owner/repo",
|
|
58
|
+
runs=runs,
|
|
59
|
+
events=[{"event_type": "workflow_run"} for _ in runs],
|
|
60
|
+
requested_limit=50,
|
|
61
|
+
include_git_ref=False,
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
assert summary["repo_slug"] == "owner/repo"
|
|
65
|
+
assert summary["requested_limit"] == 50
|
|
66
|
+
assert summary["run_count"] == 3
|
|
67
|
+
assert summary["event_count"] == 3
|
|
68
|
+
assert summary["provenance"] == "imported_history"
|
|
69
|
+
assert summary["source_category"] == "history"
|
|
70
|
+
assert summary["history_only"] is True
|
|
71
|
+
assert summary["calibration_evidence"] is False
|
|
72
|
+
assert summary["git_ref_included"] is False
|
|
73
|
+
assert summary["workflow_counts"] == {"CI": 2, "Dogfood": 1}
|
|
74
|
+
assert summary["status_counts"] == {"completed": 2, "in_progress": 1}
|
|
75
|
+
assert summary["conclusion_counts"] == {
|
|
76
|
+
"failure": 1,
|
|
77
|
+
"success": 1,
|
|
78
|
+
"unknown": 1,
|
|
79
|
+
}
|
|
80
|
+
assert summary["oldest_run_at"] == "2026-06-15T00:00:00Z"
|
|
81
|
+
assert summary["newest_run_at"] == "2026-06-17T00:00:00Z"
|
|
82
|
+
assert summary["last_updated_at"] == "2026-06-17T00:03:00Z"
|
|
83
|
+
|
|
84
|
+
|
|
31
85
|
def test_cloud_setup_round_trip_writes_private_file() -> None:
|
|
32
86
|
with tempfile.TemporaryDirectory() as tmp:
|
|
33
87
|
root = Path(tmp)
|
|
@@ -26,6 +26,14 @@ class DoctorOutputTests(unittest.TestCase):
|
|
|
26
26
|
name="doctor.plan",
|
|
27
27
|
status=STATUS_PASS,
|
|
28
28
|
message="doctor run plan: load-inputs, select-profile, runtime, providers",
|
|
29
|
+
detail={
|
|
30
|
+
"stages": [
|
|
31
|
+
{"id": "load-inputs", "group": "runtime", "optional": False},
|
|
32
|
+
{"id": "select-profile", "group": "runtime", "optional": False},
|
|
33
|
+
{"id": "runtime", "group": "runtime", "optional": False},
|
|
34
|
+
{"id": "providers", "group": "providers", "optional": False},
|
|
35
|
+
]
|
|
36
|
+
},
|
|
29
37
|
),
|
|
30
38
|
DoctorCheck(
|
|
31
39
|
name="runtime.python",
|
|
@@ -59,6 +67,11 @@ class DoctorOutputTests(unittest.TestCase):
|
|
|
59
67
|
|
|
60
68
|
rendered = output.render_doctor_text(report)
|
|
61
69
|
|
|
70
|
+
self.assertIn(
|
|
71
|
+
"Run plan: load-inputs (runtime), select-profile (runtime), "
|
|
72
|
+
"runtime (runtime), providers (providers)",
|
|
73
|
+
rendered,
|
|
74
|
+
)
|
|
62
75
|
self.assertIn("Checks: 7 total, 2 warnings, 1 skipped", rendered)
|
|
63
76
|
self.assertLess(rendered.index("Setup"), rendered.index("Runtime"))
|
|
64
77
|
self.assertLess(rendered.index("Runtime"), rendered.index("Provider lanes"))
|
|
@@ -54,6 +54,14 @@ class DoctorRegistryTests(unittest.TestCase):
|
|
|
54
54
|
tuple(stage["id"] for stage in plan_check.detail["stages"]),
|
|
55
55
|
("load-inputs", "select-profile", "runtime", "providers", "github", "cloud"),
|
|
56
56
|
)
|
|
57
|
+
self.assertEqual(
|
|
58
|
+
tuple(stage["id"] for stage in report.run_plan),
|
|
59
|
+
("load-inputs", "select-profile", "runtime", "providers", "github", "cloud"),
|
|
60
|
+
)
|
|
61
|
+
self.assertEqual(
|
|
62
|
+
tuple(stage["id"] for stage in report.as_dict()["run_plan"]),
|
|
63
|
+
("load-inputs", "select-profile", "runtime", "providers", "github", "cloud"),
|
|
64
|
+
)
|
|
57
65
|
|
|
58
66
|
|
|
59
67
|
if __name__ == "__main__":
|