cli-agent-runner 0.2.2__tar.gz → 0.2.3__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.
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/CHANGELOG.md +30 -15
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/PKG-INFO +2 -2
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/README.md +1 -1
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/_version.py +2 -2
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/agent_runtime.py +12 -1
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/builtin_plugins/_constants.py +7 -2
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/hooks.py +10 -6
- cli_agent_runner-0.2.3/agent_runner/presets/kimi.toml +38 -0
- cli_agent_runner-0.2.3/agent_runner/presets/pi.toml +42 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/runner.py +1 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/startup_check.py +16 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/README.md +4 -2
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/architecture.md +3 -3
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/commands.md +1 -1
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/configuration.md +6 -1
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/long-running-agents.md +6 -4
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/migrations/0.1.20.md +10 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/migrations/0.1.23.md +1 -1
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/migrations/0.1.25.md +1 -1
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/migrations/0.1.29.md +1 -1
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/migrations/0.1.30.md +1 -1
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/migrations/0.1.35.md +1 -1
- cli_agent_runner-0.2.3/docs/migrations/0.2.3.md +47 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/plugins.md +3 -3
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/quickstart.md +1 -1
- cli_agent_runner-0.2.3/docs/recipes/kimi.md +119 -0
- cli_agent_runner-0.2.3/docs/recipes/pi.md +106 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/_test_helpers.py +7 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/integration/test_prompt_delivery_stdin.py +4 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/integration/test_scaffold_presets.py +3 -1
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/invariants/test_doc_claims_match_ssot.py +4 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_agent_runtime.py +32 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_agent_runtime_grace.py +6 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_agent_runtime_progress.py +3 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_claude_error_detector.py +30 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_presets.py +17 -1
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_runner.py +39 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_startup_check.py +29 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/.codecov.yml +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/.github/workflows/ci.yml +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/.github/workflows/release.yml +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/.gitignore +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/.vulture-whitelist.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/BACKLOG.md +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/CODE_OF_CONDUCT.md +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/CONTRIBUTING.md +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/LICENSE +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/README.zh.md +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/SECURITY.md +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/__init__.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/_docgen.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/_emit.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/_redact.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/_registry.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/_substrate.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/_throttle.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/api.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/api_types.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/builtin_plugins/__init__.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/builtin_plugins/claude_rate_limit.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/builtin_plugins/codewhale.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/builtin_plugins/default_dirty_handler.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/builtin_plugins/gemini.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/cli/__init__.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/cli/__main__.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/cli/common.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/cli/events_cmd.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/cli/init_cmd.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/cli/install_cmd.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/cli/monitor_cmd.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/cli/peek_cmd.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/cli/round_cmd.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/cli/serve_cmd.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/cli/service_cmd.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/cli/upgrade_cmd.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/config.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/context_store.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/defenses.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/events.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/http_progress.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/lifecycle.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/metrics.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/monitor.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/presets/__init__.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/presets/aider.toml +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/presets/claude.toml +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/presets/codewhale.toml +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/presets/gemini.toml +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/prompt_loader.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/round_log.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/round_view.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/scaffold.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/service_unit.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/vcs_state.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/build.sh +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/events.md +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/migrations/0.1.16.md +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/migrations/0.1.17.md +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/migrations/0.1.19.md +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/migrations/0.1.21.md +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/migrations/0.1.22.md +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/migrations/0.1.24.md +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/migrations/0.1.26.md +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/migrations/0.1.27.md +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/migrations/0.1.28.md +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/migrations/0.1.31.md +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/migrations/0.1.32.md +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/migrations/0.1.33.md +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/migrations/0.1.34.md +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/migrations/0.1.36.md +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/migrations/0.1.37.md +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/migrations/0.1.38.md +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/migrations/0.1.39.md +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/migrations/0.1.40.md +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/migrations/0.1.42.md +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/migrations/0.2.0.md +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/migrations/0.2.1.md +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/migrations/0.2.2.md +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/recipes/aider.md +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/recipes/codewhale.md +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/runbook.md +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/docs/thesis.md +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/pyproject.toml +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/__init__.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/conftest.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/contract/__init__.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/contract/test_public_api_surface.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/e2e/__init__.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/e2e/conftest.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/e2e/test_e2e_graceful_stop.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/e2e/test_e2e_install_systemd.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/e2e/test_e2e_monitor_remote.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/e2e/test_e2e_round_lifecycle.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/fixtures/cli-real-output/claude-2.1.143-assistant-tool-use.jsonl +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/fixtures/cli-real-output/claude-2.1.143-result-event.jsonl +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/fixtures/cli-real-output/gemini-0.42.0-result-event.jsonl +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/generate_vulture_whitelist.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/integration/__init__.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/integration/test_bounded_run.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/integration/test_context_enricher_namespacing.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/integration/test_dirty_handler_seam.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/integration/test_fresh_eyes_signal.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/integration/test_grace_kill_emission.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/integration/test_install_dry_run.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/integration/test_monitor_seeded.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/integration/test_plugin_detector_loaded.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/integration/test_plugin_owned_paths.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/integration/test_plugin_real_flow.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/integration/test_run_one_round_with_fake_agent.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/integration/test_serve_loop.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/integration/test_substrate_fingerprint.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/integration/test_transient_error_backoff.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/invariants/__init__.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/invariants/_event_scan.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/invariants/test_architecture.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/invariants/test_atomic_write_enforced.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/invariants/test_auto_stop_policy_ssot.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/invariants/test_catalogs.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/invariants/test_classification_ssot.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/invariants/test_config_error_consistency.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/invariants/test_config_value_set_ssot.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/invariants/test_doc_builtin_plugins.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/invariants/test_doc_cli_claims.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/invariants/test_doc_operator_surface.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/invariants/test_doc_transient_error_claims.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/invariants/test_docs_generated.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/invariants/test_docs_index_complete.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/invariants/test_entry_points_resolve.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/invariants/test_event_kind_registry.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/invariants/test_event_kinds_ssot.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/invariants/test_events_doc_contract.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/invariants/test_hook_contract_docs.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/invariants/test_layer_2_loop_size.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/invariants/test_module_boundaries.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/invariants/test_module_sizes.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/invariants/test_no_ai_signatures.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/invariants/test_no_pytest_skip_on_parse_fail.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/invariants/test_peek_schema_version.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/invariants/test_plugins_config_stable.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/invariants/test_readme_zh_is_pointer.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/invariants/test_repo_constants_patched_in_tests.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/invariants/test_round_result_stable.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/invariants/test_set_diff_for_auto_tool_classification.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/invariants/test_stash_uses_sha_not_index.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/invariants/test_upstream_schema_canary.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/invariants/test_vulture_whitelist_generated.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/literate/__init__.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/literate/parser.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/literate/test_parser.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/literate/test_quickstart.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/__init__.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_agent_runtime_signal_name.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_api_assemble_prompt.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_api_events_stream.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_api_install.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_api_observation.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_api_read_round_num.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_api_resolve_phase.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_api_service.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_api_types.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_auto_stop_gating.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_catalogs.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_cli.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_cli_common.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_cli_init_install.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_cli_monitor_http.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_cli_service_peek_monitor.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_cli_upgrade.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_codewhale_plugin.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_config.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_config_fresh_eyes.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_config_max_rounds.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_config_prompt_delivery.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_config_stop_file.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_config_substrate_fingerprint_paths.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_config_transient_error_action.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_context_store.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_default_dirty_handler.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_defenses.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_detector_protocol.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_dirty_handlers.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_docgen.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_events.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_events_cmd.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_events_cmd_tail.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_exit_cause.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_fresh_eyes_trigger.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_gemini_plugin.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_hook_failure_isolation.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_hooks.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_http_progress.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_init_entry_points.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_lifecycle.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_metrics.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_monitor_assembly.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_monitor_detect_anomaly_repetitive.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_monitor_detect_rate_limit.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_monitor_detect_supervisor_stale.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_monitor_detectors.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_monitor_remote.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_network_blip_signal_guard.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_peek_argparse.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_peek_select.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_prompt_loader.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_redact.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_round_log_helpers.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_round_view.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_runner_throttle.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_scaffold.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_serve_cmd_bounded.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_serve_config_broken.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_serve_crash_loop.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_serve_round_log.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_serve_sentinel.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_serve_startup_hooks.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_service_unit.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_substrate.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_throttle_plugin_classification.py +0 -0
- {cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/tests/unit/test_vcs_state.py +0 -0
|
@@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.2.3] - 2026-07-26
|
|
9
|
+
|
|
10
|
+
Details: [docs/migrations/0.2.3.md](docs/migrations/0.2.3.md)
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- `--preset kimi` — a preset for [Kimi Code CLI](https://github.com/MoonshotAI/kimi-code) (`kimi -p --output-format stream-json`). `docs/recipes/kimi.md` also documents running Kimi K3 through the existing `claude` preset via Moonshot's Anthropic-compatible endpoint.
|
|
14
|
+
- `--preset pi` — a preset for [Pi Coding Agent](https://github.com/earendil-works/pi) (`pi -p -na --mode json --model …`; `-na` pins project trust off for unattended runs). `docs/recipes/pi.md` documents driving Kimi K3 through pi via a Moonshot OpenAI-compatible provider.
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
- The agent subprocess now runs in `runtime.work_dir` (`cwd=` on spawn). Previously it inherited the supervisor's cwd and only launch conventions (systemd `WorkingDirectory=`, relative `--config`) kept the two aligned — fatal for agent CLIs with no working-directory flag of their own (e.g. `pi`). The startup check now also validates a relative `agent.command[0]` against `work_dir`, matching where it executes.
|
|
18
|
+
- Plugin round-log tail window widened 50 → 200 lines: a stderr burst after the agent's terminal JSONL event could evict it from the scan window, silently dropping usage/transient classification. The round log's merged stdout+stderr contract is now documented (`HookContext.agent_log_path`, `docs/long-running-agents.md`) — the merge is deliberate; auth/network detection reads stderr text from it.
|
|
19
|
+
|
|
8
20
|
## [0.2.2] - 2026-07-18
|
|
9
21
|
|
|
10
22
|
### Removed
|
|
@@ -386,7 +398,7 @@ See `docs/migrations/0.1.17.md`.
|
|
|
386
398
|
|
|
387
399
|
### Acknowledgements
|
|
388
400
|
|
|
389
|
-
|
|
401
|
+
A downstream integrator's post-Q1-audit feedback (2026-05-14) surfaced the per-phase sub-table need (S3) and the multi-file prompt pattern (S1). Their R721 frontmatter-strip lesson informed making the (already-shipping) strip behavior an explicit opt-out config flag rather than hardcoded.
|
|
390
402
|
|
|
391
403
|
## [0.1.15] - 2026-05-14
|
|
392
404
|
|
|
@@ -418,10 +430,10 @@ independent components bundled into one release because both serve the same
|
|
|
418
430
|
|
|
419
431
|
### Acknowledgements
|
|
420
432
|
|
|
421
|
-
Two of six nice-to-have items surfaced in
|
|
433
|
+
Two of six nice-to-have items surfaced in a downstream integrator's v0.1.12
|
|
422
434
|
production-evaluation report (2026-05-14). An earlier scope also included
|
|
423
435
|
per-phase runtime override; spec review caught that `runtime.round_timeout_per_phase`
|
|
424
|
-
already covers
|
|
436
|
+
already covers the integrator's stated need, so that component was deferred to a future
|
|
425
437
|
release where a second per-phase field surfaces. Other items in the report
|
|
426
438
|
(detector helper, hot-reload, replay) remain intentionally out of scope.
|
|
427
439
|
|
|
@@ -440,7 +452,7 @@ release where a second per-phase field surfaces. Other items in the report
|
|
|
440
452
|
|
|
441
453
|
### Acknowledgements
|
|
442
454
|
|
|
443
|
-
Thanks to
|
|
455
|
+
Thanks to our downstream integrators — this release answers their imminent
|
|
444
456
|
production-deployment requirement for upgrade-without-disruption. After
|
|
445
457
|
confirming round duration (10-40 min) fits within graceful-stop tolerance,
|
|
446
458
|
this release scopes to round-boundary upgrade UX (Level 1). Mid-round
|
|
@@ -465,7 +477,7 @@ real production need.
|
|
|
465
477
|
|
|
466
478
|
### Acknowledgements
|
|
467
479
|
|
|
468
|
-
Thanks to
|
|
480
|
+
Thanks to our downstream integrators for the deep v0.1.10 audit-session feedback
|
|
469
481
|
(6 items, 3-round real-run testing on ARMv8 Pi). This release reframes those
|
|
470
482
|
items into a coherent "Plugin & Operator Transparency" theme across three
|
|
471
483
|
layers: transparency (see what plugins do), operator override (escape hatches
|
|
@@ -487,16 +499,16 @@ for audit/debug), and diagnostic quality (errors point at the next debug step).
|
|
|
487
499
|
|
|
488
500
|
### Migration notes
|
|
489
501
|
|
|
490
|
-
- `Config.plugins` type change is breaking for any caller reading the field as a dict (`cfg.plugins.get("foo")`). Plugin authors using `[plugins.
|
|
502
|
+
- `Config.plugins` type change is breaking for any caller reading the field as a dict (`cfg.plugins.get("foo")`). Plugin authors using `[plugins.acme_*]`-style keys: read them from `cfg.plugins.raw.get("acme_*")` instead.
|
|
491
503
|
- `LockHeldError` message format changed (now includes holder info: `"another agent-runner is holding /path (held by PID N, age Ns, cmd: ...)"` or stale/missing variants). Operators grepping the exact format string need to update.
|
|
492
|
-
- For
|
|
504
|
+
- For the integrator's P5 confusion: see new `docs/architecture.md` section "Plugin injection: two paths" — `inject_context` and `disable_pre_round_hooks` are INDEPENDENT flags. Setting one does not affect the other.
|
|
493
505
|
- **Known limitation**: `[plugins] disable` removes named plugins from the hook / context-enricher / detector / event-kind registries, but does NOT remove a disabled plugin's owned VCS paths (the `register_plugin_owned_paths` registry has no name attribution today). Mostly inert. If this becomes a real issue, file a GitHub issue.
|
|
494
506
|
|
|
495
507
|
## [0.1.11] - 2026-05-13
|
|
496
508
|
|
|
497
509
|
### Acknowledgements
|
|
498
510
|
|
|
499
|
-
Thanks again to
|
|
511
|
+
Thanks again to our downstream integrators — this release closes the
|
|
500
512
|
network-resilience gap that 0.1.10's `MonitorRemoteError` propagation
|
|
501
513
|
exposed, plus adds per-occurrence agent network blip observability requested
|
|
502
514
|
during 0.1.10 handover review.
|
|
@@ -525,7 +537,7 @@ For network-related failures, the events index points at the diagnostic body:
|
|
|
525
537
|
|
|
526
538
|
### Acknowledgements
|
|
527
539
|
|
|
528
|
-
Thanks to
|
|
540
|
+
Thanks to our downstream integrators for the Phase 4 second-pass production feedback that drove every change in this release. Six audit memos across 50 minutes of validated runtime surfaced four specific gaps; this release closes them.
|
|
529
541
|
|
|
530
542
|
### Added
|
|
531
543
|
|
|
@@ -553,7 +565,7 @@ Thanks to the Argus Gateway team for the Phase 4 second-pass production feedback
|
|
|
553
565
|
|
|
554
566
|
### Acknowledgements
|
|
555
567
|
|
|
556
|
-
Thanks to
|
|
568
|
+
Thanks to our downstream integrators for the dev/qa/product wall-time data
|
|
557
569
|
(Phase 4 feedback §3.1) that drove this API shape. Their three-role
|
|
558
570
|
distribution made the case for per-phase overrides concrete.
|
|
559
571
|
|
|
@@ -579,7 +591,7 @@ documented plugin-author public surface.
|
|
|
579
591
|
|
|
580
592
|
### Acknowledgements
|
|
581
593
|
|
|
582
|
-
Thanks to
|
|
594
|
+
Thanks to our downstream integrators for Phase 4 dogfooding feedback that drove
|
|
583
595
|
every item in this release. 3 audit memos (~90KB) silently swept into an
|
|
584
596
|
orphan stash is a real-world failure mode; this release closes that loop.
|
|
585
597
|
|
|
@@ -608,7 +620,7 @@ orphan stash is a real-world failure mode; this release closes that loop.
|
|
|
608
620
|
|
|
609
621
|
- Plugin outputs in plugin-declared paths (e.g. `proposals/`,
|
|
610
622
|
`logs/plugins/my_plugin/`) no longer silently swept into orphan stashes
|
|
611
|
-
by `process_orphan_wip`. Previously: 90KB
|
|
623
|
+
by `process_orphan_wip`. Previously: 90KB audit memos invisible
|
|
612
624
|
after Phase 4 round; required stash archaeology to recover.
|
|
613
625
|
|
|
614
626
|
### Migration
|
|
@@ -651,7 +663,7 @@ Or regenerate cleanly:
|
|
|
651
663
|
agent-runner init --preset claude --force
|
|
652
664
|
```
|
|
653
665
|
|
|
654
|
-
Plugin authors (
|
|
666
|
+
Plugin authors (downstream integrators, etc.): no public API was renamed or removed
|
|
655
667
|
from your import surface. The deleted symbols (`agent_runner.agent_runtime.CRITICAL_ENV_DEFAULTS`,
|
|
656
668
|
`agent_runner.agent_runtime.merge_critical_envs`) were internal — not part of
|
|
657
669
|
the documented plugin API. A new public-API contract test
|
|
@@ -882,7 +894,7 @@ Initial public release on PyPI as `cli-agent-runner`.
|
|
|
882
894
|
|
|
883
895
|
### Added
|
|
884
896
|
- Three-layer model: Round / Loop / Witness.
|
|
885
|
-
-
|
|
897
|
+
- 14 CLI verbs: `init`, `install`, `uninstall`, `start`, `stop`, `kill`,
|
|
886
898
|
`cancel`, `restart`, `status`, `round`, `serve`, `peek`, `watch`, `monitor`.
|
|
887
899
|
- 11 named defenses (round timeout, process group isolation, orphan stash
|
|
888
900
|
with SHA lock, set-diff classification, smoke check, flock concurrency,
|
|
@@ -909,7 +921,10 @@ Initial public release on PyPI as `cli-agent-runner`.
|
|
|
909
921
|
- Tag-triggered release publishing to PyPI via Trusted Publishing OIDC,
|
|
910
922
|
gated by a manual approval on the `pypi` GitHub environment.
|
|
911
923
|
|
|
912
|
-
[Unreleased]: https://github.com/wan9yu/cli-agent-runner/compare/v0.2.
|
|
924
|
+
[Unreleased]: https://github.com/wan9yu/cli-agent-runner/compare/v0.2.3...HEAD
|
|
925
|
+
[0.2.3]: https://github.com/wan9yu/cli-agent-runner/compare/v0.2.2...v0.2.3
|
|
926
|
+
[0.2.2]: https://github.com/wan9yu/cli-agent-runner/compare/v0.2.1...v0.2.2
|
|
927
|
+
[0.2.1]: https://github.com/wan9yu/cli-agent-runner/compare/v0.2.0...v0.2.1
|
|
913
928
|
[0.2.0]: https://github.com/wan9yu/cli-agent-runner/compare/v0.1.42...v0.2.0
|
|
914
929
|
[0.1.26]: https://github.com/wan9yu/cli-agent-runner/compare/v0.1.25...v0.1.26
|
|
915
930
|
[0.1.25]: https://github.com/wan9yu/cli-agent-runner/compare/v0.1.24...v0.1.25
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cli-agent-runner
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: Restart-on-exit supervisor for autonomous CLI agents
|
|
5
5
|
Project-URL: Homepage, https://github.com/wan9yu/cli-agent-runner
|
|
6
6
|
Project-URL: Documentation, https://github.com/wan9yu/cli-agent-runner#readme
|
|
@@ -41,7 +41,7 @@ Description-Content-Type: text/markdown
|
|
|
41
41
|
# agent-runner
|
|
42
42
|
|
|
43
43
|
A restart-on-exit supervisor for autonomous coding CLIs. Ships presets for
|
|
44
|
-
Claude Code, aider, gemini and
|
|
44
|
+
Claude Code, aider, gemini, codewhale, kimi and pi; any prompt-arg CLI via custom
|
|
45
45
|
config. Spawn the agent round-after-round under defenses that prevent the
|
|
46
46
|
failure modes
|
|
47
47
|
that bite in production: stuck rounds, orphan commits, OAuth burn loops,
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
# agent-runner
|
|
6
6
|
|
|
7
7
|
A restart-on-exit supervisor for autonomous coding CLIs. Ships presets for
|
|
8
|
-
Claude Code, aider, gemini and
|
|
8
|
+
Claude Code, aider, gemini, codewhale, kimi and pi; any prompt-arg CLI via custom
|
|
9
9
|
config. Spawn the agent round-after-round under defenses that prevent the
|
|
10
10
|
failure modes
|
|
11
11
|
that bite in production: stuck rounds, orphan commits, OAuth burn loops,
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '0.2.
|
|
22
|
-
__version_tuple__ = version_tuple = (0, 2,
|
|
21
|
+
__version__ = version = '0.2.3'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 2, 3)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -137,6 +137,7 @@ def run(
|
|
|
137
137
|
prompt: str,
|
|
138
138
|
prompt_delivery: str = "argv",
|
|
139
139
|
timeout_s: int,
|
|
140
|
+
work_dir: Path,
|
|
140
141
|
log_path: Path,
|
|
141
142
|
env_extra: dict[str, str],
|
|
142
143
|
max_grace_after_result_s: int = 0,
|
|
@@ -149,6 +150,12 @@ def run(
|
|
|
149
150
|
|
|
150
151
|
Wall-clock timeout (R1128). On timeout: SIGTERM pgroup → REAP_GRACE_S → SIGKILL.
|
|
151
152
|
|
|
153
|
+
work_dir: the agent child's working directory (required). Before 0.2.3 the
|
|
154
|
+
child inherited the supervisor's cwd and only launch conventions (systemd
|
|
155
|
+
WorkingDirectory=, relative --config) kept the two aligned — fatal for CLIs
|
|
156
|
+
with no --cwd flag of their own (e.g. pi). Callers pass the already-absolute
|
|
157
|
+
cfg.runtime.work_dir.
|
|
158
|
+
|
|
152
159
|
max_grace_after_result_s: when > 0, start a countdown after the first
|
|
153
160
|
type=result event is detected in the log. After it elapses, reap the
|
|
154
161
|
process group only if the agent has no live worker processes left (a
|
|
@@ -175,16 +182,20 @@ def run(
|
|
|
175
182
|
if stdin_mode
|
|
176
183
|
else _build_argv(command, prompt_arg_template, prompt)
|
|
177
184
|
)
|
|
178
|
-
|
|
185
|
+
# PWD pinned alongside cwd= so shell-reported paths agree; env_extra wins.
|
|
186
|
+
env = {**os.environ, "PWD": str(work_dir), **env_extra}
|
|
179
187
|
log_path.parent.mkdir(parents=True, exist_ok=True)
|
|
180
188
|
log_file = log_path.open("w", encoding="utf-8")
|
|
181
189
|
start = time.time()
|
|
182
190
|
last_progress_at = start
|
|
183
191
|
proc = subprocess.Popen(
|
|
184
192
|
argv,
|
|
193
|
+
cwd=work_dir,
|
|
185
194
|
env=env,
|
|
186
195
|
stdin=subprocess.PIPE if stdin_mode else subprocess.DEVNULL,
|
|
187
196
|
stdout=log_file,
|
|
197
|
+
# Merged on purpose: oauth_fail / network_fail / network-blip detection
|
|
198
|
+
# regex-scan stderr text out of this log (see hooks.agent_log_path).
|
|
188
199
|
stderr=subprocess.STDOUT,
|
|
189
200
|
start_new_session=True,
|
|
190
201
|
)
|
{cli_agent_runner-0.2.2 → cli_agent_runner-0.2.3}/agent_runner/builtin_plugins/_constants.py
RENAMED
|
@@ -6,8 +6,13 @@ same window size, raw-text caps, and transient-error back-off defaults.
|
|
|
6
6
|
|
|
7
7
|
from __future__ import annotations
|
|
8
8
|
|
|
9
|
-
_TAIL_LINES: int =
|
|
10
|
-
"""Number of log lines to scan from the end of round-N.log.
|
|
9
|
+
_TAIL_LINES: int = 200
|
|
10
|
+
"""Number of log lines to scan from the end of round-N.log.
|
|
11
|
+
|
|
12
|
+
200, not 50: the round log is merged stdout+stderr, and a CLI that bursts
|
|
13
|
+
stderr text after its terminal JSONL event (observed with stderr-chatty
|
|
14
|
+
agents like pi) could evict that event from a 50-line window — silently
|
|
15
|
+
dropping usage/transient classification for the round."""
|
|
11
16
|
|
|
12
17
|
_RAW_CAP: int = 200
|
|
13
18
|
"""Maximum length for ``raw`` field in transient_error_detected payload."""
|
|
@@ -75,16 +75,20 @@ class HookContext:
|
|
|
75
75
|
"""Basename of ``cfg.agent.command[0]`` (e.g. ``'claude'``, ``'gemini'``).
|
|
76
76
|
Distinct from ``agent_name`` (the user-cosmetic ``[agent] name`` field).
|
|
77
77
|
Plugins should guard on ``agent_binary``, not ``agent_name``, so a custom
|
|
78
|
-
``[agent] name = "
|
|
78
|
+
``[agent] name = "acme_dev"`` does not suppress events.
|
|
79
79
|
Populated from 0.1.30+; defaults to ``None`` for manually-constructed
|
|
80
80
|
HookContext instances (rare; tests set it via ``make_hook_context``).
|
|
81
81
|
"""
|
|
82
82
|
agent_log_path: Path | None = None
|
|
83
|
-
"""Path to the agent's
|
|
84
|
-
``log_dir/rounds/R<N>-<timestamp>.log``).
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
83
|
+
"""Path to the agent's round log (e.g.
|
|
84
|
+
``log_dir/rounds/R<N>-<timestamp>.log``). Contract: the file is the
|
|
85
|
+
agent's MERGED stdout+stderr — the merge is deliberate (oauth_fail /
|
|
86
|
+
network_fail detection regex-scans stderr text out of it), so JSONL
|
|
87
|
+
consumers must skip non-JSON lines (per-line ``json.loads`` in
|
|
88
|
+
try/except). Plugins parse this to extract usage / classify errors.
|
|
89
|
+
Default ``None`` for backward compatibility with manually-constructed
|
|
90
|
+
HookContext instances (rare; the supervisor always populates this
|
|
91
|
+
from 0.1.25+).
|
|
88
92
|
"""
|
|
89
93
|
dry_run: bool = False
|
|
90
94
|
"""When True, plugins should skip side-effect actions (e.g. git ops,
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# agent-runner.toml — generated by `agent-runner init --preset kimi`.
|
|
2
|
+
#
|
|
3
|
+
# Prereqs (full setup, exact auth values, and the claude-via-Kimi-K3
|
|
4
|
+
# alternative: docs/recipes/kimi.md):
|
|
5
|
+
# - Kimi Code CLI on PATH: `brew install kimi-code` (or `npm i -g @moonshot-ai/kimi-code`).
|
|
6
|
+
# - Host authenticated with a model configured. Cleanest unattended path: set the
|
|
7
|
+
# KIMI_MODEL_* env vars (a self-contained model spec — no interactive login, no
|
|
8
|
+
# config.toml); a raw KIMI_API_KEY alone is NOT enough. Or `kimi login` once.
|
|
9
|
+
# - work_dir is a git repo.
|
|
10
|
+
#
|
|
11
|
+
# `kimi -p` is headless and auto-approves tool calls itself — it REJECTS
|
|
12
|
+
# --yolo / --auto, so the command below must not add them.
|
|
13
|
+
|
|
14
|
+
[agent]
|
|
15
|
+
command = ["kimi", "--output-format", "stream-json"]
|
|
16
|
+
prompt_arg_template = ["-p", "{prompt}"]
|
|
17
|
+
name = "kimi"
|
|
18
|
+
|
|
19
|
+
[agent.env]
|
|
20
|
+
KIMI_CODE_NO_AUTO_UPDATE = "1"
|
|
21
|
+
KIMI_DISABLE_TELEMETRY = "1"
|
|
22
|
+
|
|
23
|
+
[runtime]
|
|
24
|
+
work_dir = "."
|
|
25
|
+
log_dir = "~/.agent-runner/{project}/logs"
|
|
26
|
+
round_timeout_s = 1800
|
|
27
|
+
restart_delay_s = 3
|
|
28
|
+
|
|
29
|
+
[prompt]
|
|
30
|
+
file = "./prompts/main.md"
|
|
31
|
+
inject_context = true
|
|
32
|
+
|
|
33
|
+
[vcs]
|
|
34
|
+
dirty_action = "stash"
|
|
35
|
+
stash_idempotency_s = 5
|
|
36
|
+
|
|
37
|
+
[monitor]
|
|
38
|
+
auth_fail_hint = "Configure Kimi model access on the supervisor host — set the KIMI_MODEL_* env vars (see docs/recipes/kimi.md) or run `kimi login`; `kimi doctor` validates config."
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# agent-runner.toml — generated by `agent-runner init --preset pi`.
|
|
2
|
+
#
|
|
3
|
+
# Prereqs (full setup + provider auth: docs/recipes/pi.md):
|
|
4
|
+
# - Pi Coding Agent on PATH: `npm i -g --ignore-scripts @earendil-works/pi-coding-agent`
|
|
5
|
+
# (or the install script at https://pi.dev). Binary is `pi`.
|
|
6
|
+
# - A provider + model configured. pi has NO universal default model, so you MUST
|
|
7
|
+
# set --model below. Our setup: Kimi K3 via a Moonshot provider in
|
|
8
|
+
# ~/.pi/agent/models.json — see docs/recipes/pi.md — then --model moonshot/kimi-k3.
|
|
9
|
+
# - work_dir is a git repo. agent-runner starts the agent in it (pi itself
|
|
10
|
+
# has no --cwd flag).
|
|
11
|
+
#
|
|
12
|
+
# pi runs tools unconfined (full YOLO, no confirmation) and agent-runner does not
|
|
13
|
+
# sandbox it — only point it at a repo/host where unattended automated shell is OK.
|
|
14
|
+
|
|
15
|
+
[agent]
|
|
16
|
+
# Replace PROVIDER/MODEL — pi has no default. Our default: moonshot/kimi-k3.
|
|
17
|
+
# -na pins project trust off: project-local pi resources (.pi/ settings,
|
|
18
|
+
# extensions, skills, SYSTEM.md; project .agents/skills) never load, instead
|
|
19
|
+
# of depending on the host's saved trust.json decisions or defaultProjectTrust.
|
|
20
|
+
command = ["pi", "-p", "-na", "--mode", "json", "--model", "PROVIDER/MODEL"]
|
|
21
|
+
prompt_arg_template = ["{prompt}"]
|
|
22
|
+
name = "pi"
|
|
23
|
+
|
|
24
|
+
[agent.env]
|
|
25
|
+
PI_OFFLINE = "1"
|
|
26
|
+
|
|
27
|
+
[runtime]
|
|
28
|
+
work_dir = "."
|
|
29
|
+
log_dir = "~/.agent-runner/{project}/logs"
|
|
30
|
+
round_timeout_s = 1800
|
|
31
|
+
restart_delay_s = 3
|
|
32
|
+
|
|
33
|
+
[prompt]
|
|
34
|
+
file = "./prompts/main.md"
|
|
35
|
+
inject_context = true
|
|
36
|
+
|
|
37
|
+
[vcs]
|
|
38
|
+
dirty_action = "stash"
|
|
39
|
+
stash_idempotency_s = 5
|
|
40
|
+
|
|
41
|
+
[monitor]
|
|
42
|
+
auth_fail_hint = "Configure a pi provider on the supervisor host — add it to ~/.pi/agent/models.json (see docs/recipes/pi.md) or run `pi /login`, and set --model to a reachable provider/model; `pi -p \"ok\"` validates it."
|
|
@@ -507,6 +507,7 @@ def _run_one_round_inner(cfg: Config, *, phase_override: str | None = None) -> R
|
|
|
507
507
|
prompt=prompt,
|
|
508
508
|
prompt_delivery=cfg.agent.prompt_delivery,
|
|
509
509
|
timeout_s=timeout_s,
|
|
510
|
+
work_dir=cfg.runtime.work_dir,
|
|
510
511
|
log_path=log_path,
|
|
511
512
|
env_extra={**framework_env, **dict(cfg.agent.env)},
|
|
512
513
|
max_grace_after_result_s=cfg.runtime.max_grace_after_result_s,
|
|
@@ -8,6 +8,7 @@ import os
|
|
|
8
8
|
import shutil
|
|
9
9
|
from collections.abc import Callable
|
|
10
10
|
from dataclasses import dataclass
|
|
11
|
+
from pathlib import Path
|
|
11
12
|
|
|
12
13
|
from agent_runner.config import Config
|
|
13
14
|
|
|
@@ -45,6 +46,21 @@ def _check_agent_cli(cfg: Config) -> CheckResult:
|
|
|
45
46
|
if not cfg.agent.command:
|
|
46
47
|
return CheckResult("agent_cli_in_path", False, "agent.command is empty")
|
|
47
48
|
cli = cfg.agent.command[0]
|
|
49
|
+
if "/" in cli:
|
|
50
|
+
# Slash-containing commands are exec'd relative to the agent's cwd
|
|
51
|
+
# (= runtime.work_dir since the cwd= spawn fix), not PATH — validate
|
|
52
|
+
# against the same base the exec will use, not the supervisor's cwd.
|
|
53
|
+
candidate = Path(cli)
|
|
54
|
+
if not candidate.is_absolute():
|
|
55
|
+
candidate = cfg.runtime.work_dir / candidate
|
|
56
|
+
if not (candidate.is_file() and os.access(candidate, os.X_OK)):
|
|
57
|
+
return CheckResult(
|
|
58
|
+
"agent_cli_in_path",
|
|
59
|
+
False,
|
|
60
|
+
reason=f"{cli!r} not found or not executable under {cfg.runtime.work_dir}",
|
|
61
|
+
how_to_fix="fix the path relative to runtime.work_dir, or use an absolute path",
|
|
62
|
+
)
|
|
63
|
+
return CheckResult("agent_cli_in_path", True)
|
|
48
64
|
if shutil.which(cli) is None:
|
|
49
65
|
return CheckResult(
|
|
50
66
|
"agent_cli_in_path",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# agent-runner — Documentation
|
|
2
2
|
|
|
3
3
|
A restart-on-exit supervisor for autonomous coding CLIs (Claude Code, aider,
|
|
4
|
-
gemini, codewhale, or any prompt-arg CLI). Each round runs the agent once and
|
|
4
|
+
gemini, codewhale, kimi, pi, or any prompt-arg CLI). Each round runs the agent once and
|
|
5
5
|
exits; an external
|
|
6
6
|
service manager (systemd / launchd / bash loop) restarts. State persists
|
|
7
7
|
across restarts via JSON files; defenses (timeout, process-group reap,
|
|
@@ -23,10 +23,12 @@ modes.
|
|
|
23
23
|
| [long-running-agents.md](long-running-agents.md) | Context rot, fresh eyes, long-lineage runs |
|
|
24
24
|
| [recipes/aider.md](recipes/aider.md) | aider walkthrough |
|
|
25
25
|
| [recipes/codewhale.md](recipes/codewhale.md) | codewhale walkthrough |
|
|
26
|
+
| [recipes/kimi.md](recipes/kimi.md) | Kimi Code CLI + running Kimi K3 via the claude preset |
|
|
27
|
+
| [recipes/pi.md](recipes/pi.md) | Pi Coding Agent + Kimi K3 via a Moonshot provider |
|
|
26
28
|
|
|
27
29
|
## 中文导读
|
|
28
30
|
|
|
29
|
-
agent-runner 是一个面向自主编码 CLI(Claude Code、aider、gemini、codewhale,
|
|
31
|
+
agent-runner 是一个面向自主编码 CLI(Claude Code、aider、gemini、codewhale、kimi、pi,
|
|
30
32
|
或任何 prompt-arg CLI)的「跑完即退、自动重启」调度框架。
|
|
31
33
|
进程退出后由外部服务管理器(systemd / launchd / bash loop)立即拉起新一轮,
|
|
32
34
|
状态文件持久化在 JSON 中,关键防御(超时、进程组回收、孤儿 stash、启动 smoke
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
Each layer can run without the layer above. The Witness can watch a remote
|
|
16
16
|
Loop.
|
|
17
17
|
|
|
18
|
-
**Provider-agnostic by design.**
|
|
19
|
-
plus `aider`, `gemini` and `
|
|
18
|
+
**Provider-agnostic by design.** 6 presets ship (`claude` — the default —
|
|
19
|
+
plus `aider`, `gemini`, `codewhale`, `kimi` and `pi`) because those are what we run in
|
|
20
20
|
production, but the supervisor's defenses, observability, and lifecycle make
|
|
21
21
|
no CLI-specific assumptions in core. Set `[agent].command` to any prompt-arg
|
|
22
22
|
CLI and the same Round / Loop / Witness layers apply.
|
|
@@ -97,7 +97,7 @@ API quota / writing to a near-full disk).
|
|
|
97
97
|
|
|
98
98
|
## Monitor: anomaly-only by design
|
|
99
99
|
|
|
100
|
-
The monitor emits no events during healthy operation — it surfaces alerts only when a detector fires. To verify the monitor process is running, look for the `monitor_started` event in `events-*.jsonl`. Programmatic consumers (e.g.
|
|
100
|
+
The monitor emits no events during healthy operation — it surfaces alerts only when a detector fires. To verify the monitor process is running, look for the `monitor_started` event in `events-*.jsonl`. Programmatic consumers (e.g. an external supervisory layer) should subscribe to that event kind as the canonical "supervision is up" signal. The event carries `mode: "anomaly-only"` to document the intentional silence.
|
|
101
101
|
|
|
102
102
|
## Monitor: transient ssh tolerance
|
|
103
103
|
|
|
@@ -35,7 +35,7 @@ appends `logs/` to `.gitignore`. By default also creates a git commit.
|
|
|
35
35
|
|
|
36
36
|
Flags:
|
|
37
37
|
|
|
38
|
-
- `--preset {claude,aider,gemini,codewhale}` — agent CLI preset to scaffold (default: `claude`)
|
|
38
|
+
- `--preset {claude,aider,gemini,codewhale,kimi,pi}` — agent CLI preset to scaffold (default: `claude`)
|
|
39
39
|
- `--force` — overwrite an existing `agent-runner.toml`
|
|
40
40
|
- `--no-commit` — skip the initial git commit
|
|
41
41
|
|
|
@@ -161,6 +161,11 @@ guidance without authoring it themselves:
|
|
|
161
161
|
credentials, or set `DEEPSEEK_API_KEY` on the supervisor host.
|
|
162
162
|
- `--preset gemini` → verify your API key or check your authentication status
|
|
163
163
|
for Gemini CLI.
|
|
164
|
+
- `--preset kimi` → set the `KIMI_MODEL_*` env vars (see `recipes/kimi.md`), or
|
|
165
|
+
run `kimi login`; `kimi doctor` validates config.
|
|
166
|
+
- `--preset pi` → configure a pi provider in `~/.pi/agent/models.json` (see
|
|
167
|
+
`recipes/pi.md`) or run `pi /login`, and set `--model` to a reachable
|
|
168
|
+
provider/model.
|
|
164
169
|
|
|
165
170
|
Override in your `agent-runner.toml` if you ship a custom CLI.
|
|
166
171
|
|
|
@@ -176,7 +181,7 @@ concat_separator = "\n\n" # default; use "\n\n---\n\n" for visible breaks
|
|
|
176
181
|
strip_yaml_frontmatter = true # default; set false for non-LLM-CLI agents
|
|
177
182
|
```
|
|
178
183
|
|
|
179
|
-
- **Missing `files[0]`** → `
|
|
184
|
+
- **Missing `files[0]`** → `FileNotFoundError` when the round assembles the prompt (the first file is required; the existence check happens at prompt assembly, not at config load).
|
|
180
185
|
- **Missing `files[n≥1]`** → warning logged, file skipped (supports optional preamble pattern).
|
|
181
186
|
- **Both `prompt.file` and `prompt.files` set** → `ConfigError`.
|
|
182
187
|
- **`prompt.file = "x.md"` shorthand** — single-file back-compat, still works unchanged.
|
|
@@ -227,10 +227,12 @@ migration recipes.
|
|
|
227
227
|
### Reading agent stdout from a plugin
|
|
228
228
|
|
|
229
229
|
Use `ctx.agent_log_path` (added in 0.1.25). This points to the agent's
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
230
|
+
round log (`log_dir/rounds/R<N>-<timestamp>.log`) — the agent's **merged
|
|
231
|
+
stdout+stderr**, merged deliberately so auth/network error text emitted on
|
|
232
|
+
stderr stays detectable. Parse it as JSONL that may contain non-JSON lines
|
|
233
|
+
(per-line `json.loads` in try/except, as the built-in plugins do). Do NOT
|
|
234
|
+
compute the path from `ctx.log_dir + round_num` — historical naming
|
|
235
|
+
conventions in that directory are subject to change.
|
|
234
236
|
|
|
235
237
|
```python
|
|
236
238
|
def after_round(self, ctx: HookContext, result: Any) -> None:
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# 0.1.20 migration notes
|
|
2
2
|
|
|
3
|
+
> **Forward note (added 2026-07-18 for 0.2.2)**: the rate-limit surface this page
|
|
4
|
+
> introduces was later replaced — read this page as history, not current behavior:
|
|
5
|
+
> - The three events (`rate_limit_rejected`, `rate_limit_recovered`,
|
|
6
|
+
> `rate_limit_backoff_capped`) were **removed in 0.1.29** and are no longer
|
|
7
|
+
> registered kinds, so a subscriber never fires. `transient_error_*` is the
|
|
8
|
+
> current emission path.
|
|
9
|
+
> - `[runtime] rate_limit_action` was **removed in 0.1.29** and now hard-fails
|
|
10
|
+
> config load — use `runtime.transient_error_action`.
|
|
11
|
+
> - Events are written to monthly `events-YYYY-MM.jsonl`, not `events.jsonl`.
|
|
12
|
+
|
|
3
13
|
## What changed
|
|
4
14
|
|
|
5
15
|
### 1. Built-in claude rate-limit detection
|
|
@@ -35,7 +35,7 @@ transient API errors via a unified classifier:
|
|
|
35
35
|
Same supervisor mechanism (sleep until `reset_at_epoch + jitter`, 8h cap).
|
|
36
36
|
All 4 classifications honor `[runtime] transient_error_action`.
|
|
37
37
|
|
|
38
|
-
Motivation:
|
|
38
|
+
Motivation: a downstream integrator reported a 15-min claude API 500 outage that caused
|
|
39
39
|
16 wasted empty rounds before the operator noticed and intervened. The existing
|
|
40
40
|
rate-limit machinery already had the right back-off design; extending it to
|
|
41
41
|
cover 5xx/timeout was the natural generalization.
|
|
@@ -86,7 +86,7 @@ should start producing events on the next round.
|
|
|
86
86
|
- **Auto-detect plugins using old path + warn** — rejected: too magic;
|
|
87
87
|
explicit migration recipe is cleaner
|
|
88
88
|
|
|
89
|
-
## What
|
|
89
|
+
## What downstream + other third-party users should do
|
|
90
90
|
|
|
91
91
|
1. Update to agent-runner 0.1.25
|
|
92
92
|
2. Audit any custom `post_round_hook` plugins for `ctx.log_dir /
|
|
@@ -70,7 +70,7 @@ from agent_runner.api import emit_transient_error_backoff_capped
|
|
|
70
70
|
|
|
71
71
|
The alias surface was introduced in 0.1.20 (`rate_limit_rejected`), generalized
|
|
72
72
|
in 0.1.23 (`transient_error_detected` as canonical), and dual-emitting since.
|
|
73
|
-
|
|
73
|
+
Downstream consumers confirmed test-mode integration (not production workloads);
|
|
74
74
|
cutting the aliases now avoids carrying back-compat dual-emission indefinitely.
|
|
75
75
|
|
|
76
76
|
## Verification recipe
|
|
@@ -22,7 +22,7 @@ If your config has a custom `[agent] name`:
|
|
|
22
22
|
```toml
|
|
23
23
|
[agent]
|
|
24
24
|
command = ["claude", "--some-flag"]
|
|
25
|
-
name = "
|
|
25
|
+
name = "acme_dev" # custom cosmetic name
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
Previously this silenced all `agent_usage_recorded` and
|
|
@@ -59,7 +59,7 @@ since 0.1.20.
|
|
|
59
59
|
## Why hard-cut (no deprecation cycle)
|
|
60
60
|
|
|
61
61
|
The 0.1.23 rename is 12 releases / ~6 days old (as measured by the rapid
|
|
62
|
-
0.1.25-0.1.34 ship cadence).
|
|
62
|
+
0.1.25-0.1.34 ship cadence). A downstream integrator — our only known
|
|
63
63
|
production consumer — explicitly migrated away from the old name during
|
|
64
64
|
their 2026-05-19/20 monitoring overhaul. Carrying an unused back-compat
|
|
65
65
|
entry-point line indefinitely is debt; per project policy
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Migration guide: 0.2.3
|
|
2
|
+
|
|
3
|
+
## TL;DR
|
|
4
|
+
|
|
5
|
+
No public symbols removed, no TOML changes required. Two additive presets
|
|
6
|
+
(`kimi`, `pi`) and two behavior fixes. Upgrade freely; read on only if you
|
|
7
|
+
launch `serve` from outside `work_dir` or ship plugins that parse round logs.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Fixed: the agent subprocess now runs in `runtime.work_dir`
|
|
12
|
+
|
|
13
|
+
Before 0.2.3 the agent child inherited the **supervisor's** cwd; only launch
|
|
14
|
+
conventions (the systemd unit's `WorkingDirectory=`, the default relative
|
|
15
|
+
`./agent-runner.toml`) kept the two aligned. Agent CLIs with no working-
|
|
16
|
+
directory flag of their own (e.g. `pi`) had no recourse when the convention
|
|
17
|
+
was violated.
|
|
18
|
+
|
|
19
|
+
From 0.2.3 the child is spawned with `cwd=work_dir` (and `PWD` pinned to
|
|
20
|
+
match). If you relied on the agent running somewhere other than `work_dir`,
|
|
21
|
+
that setup was already misbehaving — the startup battery usually failed it —
|
|
22
|
+
and now runs where the config says.
|
|
23
|
+
|
|
24
|
+
Related: a relative, slash-containing `agent.command[0]` (e.g.
|
|
25
|
+
`./run-agent.sh`) is now validated by the startup check against `work_dir` —
|
|
26
|
+
the same base the exec uses — instead of the supervisor's cwd.
|
|
27
|
+
|
|
28
|
+
## Changed: plugin round-log tail window 50 → 200 lines
|
|
29
|
+
|
|
30
|
+
The round log is the agent's **merged stdout+stderr** (deliberate: auth- and
|
|
31
|
+
network-error detection regex-scan stderr text out of it). A CLI bursting >50
|
|
32
|
+
stderr lines after its terminal JSONL event could evict that event from the
|
|
33
|
+
50-line scan window, silently dropping usage / transient-error classification
|
|
34
|
+
for the round. The window is now 200 lines. No action needed; the merged-log
|
|
35
|
+
contract is documented at `HookContext.agent_log_path` and
|
|
36
|
+
`docs/long-running-agents.md` — plugin parsers must skip non-JSON lines.
|
|
37
|
+
|
|
38
|
+
## Added: `--preset kimi` and `--preset pi`
|
|
39
|
+
|
|
40
|
+
- `kimi` — Kimi Code CLI (`kimi -p --output-format stream-json`); auth via
|
|
41
|
+
`KIMI_MODEL_*` env vars. See `docs/recipes/kimi.md`.
|
|
42
|
+
- `pi` — Pi Coding Agent (`pi -p -na --mode json --model …`). `-na` pins pi's
|
|
43
|
+
project trust **off** for unattended rounds: without it, a saved trust
|
|
44
|
+
decision for `work_dir` or any parent silently loads repo-local `.pi/`
|
|
45
|
+
resources, including a `SYSTEM.md` that replaces the system prompt. pi has
|
|
46
|
+
no turn cap or timeout of its own — agent-runner's `round_timeout_s` is the
|
|
47
|
+
only brake. See `docs/recipes/pi.md`.
|
|
@@ -448,7 +448,7 @@ detector. Other plugin detectors and all builtins still run normally.
|
|
|
448
448
|
|
|
449
449
|
This example shows the full pattern for a project-specific monitor detector
|
|
450
450
|
that filters out rounds the plugin marks as exempt by some project rule.
|
|
451
|
-
Covers
|
|
451
|
+
Covers supervisory needs like "stuck role detection" (count git commits per
|
|
452
452
|
round) and "wall-time trend" (compare recent avg vs older avg).
|
|
453
453
|
|
|
454
454
|
**The shape**: a plugin emits a custom event for exempt rounds; a custom
|
|
@@ -684,7 +684,7 @@ from agent_runner.vcs_state import register_plugin_owned_paths
|
|
|
684
684
|
# Module-top side effect — must register before the first round runs.
|
|
685
685
|
register_plugin_owned_paths([
|
|
686
686
|
"proposals/", # trailing slash → prefix match
|
|
687
|
-
"logs/plugins/my_plugin/**/*", # recursive glob (
|
|
687
|
+
"logs/plugins/my_plugin/**/*", # recursive glob (globstar)
|
|
688
688
|
"reports/*.md", # single-segment glob (PurePath.match)
|
|
689
689
|
])
|
|
690
690
|
```
|
|
@@ -697,7 +697,7 @@ register_plugin_owned_paths([
|
|
|
697
697
|
| `"proposals"` (no slash) | `proposals` exactly | Single-segment literal. |
|
|
698
698
|
| `"reports/*.md"` | `reports/dev.md` | `*` does not cross slashes. |
|
|
699
699
|
| `"reports/**/*.md"` | `reports/dev.md`, `reports/sub/qa.md` | `**` matches across directory separators. |
|
|
700
|
-
| `"logs/plugins/**/*"` | `logs/plugins/
|
|
700
|
+
| `"logs/plugins/**/*"` | `logs/plugins/acme/state.json` | Same — `**` covers intermediate dirs. |
|
|
701
701
|
|
|
702
702
|
### Caveat — this is NOT a "make work_dir messy" license
|
|
703
703
|
|