cli-agent-runner 0.2.1__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.
Files changed (278) hide show
  1. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/.github/workflows/ci.yml +4 -0
  2. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/.gitignore +5 -0
  3. cli_agent_runner-0.2.3/.vulture-whitelist.py +244 -0
  4. cli_agent_runner-0.2.3/BACKLOG.md +90 -0
  5. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/CHANGELOG.md +53 -15
  6. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/CONTRIBUTING.md +26 -0
  7. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/PKG-INFO +7 -7
  8. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/README.md +6 -5
  9. cli_agent_runner-0.2.3/README.zh.md +37 -0
  10. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/SECURITY.md +17 -0
  11. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/_docgen.py +45 -19
  12. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/_throttle.py +13 -4
  13. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/_version.py +2 -2
  14. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/agent_runtime.py +12 -20
  15. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/api.py +11 -17
  16. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/builtin_plugins/_constants.py +7 -2
  17. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/builtin_plugins/default_dirty_handler.py +20 -12
  18. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/cli/events_cmd.py +4 -2
  19. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/cli/install_cmd.py +1 -3
  20. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/cli/serve_cmd.py +4 -25
  21. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/cli/service_cmd.py +1 -7
  22. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/cli/upgrade_cmd.py +1 -1
  23. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/config.py +62 -28
  24. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/context_store.py +0 -23
  25. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/defenses.py +21 -11
  26. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/events.py +0 -1
  27. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/hooks.py +20 -15
  28. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/http_progress.py +1 -1
  29. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/lifecycle.py +1 -1
  30. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/monitor.py +28 -18
  31. cli_agent_runner-0.2.3/agent_runner/presets/kimi.toml +38 -0
  32. cli_agent_runner-0.2.3/agent_runner/presets/pi.toml +42 -0
  33. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/prompt_loader.py +0 -7
  34. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/round_view.py +3 -2
  35. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/runner.py +13 -8
  36. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/startup_check.py +16 -0
  37. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/vcs_state.py +162 -108
  38. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/build.sh +13 -1
  39. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/README.md +14 -5
  40. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/architecture.md +17 -15
  41. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/commands.md +10 -10
  42. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/configuration.md +49 -21
  43. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/events.md +1 -1
  44. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/long-running-agents.md +6 -4
  45. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/migrations/0.1.20.md +10 -0
  46. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/migrations/0.1.23.md +8 -1
  47. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/migrations/0.1.25.md +1 -1
  48. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/migrations/0.1.26.md +6 -0
  49. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/migrations/0.1.27.md +7 -0
  50. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/migrations/0.1.29.md +1 -1
  51. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/migrations/0.1.30.md +1 -1
  52. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/migrations/0.1.32.md +11 -0
  53. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/migrations/0.1.35.md +1 -1
  54. cli_agent_runner-0.2.3/docs/migrations/0.2.2.md +242 -0
  55. cli_agent_runner-0.2.3/docs/migrations/0.2.3.md +47 -0
  56. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/plugins.md +114 -145
  57. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/quickstart.md +4 -5
  58. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/recipes/aider.md +5 -3
  59. cli_agent_runner-0.2.3/docs/recipes/kimi.md +119 -0
  60. cli_agent_runner-0.2.3/docs/recipes/pi.md +106 -0
  61. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/runbook.md +3 -7
  62. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/thesis.md +1 -1
  63. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/pyproject.toml +22 -8
  64. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/_test_helpers.py +7 -0
  65. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/contract/test_public_api_surface.py +25 -12
  66. cli_agent_runner-0.2.3/tests/generate_vulture_whitelist.py +82 -0
  67. cli_agent_runner-0.2.3/tests/integration/test_fresh_eyes_signal.py +135 -0
  68. cli_agent_runner-0.2.3/tests/integration/test_plugin_owned_paths.py +279 -0
  69. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/integration/test_prompt_delivery_stdin.py +4 -0
  70. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/integration/test_scaffold_presets.py +3 -1
  71. cli_agent_runner-0.2.3/tests/invariants/_event_scan.py +94 -0
  72. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/invariants/test_architecture.py +1 -1
  73. cli_agent_runner-0.2.3/tests/invariants/test_auto_stop_policy_ssot.py +39 -0
  74. cli_agent_runner-0.2.3/tests/invariants/test_catalogs.py +82 -0
  75. cli_agent_runner-0.2.3/tests/invariants/test_config_error_consistency.py +73 -0
  76. cli_agent_runner-0.2.3/tests/invariants/test_config_value_set_ssot.py +64 -0
  77. cli_agent_runner-0.2.3/tests/invariants/test_doc_builtin_plugins.py +42 -0
  78. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/invariants/test_doc_claims_match_ssot.py +38 -5
  79. cli_agent_runner-0.2.3/tests/invariants/test_doc_cli_claims.py +122 -0
  80. cli_agent_runner-0.2.3/tests/invariants/test_doc_operator_surface.py +83 -0
  81. cli_agent_runner-0.2.3/tests/invariants/test_doc_transient_error_claims.py +58 -0
  82. cli_agent_runner-0.2.3/tests/invariants/test_docs_index_complete.py +34 -0
  83. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/invariants/test_event_kind_registry.py +16 -24
  84. cli_agent_runner-0.2.3/tests/invariants/test_event_kinds_ssot.py +151 -0
  85. cli_agent_runner-0.2.3/tests/invariants/test_hook_contract_docs.py +77 -0
  86. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/invariants/test_module_boundaries.py +39 -15
  87. cli_agent_runner-0.2.3/tests/invariants/test_plugins_config_stable.py +38 -0
  88. cli_agent_runner-0.2.3/tests/invariants/test_readme_zh_is_pointer.py +54 -0
  89. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/invariants/test_round_result_stable.py +1 -0
  90. cli_agent_runner-0.2.3/tests/invariants/test_set_diff_for_auto_tool_classification.py +97 -0
  91. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/invariants/test_stash_uses_sha_not_index.py +3 -12
  92. cli_agent_runner-0.2.3/tests/invariants/test_vulture_whitelist_generated.py +19 -0
  93. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_agent_runtime.py +30 -10
  94. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_agent_runtime_grace.py +6 -0
  95. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_agent_runtime_progress.py +3 -0
  96. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_api_service.py +0 -15
  97. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_claude_error_detector.py +30 -0
  98. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_cli_service_peek_monitor.py +0 -10
  99. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_config.py +102 -0
  100. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_context_store.py +0 -36
  101. cli_agent_runner-0.2.3/tests/unit/test_default_dirty_handler.py +177 -0
  102. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_defenses.py +59 -3
  103. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_docgen.py +66 -1
  104. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_events.py +0 -1
  105. cli_agent_runner-0.2.3/tests/unit/test_events_cmd_tail.py +73 -0
  106. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_presets.py +17 -1
  107. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_prompt_loader.py +0 -12
  108. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_runner.py +100 -4
  109. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_serve_cmd_bounded.py +2 -3
  110. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_startup_check.py +29 -0
  111. cli_agent_runner-0.2.3/tests/unit/test_throttle_plugin_classification.py +42 -0
  112. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_vcs_state.py +29 -38
  113. cli_agent_runner-0.2.1/.vulture-whitelist.py +0 -6
  114. cli_agent_runner-0.2.1/README.zh.md +0 -157
  115. cli_agent_runner-0.2.1/agent_runner/detector_helpers.py +0 -115
  116. cli_agent_runner-0.2.1/deploy/example-agent-runner.toml +0 -24
  117. cli_agent_runner-0.2.1/deploy/launchd.plist.tmpl +0 -39
  118. cli_agent_runner-0.2.1/deploy/run-loop.sh +0 -27
  119. cli_agent_runner-0.2.1/deploy/systemd.service.tmpl +0 -15
  120. cli_agent_runner-0.2.1/docs/marketing/README.md +0 -34
  121. cli_agent_runner-0.2.1/docs/marketing/promo-cn.html +0 -287
  122. cli_agent_runner-0.2.1/tests/integration/test_fresh_eyes_signal.py +0 -69
  123. cli_agent_runner-0.2.1/tests/integration/test_plugin_owned_paths.py +0 -88
  124. cli_agent_runner-0.2.1/tests/invariants/test_catalogs.py +0 -228
  125. cli_agent_runner-0.2.1/tests/invariants/test_event_kinds_ssot.py +0 -41
  126. cli_agent_runner-0.2.1/tests/unit/test_default_dirty_handler.py +0 -77
  127. cli_agent_runner-0.2.1/tests/unit/test_detector_helpers.py +0 -141
  128. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/.codecov.yml +0 -0
  129. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  130. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  131. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  132. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  133. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/.github/workflows/release.yml +0 -0
  134. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/CODE_OF_CONDUCT.md +0 -0
  135. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/LICENSE +0 -0
  136. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/__init__.py +0 -0
  137. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/_emit.py +0 -0
  138. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/_redact.py +0 -0
  139. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/_registry.py +0 -0
  140. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/_substrate.py +0 -0
  141. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/api_types.py +0 -0
  142. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/builtin_plugins/__init__.py +0 -0
  143. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/builtin_plugins/claude_rate_limit.py +0 -0
  144. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/builtin_plugins/codewhale.py +0 -0
  145. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/builtin_plugins/gemini.py +0 -0
  146. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/cli/__init__.py +0 -0
  147. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/cli/__main__.py +0 -0
  148. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/cli/common.py +0 -0
  149. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/cli/init_cmd.py +0 -0
  150. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/cli/monitor_cmd.py +0 -0
  151. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/cli/peek_cmd.py +0 -0
  152. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/cli/round_cmd.py +0 -0
  153. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/metrics.py +0 -0
  154. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/presets/__init__.py +0 -0
  155. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/presets/aider.toml +0 -0
  156. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/presets/claude.toml +0 -0
  157. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/presets/codewhale.toml +0 -0
  158. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/presets/gemini.toml +0 -0
  159. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/round_log.py +0 -0
  160. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/scaffold.py +0 -0
  161. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/agent_runner/service_unit.py +0 -0
  162. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/migrations/0.1.16.md +0 -0
  163. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/migrations/0.1.17.md +0 -0
  164. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/migrations/0.1.19.md +0 -0
  165. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/migrations/0.1.21.md +0 -0
  166. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/migrations/0.1.22.md +0 -0
  167. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/migrations/0.1.24.md +0 -0
  168. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/migrations/0.1.28.md +0 -0
  169. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/migrations/0.1.31.md +0 -0
  170. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/migrations/0.1.33.md +0 -0
  171. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/migrations/0.1.34.md +0 -0
  172. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/migrations/0.1.36.md +0 -0
  173. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/migrations/0.1.37.md +0 -0
  174. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/migrations/0.1.38.md +0 -0
  175. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/migrations/0.1.39.md +0 -0
  176. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/migrations/0.1.40.md +0 -0
  177. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/migrations/0.1.42.md +0 -0
  178. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/migrations/0.2.0.md +0 -0
  179. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/migrations/0.2.1.md +0 -0
  180. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/docs/recipes/codewhale.md +0 -0
  181. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/__init__.py +0 -0
  182. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/conftest.py +0 -0
  183. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/contract/__init__.py +0 -0
  184. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/e2e/__init__.py +0 -0
  185. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/e2e/conftest.py +0 -0
  186. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/e2e/test_e2e_graceful_stop.py +0 -0
  187. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/e2e/test_e2e_install_systemd.py +0 -0
  188. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/e2e/test_e2e_monitor_remote.py +0 -0
  189. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/e2e/test_e2e_round_lifecycle.py +0 -0
  190. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/fixtures/cli-real-output/claude-2.1.143-assistant-tool-use.jsonl +0 -0
  191. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/fixtures/cli-real-output/claude-2.1.143-result-event.jsonl +0 -0
  192. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/fixtures/cli-real-output/gemini-0.42.0-result-event.jsonl +0 -0
  193. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/integration/__init__.py +0 -0
  194. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/integration/test_bounded_run.py +0 -0
  195. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/integration/test_context_enricher_namespacing.py +0 -0
  196. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/integration/test_dirty_handler_seam.py +0 -0
  197. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/integration/test_grace_kill_emission.py +0 -0
  198. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/integration/test_install_dry_run.py +0 -0
  199. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/integration/test_monitor_seeded.py +0 -0
  200. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/integration/test_plugin_detector_loaded.py +0 -0
  201. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/integration/test_plugin_real_flow.py +0 -0
  202. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/integration/test_run_one_round_with_fake_agent.py +0 -0
  203. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/integration/test_serve_loop.py +0 -0
  204. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/integration/test_substrate_fingerprint.py +0 -0
  205. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/integration/test_transient_error_backoff.py +0 -0
  206. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/invariants/__init__.py +0 -0
  207. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/invariants/test_atomic_write_enforced.py +0 -0
  208. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/invariants/test_classification_ssot.py +0 -0
  209. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/invariants/test_docs_generated.py +0 -0
  210. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/invariants/test_entry_points_resolve.py +0 -0
  211. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/invariants/test_events_doc_contract.py +0 -0
  212. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/invariants/test_layer_2_loop_size.py +0 -0
  213. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/invariants/test_module_sizes.py +0 -0
  214. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/invariants/test_no_ai_signatures.py +0 -0
  215. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/invariants/test_no_pytest_skip_on_parse_fail.py +0 -0
  216. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/invariants/test_peek_schema_version.py +0 -0
  217. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/invariants/test_repo_constants_patched_in_tests.py +0 -0
  218. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/invariants/test_upstream_schema_canary.py +0 -0
  219. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/literate/__init__.py +0 -0
  220. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/literate/parser.py +0 -0
  221. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/literate/test_parser.py +0 -0
  222. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/literate/test_quickstart.py +0 -0
  223. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/__init__.py +0 -0
  224. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_agent_runtime_signal_name.py +0 -0
  225. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_api_assemble_prompt.py +0 -0
  226. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_api_events_stream.py +0 -0
  227. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_api_install.py +0 -0
  228. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_api_observation.py +0 -0
  229. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_api_read_round_num.py +0 -0
  230. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_api_resolve_phase.py +0 -0
  231. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_api_types.py +0 -0
  232. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_auto_stop_gating.py +0 -0
  233. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_catalogs.py +0 -0
  234. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_cli.py +0 -0
  235. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_cli_common.py +0 -0
  236. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_cli_init_install.py +0 -0
  237. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_cli_monitor_http.py +0 -0
  238. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_cli_upgrade.py +0 -0
  239. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_codewhale_plugin.py +0 -0
  240. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_config_fresh_eyes.py +0 -0
  241. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_config_max_rounds.py +0 -0
  242. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_config_prompt_delivery.py +0 -0
  243. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_config_stop_file.py +0 -0
  244. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_config_substrate_fingerprint_paths.py +0 -0
  245. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_config_transient_error_action.py +0 -0
  246. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_detector_protocol.py +0 -0
  247. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_dirty_handlers.py +0 -0
  248. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_events_cmd.py +0 -0
  249. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_exit_cause.py +0 -0
  250. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_fresh_eyes_trigger.py +0 -0
  251. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_gemini_plugin.py +0 -0
  252. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_hook_failure_isolation.py +0 -0
  253. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_hooks.py +0 -0
  254. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_http_progress.py +0 -0
  255. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_init_entry_points.py +0 -0
  256. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_lifecycle.py +0 -0
  257. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_metrics.py +0 -0
  258. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_monitor_assembly.py +0 -0
  259. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_monitor_detect_anomaly_repetitive.py +0 -0
  260. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_monitor_detect_rate_limit.py +0 -0
  261. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_monitor_detect_supervisor_stale.py +0 -0
  262. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_monitor_detectors.py +0 -0
  263. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_monitor_remote.py +0 -0
  264. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_network_blip_signal_guard.py +0 -0
  265. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_peek_argparse.py +0 -0
  266. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_peek_select.py +0 -0
  267. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_redact.py +0 -0
  268. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_round_log_helpers.py +0 -0
  269. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_round_view.py +0 -0
  270. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_runner_throttle.py +0 -0
  271. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_scaffold.py +0 -0
  272. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_serve_config_broken.py +0 -0
  273. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_serve_crash_loop.py +0 -0
  274. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_serve_round_log.py +0 -0
  275. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_serve_sentinel.py +0 -0
  276. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_serve_startup_hooks.py +0 -0
  277. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_service_unit.py +0 -0
  278. {cli_agent_runner-0.2.1 → cli_agent_runner-0.2.3}/tests/unit/test_substrate.py +0 -0
@@ -87,6 +87,10 @@ jobs:
87
87
  run: |
88
88
  ruff check .
89
89
  ruff format --check .
90
+ - name: vulture (dead-code scan)
91
+ # Config in [tool.vulture]; exits nonzero on any finding. No pipe — a
92
+ # `| tail` would swallow the exit code and let dead code through.
93
+ run: vulture
90
94
  - name: tests with coverage
91
95
  run: pytest -q --ignore=tests/e2e --ignore=tests/literate --cov --cov-report=xml --cov-report=term
92
96
  - name: docs CI gate
@@ -30,3 +30,8 @@ htmlcov/
30
30
 
31
31
  # Personal /team-onboarding artifact — not project content
32
32
  ONBOARDING.md
33
+
34
+ # Local tooling scratch directories — never project content, never published.
35
+ # Defense in depth only: releases build from a fresh CI checkout, and every
36
+ # sdist 0.1.1–0.2.1 was checked clean. This only guards a local `python -m build`.
37
+ .superpowers/
@@ -0,0 +1,244 @@
1
+ # GENERATED by tests/generate_vulture_whitelist.py — DO NOT EDIT BY HAND.
2
+ # Regenerate: ./build.sh vulture-whitelist
3
+ #
4
+ # vulture (min_confidence=60) reports @dataclass fields as "unused variable":
5
+ # they cross a JSON / CLI / plugin boundary static analysis cannot see. Each
6
+ # bare name below marks one field "used". SSOT = the @dataclass definitions in
7
+ # agent_runner/; a new field is covered by regenerating, never by editing here.
8
+
9
+ # agent_runner.agent_runtime.RunResult
10
+ exit_code
11
+ duration_s
12
+ timed_out
13
+ pid
14
+ killed_for_grace
15
+ grace_kill_children
16
+
17
+ # agent_runner.api_types.Alert
18
+ severity
19
+ detector
20
+ message
21
+ context
22
+ ts
23
+ auto_action
24
+
25
+ # agent_runner.api_types.DirtyOutcome
26
+ kind
27
+ ref
28
+
29
+ # agent_runner.api_types.InitResult
30
+ work_dir
31
+ files_created
32
+ committed
33
+ preset
34
+
35
+ # agent_runner.api_types.InstallResult
36
+ unit_path
37
+ monitor_unit_path
38
+ enabled
39
+ started
40
+
41
+ # agent_runner.api_types.ProjectState
42
+ project
43
+ status
44
+ defenses
45
+ current_round
46
+ recent_rounds
47
+ orphan
48
+ system
49
+ service
50
+ recent_events
51
+ recent_hook_failures
52
+ recent_blips
53
+
54
+ # agent_runner.api_types.RateLimitState
55
+ throttled_until_epoch
56
+ limit_type
57
+ agent
58
+ since_round
59
+
60
+ # agent_runner.api_types.RoundResult
61
+ round_num
62
+ phase
63
+ started_at
64
+ ended_at
65
+ exit_code
66
+ duration_s
67
+ timed_out
68
+ log_path
69
+ dirty_files
70
+ stashed
71
+ dirty_outcome
72
+ killed_for_grace
73
+
74
+ # agent_runner.api_types.RoundView
75
+ round_num
76
+ phase
77
+ started_at
78
+ duration_so_far_s
79
+ pid
80
+ exit_code
81
+ timed_out
82
+ log_path
83
+ log_tail
84
+ recent_events
85
+
86
+ # agent_runner.api_types.ServiceStatus
87
+ mode
88
+ active
89
+ pid
90
+ uptime_s
91
+ unit_file
92
+ rate_limit
93
+
94
+ # agent_runner.api_types.SystemMetrics
95
+ mem_total_mb
96
+ mem_available_mb
97
+ disk_used_pct
98
+ disk_free_gb
99
+ load_1m
100
+ cpu_pct
101
+ agent_process_count
102
+
103
+ # agent_runner.api_types.TransientErrorState
104
+ reset_at_epoch
105
+ classification
106
+ agent
107
+ since_round
108
+
109
+ # agent_runner.config.AgentConfig
110
+ command
111
+ prompt_arg_template
112
+ name
113
+ env
114
+ prompt_delivery
115
+
116
+ # agent_runner.config.Config
117
+ agent
118
+ runtime
119
+ prompt
120
+ vcs
121
+ monitor
122
+ phases
123
+ plugins
124
+
125
+ # agent_runner.config.MonitorConfig
126
+ auth_fail_patterns
127
+ auth_fail_hint
128
+ auto_stop_on
129
+ remote_failure_tolerance_s
130
+ anomaly_repetitive_window
131
+ anomaly_repetitive_threshold
132
+ host_health
133
+ round_progress_interval_s
134
+ supervisor_stale_threshold_s
135
+
136
+ # agent_runner.config.MonitorHostHealthConfig
137
+ mem_avail_min_mb
138
+ disk_warning_pct
139
+ disk_critical_pct
140
+
141
+ # agent_runner.config.PhaseOverride
142
+ round_timeout_s
143
+ disable_pre_round_hooks
144
+ prompt_files
145
+
146
+ # agent_runner.config.PhasesConfig
147
+ list
148
+ overrides
149
+
150
+ # agent_runner.config.PluginsConfig
151
+ disable
152
+ raw
153
+
154
+ # agent_runner.config.PromptConfig
155
+ file
156
+ files
157
+ inject_context
158
+ context_injection_mode
159
+ concat_separator
160
+ strip_yaml_frontmatter
161
+
162
+ # agent_runner.config.RuntimeConfig
163
+ work_dir
164
+ log_dir
165
+ round_timeout_s
166
+ restart_delay_s
167
+ disable_pre_round_hooks
168
+ round_log_retention
169
+ narrative_file
170
+ transient_error_action
171
+ max_rounds
172
+ stop_file
173
+ substrate_fingerprint_paths
174
+ fresh_eyes_every_n
175
+ dry_run
176
+ max_grace_after_result_s
177
+ grace_kill_ignore_patterns
178
+
179
+ # agent_runner.config.VcsConfig
180
+ stash_idempotency_s
181
+ dirty_action
182
+
183
+ # agent_runner.context_store.OrphanState
184
+ round_num
185
+ files
186
+ stashed_ref
187
+ stash_message
188
+ timestamp
189
+ phase
190
+
191
+ # agent_runner.context_store.Status
192
+ round_num
193
+ running
194
+ last_completed_at
195
+ last_exit_code
196
+ last_duration_s
197
+ current_phase
198
+ phase_index
199
+
200
+ # agent_runner.defenses.Defense
201
+ name
202
+ value
203
+ codifies
204
+ guarded_by
205
+ current_state
206
+
207
+ # agent_runner.hooks.HookContext
208
+ work_dir
209
+ log_dir
210
+ project
211
+ round_num
212
+ phase
213
+ agent_name
214
+ agent_binary
215
+ agent_log_path
216
+ dry_run
217
+ anomaly_repetitive_window
218
+ anomaly_repetitive_threshold
219
+ vcs
220
+
221
+ # agent_runner.hooks.VcsHookView
222
+ dirty_action
223
+ stash_idempotency_s
224
+
225
+ # agent_runner.lifecycle.PIDFile
226
+ path
227
+
228
+ # agent_runner.monitor.LocalSource
229
+ log_dir
230
+
231
+ # agent_runner.monitor.RemoteSource
232
+ host
233
+ project
234
+
235
+ # agent_runner.startup_check.CheckResult
236
+ name
237
+ ok
238
+ reason
239
+ how_to_fix
240
+
241
+ # agent_runner.vcs_state.StashRef
242
+ sha
243
+ message
244
+ reused
@@ -0,0 +1,90 @@
1
+ # Backlog
2
+
3
+ Known follow-ups that are real design or behavior decisions, not defects. Each
4
+ entry carries enough context to act on without re-deriving it.
5
+
6
+ Items marked **NEEDS_DESIGN** change user-visible behavior and are held for an
7
+ explicit decision — they are not shipped silently in a maintenance release.
8
+
9
+ ## `try_auto_commit` sweeps plugin-owned paths
10
+
11
+ `vcs_state.try_auto_commit` runs `git add -A` with an exclude pathspec built only
12
+ from the log directory (`_log_dir_exclude_pathspec`), so under
13
+ `vcs.dirty_action = "auto_commit"` paths registered via
14
+ `register_plugin_owned_paths` are committed along with the agent's work.
15
+
16
+ 0.2.2 made the registry authoritative at the git boundary for `stash_orphan`
17
+ only. That fix discharged the specific promise in `docs/plugins.md` that owned
18
+ paths are not silently swept into an orphan stash. `auto_commit` is a different
19
+ promise with a different harm (a commit, not a hidden stash) and no equivalent
20
+ published guarantee, so it needs its own call: should `auto_commit` honor the
21
+ registry, or is committing a plugin deliverable alongside agent work the
22
+ intended behavior?
23
+
24
+ ## `_tail_events` / `_tail_events_jsonl` duplication
25
+
26
+ `cli/events_cmd.py:_tail_events` and `api.py:_tail_events_jsonl` both tail the
27
+ event stream, deliberately at different scopes: `api` globs every
28
+ `events-*.jsonl`; `events_cmd` is current-month-scoped and resets its offset to
29
+ 0 on truncation. They are not accidental copies. Collapsing them means first
30
+ deciding which scope is correct for each caller.
31
+
32
+ Related, from the same area: the kind-read loops in `_throttle.py` and
33
+ `monitor.py` (`kind = ev.get("event")` over `reversed(events)`) are
34
+ character-identical after the 0.2.2 constant normalization. Extracting a shared
35
+ helper is a structural change, not a literal swap.
36
+
37
+ ## Detector fixtures pin raw event-kind literals
38
+
39
+ Detector test fixtures construct events from hardcoded strings (`{"event":
40
+ "round_start"}`) rather than emitting through `events.emit()`. Fixture and
41
+ reader therefore agree with each other while both can diverge from what the
42
+ supervisor actually writes.
43
+
44
+ Proven by mutation: point the emitter at a different kind value and the 28
45
+ `test_claude_error_detector.py` tests stay green while every detector is blind.
46
+ The 0.2.2 constant normalization does not close this — it moves the pin from the
47
+ reader to the fixture. Closing it means fixtures emitting through
48
+ `events.emit()`, or an end-to-end test asserting a real round produces events
49
+ the detectors actually match.
50
+
51
+ Bounded by `docs/events.md`, which forbids renaming a kind value outright (the
52
+ kind name is the version discriminator; a breaking change ships as
53
+ `round_start_v2`). Reaching this failure requires a contract violation — but the
54
+ suite would not report it.
55
+
56
+ ## `remote_failure_tolerance_s` does not cover `subprocess.TimeoutExpired` — NEEDS_DESIGN
57
+
58
+ The tolerance window covers ssh exit code 255 only. `monitor.run_remote_command`
59
+ raises `MonitorRemoteError` on rc=255, and `api.monitor_loop`'s retry loop
60
+ catches exactly that. A hung (not failed) ssh connection instead trips the
61
+ `subprocess.run(timeout=...)` guard and raises `subprocess.TimeoutExpired`,
62
+ which bypasses the window and kills the monitor.
63
+
64
+ The rc=255-only scope is intentional and pinned by the monitor-signals design,
65
+ and the documentation matches the code exactly — there is no drift here. Widening
66
+ it changes a documented recovery path, so it is a design decision, not debt.
67
+
68
+ ## `anomaly_repetitive_*` default — NEEDS_DESIGN
69
+
70
+ `monitor.anomaly_repetitive_window` and `anomaly_repetitive_threshold` both
71
+ default to `0`, which disables the detector. This is a deliberate opt-in kill
72
+ switch, documented since the field's first commit, and the detector fires
73
+ correctly the moment an operator opts in.
74
+
75
+ The open question is whether opt-in is the right default, or whether this belongs
76
+ in a preset. Flipping the default would arm a new alert for every existing
77
+ deployment.
78
+
79
+ ## `stash_orphan` loses the ref when the post-push listing fails
80
+
81
+ `vcs_state.stash_orphan` returns `None` in three cases; two are true no-ops. The
82
+ third — `git stash push` succeeded but the follow-up `git stash list` failed —
83
+ means the WIP *is* stashed yet callers read "nothing stashed" and report the
84
+ tree as ignored. It is already documented in-code as a KNOWN GAP and judged
85
+ effectively unreachable (a listing that fails microseconds after a push that
86
+ just succeeded in the same repo).
87
+
88
+ Deferred because closing it is a naming decision, not cleanup: no event kind
89
+ carries the meaning "stashed but ref lost" (`orphan_stash_failed` would be wrong
90
+ — the stash exists). Left as-is until that kind is designed.
@@ -5,6 +5,41 @@ 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
+
20
+ ## [0.2.2] - 2026-07-18
21
+
22
+ ### Removed
23
+ - `agent_runner.detector_helpers` and its three helpers (`cumulative_window_check`, `dual_source_silence`, `phase_filter`) — **breaking** for any out-of-tree detector that imported them; vendor the ~115 LOC.
24
+ - `agent-runner cancel` and `api.cancel()` — **breaking**; they never delivered the documented SIGINT-to-round semantics (nothing ever wrote the `round.pid` they read), so `cancel` was only a slower alias for `stop`. Use `stop`; `serve` no longer traps `SIGUSR1`.
25
+ - `events.SIGTERM_RECEIVED` (the `sigterm_received` kind) — declared but never emitted, so nothing could ever observe it.
26
+
27
+ ### Changed
28
+ - Paths registered with `register_plugin_owned_paths` are no longer swept into the orphan stash: all three documented pattern forms (trailing-slash prefix, glob, `**/*`) are now honored at the git boundary, not only the report boundary, so a deliverable is no longer silently stashed — and possibly lost — when the agent also touches a non-owned file. `**/*` patterns now also match files directly in the registered directory, changing which paths `detect_dirty_files` filters. **Check `git stash list` if you register owned paths.**
29
+ - Config-load rejections now raise `ConfigError` (a subclass of `ValueError`) consistently; fully backward compatible — any `except ValueError` still catches them.
30
+ - `[monitor.host_health]` percent thresholds, `[prompt] inject_context`, and `[monitor] auth_fail_patterns` are validated at load, so configs that were previously accepted-but-silently-broken now fail loudly at startup.
31
+
32
+ ### Fixed
33
+ - `agent-runner events --tail` no longer re-emits events appended while a poll's read loop was in flight.
34
+ - The orphan-stash defense now signals push failure (`orphan_stash_failed`) and idempotent reuse (`orphan_idempotent_skip`) — both kinds were declared but never emitted — instead of degrading silently; `stash_orphan` raises `StashError` (re-exported from `agent_runner.api`) on push failure.
35
+ - Plugin-supplied transient-error classifications no longer crash the supervisor with `KeyError`.
36
+ - Defense-catalog honesty (every advertised defense now names a real guarding test) and ~31 false claims across README, docs, and docstrings.
37
+
38
+ ### Added
39
+ - Housekeeping: the build gate runs `vulture` (dead-code scan, whitelist auto-generated from `@dataclass` fields); `AGENT_RUNNER_FRESH_EYES` is now a documented, tested round-subprocess env-var contract; `SECURITY.md` gains a threat model (agent-runner is a supervisor, not a sandbox).
40
+
41
+ See `docs/migrations/0.2.2.md`.
42
+
8
43
  ## [0.2.1] - 2026-07-16
9
44
 
10
45
  ### Added
@@ -363,7 +398,7 @@ See `docs/migrations/0.1.17.md`.
363
398
 
364
399
  ### Acknowledgements
365
400
 
366
- Argus Gateway'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.
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.
367
402
 
368
403
  ## [0.1.15] - 2026-05-14
369
404
 
@@ -395,10 +430,10 @@ independent components bundled into one release because both serve the same
395
430
 
396
431
  ### Acknowledgements
397
432
 
398
- Two of six nice-to-have items surfaced in Argus Gateway's v0.1.12
433
+ Two of six nice-to-have items surfaced in a downstream integrator's v0.1.12
399
434
  production-evaluation report (2026-05-14). An earlier scope also included
400
435
  per-phase runtime override; spec review caught that `runtime.round_timeout_per_phase`
401
- already covers Argus's stated need, so that component was deferred to a future
436
+ already covers the integrator's stated need, so that component was deferred to a future
402
437
  release where a second per-phase field surfaces. Other items in the report
403
438
  (detector helper, hot-reload, replay) remain intentionally out of scope.
404
439
 
@@ -417,7 +452,7 @@ release where a second per-phase field surfaces. Other items in the report
417
452
 
418
453
  ### Acknowledgements
419
454
 
420
- Thanks to the Argus Gateway team — this release answers their imminent
455
+ Thanks to our downstream integrators — this release answers their imminent
421
456
  production-deployment requirement for upgrade-without-disruption. After
422
457
  confirming round duration (10-40 min) fits within graceful-stop tolerance,
423
458
  this release scopes to round-boundary upgrade UX (Level 1). Mid-round
@@ -442,7 +477,7 @@ real production need.
442
477
 
443
478
  ### Acknowledgements
444
479
 
445
- Thanks to the Argus Gateway team for the deep v0.1.10 audit-session feedback
480
+ Thanks to our downstream integrators for the deep v0.1.10 audit-session feedback
446
481
  (6 items, 3-round real-run testing on ARMv8 Pi). This release reframes those
447
482
  items into a coherent "Plugin & Operator Transparency" theme across three
448
483
  layers: transparency (see what plugins do), operator override (escape hatches
@@ -464,16 +499,16 @@ for audit/debug), and diagnostic quality (errors point at the next debug step).
464
499
 
465
500
  ### Migration notes
466
501
 
467
- - `Config.plugins` type change is breaking for any caller reading the field as a dict (`cfg.plugins.get("foo")`). Plugin authors using `[plugins.argus_*]`-style keys: read them from `cfg.plugins.raw.get("argus_*")` instead.
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.
468
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.
469
- - For Argus'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.
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.
470
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.
471
506
 
472
507
  ## [0.1.11] - 2026-05-13
473
508
 
474
509
  ### Acknowledgements
475
510
 
476
- Thanks again to the Argus Gateway team — this release closes the
511
+ Thanks again to our downstream integrators — this release closes the
477
512
  network-resilience gap that 0.1.10's `MonitorRemoteError` propagation
478
513
  exposed, plus adds per-occurrence agent network blip observability requested
479
514
  during 0.1.10 handover review.
@@ -502,7 +537,7 @@ For network-related failures, the events index points at the diagnostic body:
502
537
 
503
538
  ### Acknowledgements
504
539
 
505
- Thanks to the Argus Gateway team 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.
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.
506
541
 
507
542
  ### Added
508
543
 
@@ -530,7 +565,7 @@ Thanks to the Argus Gateway team for the Phase 4 second-pass production feedback
530
565
 
531
566
  ### Acknowledgements
532
567
 
533
- Thanks to the argus-gateway team for the dev/qa/product wall-time data
568
+ Thanks to our downstream integrators for the dev/qa/product wall-time data
534
569
  (Phase 4 feedback §3.1) that drove this API shape. Their three-role
535
570
  distribution made the case for per-phase overrides concrete.
536
571
 
@@ -556,7 +591,7 @@ documented plugin-author public surface.
556
591
 
557
592
  ### Acknowledgements
558
593
 
559
- Thanks to the argus-gateway team for Phase 4 dogfooding feedback that drove
594
+ Thanks to our downstream integrators for Phase 4 dogfooding feedback that drove
560
595
  every item in this release. 3 audit memos (~90KB) silently swept into an
561
596
  orphan stash is a real-world failure mode; this release closes that loop.
562
597
 
@@ -585,7 +620,7 @@ orphan stash is a real-world failure mode; this release closes that loop.
585
620
 
586
621
  - Plugin outputs in plugin-declared paths (e.g. `proposals/`,
587
622
  `logs/plugins/my_plugin/`) no longer silently swept into orphan stashes
588
- by `process_orphan_wip`. Previously: 90KB Argus audit memos invisible
623
+ by `process_orphan_wip`. Previously: 90KB audit memos invisible
589
624
  after Phase 4 round; required stash archaeology to recover.
590
625
 
591
626
  ### Migration
@@ -628,7 +663,7 @@ Or regenerate cleanly:
628
663
  agent-runner init --preset claude --force
629
664
  ```
630
665
 
631
- Plugin authors (Argus Gateway, etc.): no public API was renamed or removed
666
+ Plugin authors (downstream integrators, etc.): no public API was renamed or removed
632
667
  from your import surface. The deleted symbols (`agent_runner.agent_runtime.CRITICAL_ENV_DEFAULTS`,
633
668
  `agent_runner.agent_runtime.merge_critical_envs`) were internal — not part of
634
669
  the documented plugin API. A new public-API contract test
@@ -859,7 +894,7 @@ Initial public release on PyPI as `cli-agent-runner`.
859
894
 
860
895
  ### Added
861
896
  - Three-layer model: Round / Loop / Witness.
862
- - 13 CLI verbs: `init`, `install`, `uninstall`, `start`, `stop`, `kill`,
897
+ - 14 CLI verbs: `init`, `install`, `uninstall`, `start`, `stop`, `kill`,
863
898
  `cancel`, `restart`, `status`, `round`, `serve`, `peek`, `watch`, `monitor`.
864
899
  - 11 named defenses (round timeout, process group isolation, orphan stash
865
900
  with SHA lock, set-diff classification, smoke check, flock concurrency,
@@ -886,7 +921,10 @@ Initial public release on PyPI as `cli-agent-runner`.
886
921
  - Tag-triggered release publishing to PyPI via Trusted Publishing OIDC,
887
922
  gated by a manual approval on the `pypi` GitHub environment.
888
923
 
889
- [Unreleased]: https://github.com/wan9yu/cli-agent-runner/compare/v0.2.0...HEAD
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
890
928
  [0.2.0]: https://github.com/wan9yu/cli-agent-runner/compare/v0.1.42...v0.2.0
891
929
  [0.1.26]: https://github.com/wan9yu/cli-agent-runner/compare/v0.1.25...v0.1.26
892
930
  [0.1.25]: https://github.com/wan9yu/cli-agent-runner/compare/v0.1.24...v0.1.25
@@ -29,6 +29,26 @@ what GitHub Actions runs on every push and PR.
29
29
  reject auto-generated trailers and robot signatures — keep messages
30
30
  human-authored.
31
31
 
32
+ ## Migration docs
33
+
34
+ A `docs/migrations/<version>.md` guide is written **only** when a release:
35
+
36
+ - makes a **breaking change** — a removed or renamed public symbol, or a
37
+ config that used to load and now does not; or
38
+ - **requires operator action** — a TOML edit, a manual recovery step, or a
39
+ data/format migration.
40
+
41
+ Otherwise `CHANGELOG.md` carries the whole story; a guide that only restates
42
+ the changelog is upkeep with no reader. When a guide does exist, keep the
43
+ CHANGELOG entry terse and link it (`See docs/migrations/<version>.md.`).
44
+
45
+ 0.2.2 is the first release written under this policy: it removes two public
46
+ symbols — the `detector_helpers` module and the `cancel` verb — so it ships a
47
+ guide. Existing `docs/migrations/` files are history: append-only, never
48
+ rewritten or deleted, including ones this policy would not have produced.
49
+ Correct a shipped guide with a dated `**Correction (<version>)**:` note, not
50
+ an edit in place.
51
+
32
52
  ## Architecture / docs
33
53
 
34
54
  - [`docs/architecture.md`](docs/architecture.md) — 3-layer model, defenses-as-data.
@@ -40,6 +60,12 @@ table in `docs/*.md` are auto-generated by `./build.sh docs`. The CI gate
40
60
  fails if those regions drift from the code's source of truth. Don't edit
41
61
  them manually — edit the generator or the data source.
42
62
 
63
+ `.vulture-whitelist.py` is likewise generated — from every `@dataclass` field
64
+ in `agent_runner/`. If you add or rename a dataclass field, run
65
+ `./build.sh vulture-whitelist` and commit the regenerated file;
66
+ `tests/invariants/test_vulture_whitelist_generated.py` fails the gate if it
67
+ drifts.
68
+
43
69
  ## Tests
44
70
 
45
71
  - Unit + integration: `pytest -q --ignore=tests/e2e --ignore=tests/literate`
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cli-agent-runner
3
- Version: 0.2.1
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
@@ -31,7 +31,6 @@ Requires-Dist: pytest>=8; extra == 'dev'
31
31
  Requires-Dist: ruff>=0.5; extra == 'dev'
32
32
  Requires-Dist: vulture>=2.13; extra == 'dev'
33
33
  Provides-Extra: e2e
34
- Requires-Dist: fabric>=3; extra == 'e2e'
35
34
  Requires-Dist: pytest>=8; extra == 'e2e'
36
35
  Description-Content-Type: text/markdown
37
36
 
@@ -41,9 +40,10 @@ Description-Content-Type: text/markdown
41
40
 
42
41
  # agent-runner
43
42
 
44
- A restart-on-exit supervisor for autonomous coding CLIs. Tested with Claude
45
- Code and aider out of the box; any prompt-arg CLI via custom config. Spawn
46
- the agent round-after-round under defenses that prevent the failure modes
43
+ A restart-on-exit supervisor for autonomous coding CLIs. Ships presets for
44
+ Claude Code, aider, gemini, codewhale, kimi and pi; any prompt-arg CLI via custom
45
+ config. Spawn the agent round-after-round under defenses that prevent the
46
+ failure modes
47
47
  that bite in production: stuck rounds, orphan commits, OAuth burn loops,
48
48
  full disks, runaway memory.
49
49
 
@@ -80,12 +80,12 @@ agent-runner monitor # live anomaly detection
80
80
 
81
81
  Full walkthrough: [`docs/quickstart.md`](docs/quickstart.md).
82
82
 
83
- ## 16 verbs
83
+ ## 15 verbs
84
84
 
85
85
  | Lifecycle | Observation |
86
86
  |---|---|
87
87
  | `init` / `install` / `uninstall` | `peek` — state snapshot |
88
- | `start` / `stop` / `kill` / `cancel` | `watch` — peek in a refresh loop |
88
+ | `start` / `stop` / `kill` | `watch` — peek in a refresh loop |
89
89
  | `restart` / `status` | `monitor` — 11 detectors, alerts, auto-stop |
90
90
  | `round` / `serve` / `upgrade` | `events` — query / stream events.jsonl |
91
91
 
@@ -4,9 +4,10 @@
4
4
 
5
5
  # agent-runner
6
6
 
7
- A restart-on-exit supervisor for autonomous coding CLIs. Tested with Claude
8
- Code and aider out of the box; any prompt-arg CLI via custom config. Spawn
9
- the agent round-after-round under defenses that prevent the failure modes
7
+ A restart-on-exit supervisor for autonomous coding CLIs. Ships presets for
8
+ Claude Code, aider, gemini, codewhale, kimi and pi; any prompt-arg CLI via custom
9
+ config. Spawn the agent round-after-round under defenses that prevent the
10
+ failure modes
10
11
  that bite in production: stuck rounds, orphan commits, OAuth burn loops,
11
12
  full disks, runaway memory.
12
13
 
@@ -43,12 +44,12 @@ agent-runner monitor # live anomaly detection
43
44
 
44
45
  Full walkthrough: [`docs/quickstart.md`](docs/quickstart.md).
45
46
 
46
- ## 16 verbs
47
+ ## 15 verbs
47
48
 
48
49
  | Lifecycle | Observation |
49
50
  |---|---|
50
51
  | `init` / `install` / `uninstall` | `peek` — state snapshot |
51
- | `start` / `stop` / `kill` / `cancel` | `watch` — peek in a refresh loop |
52
+ | `start` / `stop` / `kill` | `watch` — peek in a refresh loop |
52
53
  | `restart` / `status` | `monitor` — 11 detectors, alerts, auto-stop |
53
54
  | `round` / `serve` / `upgrade` | `events` — query / stream events.jsonl |
54
55
 
@@ -0,0 +1,37 @@
1
+ > 中文 · **[English](README.md)**
2
+
3
+ # agent-runner
4
+
5
+ 把任意 CLI agent(Claude Code、aider、任何接受 prompt 参数的命令)包装成能被
6
+ systemd / launchd 拉起、能被远程观测的服务。**每轮跑完进程退出**,外层
7
+ supervisor 重启 —— 这是核心模式。中间穿插一组防御,避开 production 上最容易
8
+ 翻车的几条路:轮卡死、脏文件没 commit、OAuth 失效烧 quota、磁盘写满、
9
+ 两个 supervisor 抢同一个仓库。
10
+
11
+ 三层,每层都能独立运行,上层都是可选的:`round` 跑一次 agent 跑完即退;
12
+ `serve` 捕获信号循环拉起 round;`monitor` 检测器 + 告警,critical 时自动停服
13
+ (本机或 ssh 远程)。
14
+
15
+ ## 安装
16
+
17
+ ```bash
18
+ pip install cli-agent-runner
19
+ ```
20
+
21
+ CLI 命令是 `agent-runner`(PyPI 包名加 `cli-` 前缀只是为了规避命名冲突,
22
+ 导入名 `agent_runner` 和命令名都不变)。
23
+
24
+ ## 完整文档
25
+
26
+ 文档以英文为准。下面 `docs/` 各页末尾都附有中文摘要,完整细节见英文正文:
27
+
28
+ - [`docs/quickstart.md`](docs/quickstart.md) —— 5 步装好并跑通第一轮
29
+ - [`README.md`](README.md) —— 定位、动词表、内置防御、Monitor 检测器
30
+ - [`docs/architecture.md`](docs/architecture.md) —— 三层模型 + defenses-as-data
31
+ - [`docs/commands.md`](docs/commands.md) —— 动词参考
32
+ - [`docs/configuration.md`](docs/configuration.md) —— `agent-runner.toml` schema
33
+ - [`docs/runbook.md`](docs/runbook.md) —— 操作手册 + 故障排查
34
+
35
+ ## License
36
+
37
+ [Apache License 2.0](LICENSE).