cheaphelp 1.0.0__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 (103) hide show
  1. cheaphelp-1.0.0/AGENTS.md +1 -0
  2. cheaphelp-1.0.0/CHANGELOG.md +60 -0
  3. cheaphelp-1.0.0/CLAUDE.md +127 -0
  4. cheaphelp-1.0.0/CODE_OF_CONDUCT.md +84 -0
  5. cheaphelp-1.0.0/CONTRIBUTING.md +112 -0
  6. cheaphelp-1.0.0/LICENSE +21 -0
  7. cheaphelp-1.0.0/PKG-INFO +112 -0
  8. cheaphelp-1.0.0/README.md +82 -0
  9. cheaphelp-1.0.0/config/coverage.ini +25 -0
  10. cheaphelp-1.0.0/config/git-changelog.toml +9 -0
  11. cheaphelp-1.0.0/config/pytest.ini +16 -0
  12. cheaphelp-1.0.0/config/ruff.toml +102 -0
  13. cheaphelp-1.0.0/config/ty.toml +6 -0
  14. cheaphelp-1.0.0/config/vscode/launch.json +56 -0
  15. cheaphelp-1.0.0/config/vscode/settings.json +31 -0
  16. cheaphelp-1.0.0/config/vscode/tasks.json +97 -0
  17. cheaphelp-1.0.0/docs/.overrides/partials/comments.html +57 -0
  18. cheaphelp-1.0.0/docs/background-service.md +34 -0
  19. cheaphelp-1.0.0/docs/changelog.md +5 -0
  20. cheaphelp-1.0.0/docs/code_of_conduct.md +5 -0
  21. cheaphelp-1.0.0/docs/configuration.md +50 -0
  22. cheaphelp-1.0.0/docs/contributing.md +5 -0
  23. cheaphelp-1.0.0/docs/cost-tracking.md +17 -0
  24. cheaphelp-1.0.0/docs/credits.md +9 -0
  25. cheaphelp-1.0.0/docs/css/apidocs.css +21 -0
  26. cheaphelp-1.0.0/docs/dev-guide.md +48 -0
  27. cheaphelp-1.0.0/docs/getting-started.md +86 -0
  28. cheaphelp-1.0.0/docs/index.md +59 -0
  29. cheaphelp-1.0.0/docs/js/feedback.js +14 -0
  30. cheaphelp-1.0.0/docs/license.md +11 -0
  31. cheaphelp-1.0.0/docs/pipeline.md +67 -0
  32. cheaphelp-1.0.0/docs/reference/api.md +11 -0
  33. cheaphelp-1.0.0/docs/sandboxing.md +26 -0
  34. cheaphelp-1.0.0/docs/workspace.md +50 -0
  35. cheaphelp-1.0.0/duties.py +204 -0
  36. cheaphelp-1.0.0/pyproject.toml +109 -0
  37. cheaphelp-1.0.0/scripts/gen_credits.py +178 -0
  38. cheaphelp-1.0.0/scripts/get_version.py +31 -0
  39. cheaphelp-1.0.0/scripts/make +1 -0
  40. cheaphelp-1.0.0/scripts/make.py +227 -0
  41. cheaphelp-1.0.0/src/cheaphelp/__init__.py +10 -0
  42. cheaphelp-1.0.0/src/cheaphelp/__main__.py +14 -0
  43. cheaphelp-1.0.0/src/cheaphelp/_internal/__init__.py +0 -0
  44. cheaphelp-1.0.0/src/cheaphelp/_internal/cleanup.py +111 -0
  45. cheaphelp-1.0.0/src/cheaphelp/_internal/cli.py +372 -0
  46. cheaphelp-1.0.0/src/cheaphelp/_internal/commands.py +1025 -0
  47. cheaphelp-1.0.0/src/cheaphelp/_internal/config.py +326 -0
  48. cheaphelp-1.0.0/src/cheaphelp/_internal/conventions.py +21 -0
  49. cheaphelp-1.0.0/src/cheaphelp/_internal/debug.py +107 -0
  50. cheaphelp-1.0.0/src/cheaphelp/_internal/env.py +103 -0
  51. cheaphelp-1.0.0/src/cheaphelp/_internal/fixer.py +133 -0
  52. cheaphelp-1.0.0/src/cheaphelp/_internal/github.py +372 -0
  53. cheaphelp-1.0.0/src/cheaphelp/_internal/gitutil.py +216 -0
  54. cheaphelp-1.0.0/src/cheaphelp/_internal/lock.py +83 -0
  55. cheaphelp-1.0.0/src/cheaphelp/_internal/opencode.py +655 -0
  56. cheaphelp-1.0.0/src/cheaphelp/_internal/orchestrator.py +801 -0
  57. cheaphelp-1.0.0/src/cheaphelp/_internal/planner.py +187 -0
  58. cheaphelp-1.0.0/src/cheaphelp/_internal/pr_state.py +48 -0
  59. cheaphelp-1.0.0/src/cheaphelp/_internal/registry.py +147 -0
  60. cheaphelp-1.0.0/src/cheaphelp/_internal/responder.py +225 -0
  61. cheaphelp-1.0.0/src/cheaphelp/_internal/reviewer.py +322 -0
  62. cheaphelp-1.0.0/src/cheaphelp/_internal/rework.py +371 -0
  63. cheaphelp-1.0.0/src/cheaphelp/_internal/spend.py +107 -0
  64. cheaphelp-1.0.0/src/cheaphelp/_internal/systemd.py +302 -0
  65. cheaphelp-1.0.0/src/cheaphelp/_internal/tasks.py +263 -0
  66. cheaphelp-1.0.0/src/cheaphelp/_internal/templates/__init__.py +24 -0
  67. cheaphelp-1.0.0/src/cheaphelp/_internal/templates/fixer.md +50 -0
  68. cheaphelp-1.0.0/src/cheaphelp/_internal/templates/planner.md +64 -0
  69. cheaphelp-1.0.0/src/cheaphelp/_internal/templates/responder.md +154 -0
  70. cheaphelp-1.0.0/src/cheaphelp/_internal/templates/reviewer.md +53 -0
  71. cheaphelp-1.0.0/src/cheaphelp/_internal/templates/rework.md +61 -0
  72. cheaphelp-1.0.0/src/cheaphelp/_internal/templates/worker.md +49 -0
  73. cheaphelp-1.0.0/src/cheaphelp/_internal/worker.py +147 -0
  74. cheaphelp-1.0.0/src/cheaphelp/py.typed +0 -0
  75. cheaphelp-1.0.0/tests/__init__.py +7 -0
  76. cheaphelp-1.0.0/tests/conftest.py +242 -0
  77. cheaphelp-1.0.0/tests/test_api.py +163 -0
  78. cheaphelp-1.0.0/tests/test_cleanup.py +79 -0
  79. cheaphelp-1.0.0/tests/test_cli_basics.py +52 -0
  80. cheaphelp-1.0.0/tests/test_cli_clean.py +47 -0
  81. cheaphelp-1.0.0/tests/test_cli_config.py +297 -0
  82. cheaphelp-1.0.0/tests/test_cli_doctor.py +199 -0
  83. cheaphelp-1.0.0/tests/test_cli_logs.py +122 -0
  84. cheaphelp-1.0.0/tests/test_cli_repo.py +470 -0
  85. cheaphelp-1.0.0/tests/test_cli_retry.py +631 -0
  86. cheaphelp-1.0.0/tests/test_cli_run.py +514 -0
  87. cheaphelp-1.0.0/tests/test_cli_status.py +704 -0
  88. cheaphelp-1.0.0/tests/test_config.py +271 -0
  89. cheaphelp-1.0.0/tests/test_conventions.py +65 -0
  90. cheaphelp-1.0.0/tests/test_fixer.py +125 -0
  91. cheaphelp-1.0.0/tests/test_github.py +322 -0
  92. cheaphelp-1.0.0/tests/test_gitutil.py +85 -0
  93. cheaphelp-1.0.0/tests/test_opencode.py +714 -0
  94. cheaphelp-1.0.0/tests/test_orchestrator.py +1139 -0
  95. cheaphelp-1.0.0/tests/test_planner.py +238 -0
  96. cheaphelp-1.0.0/tests/test_responder.py +389 -0
  97. cheaphelp-1.0.0/tests/test_reviewer.py +384 -0
  98. cheaphelp-1.0.0/tests/test_rework.py +620 -0
  99. cheaphelp-1.0.0/tests/test_spend.py +95 -0
  100. cheaphelp-1.0.0/tests/test_systemd.py +515 -0
  101. cheaphelp-1.0.0/tests/test_tasks.py +299 -0
  102. cheaphelp-1.0.0/tests/test_worker.py +338 -0
  103. cheaphelp-1.0.0/zensical.toml +181 -0
@@ -0,0 +1 @@
1
+ CLAUDE.md
@@ -0,0 +1,60 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
6
+ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
7
+
8
+ <!-- insertion marker -->
9
+ ## [1.0.0](https://github.com/jacotay7/cheaphelp/releases/tag/1.0.0) - 2026-06-14
10
+
11
+ <small>[Compare with first commit](https://github.com/jacotay7/cheaphelp/compare/4e6e0365dc8de03ebbfd97a3d418cb181608799d...1.0.0)</small>
12
+
13
+ ### Features
14
+
15
+ - `--linger` flag to enable lingering during install (#102) ([544c7d5](https://github.com/jacotay7/cheaphelp/commit/544c7d58a6f61bcba8bf9d2fe7fb6a9fe68baa15) by Jacob Taylor). Co-authored-by: cheaphelp[bot] <cheaphelp@users.noreply.github.com>
16
+ - repair a failing quality gate with a fixer before replanning (#101) ([9210638](https://github.com/jacotay7/cheaphelp/commit/92106383bfae50347649e397dbbf66960c0063a4) by Jacob Taylor). Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
17
+ - include per-issue cost breakdown in opened PR descriptions (#100) ([ada7503](https://github.com/jacotay7/cheaphelp/commit/ada7503da108be365431b35c579e97d7b4d9515b) by Jacob Taylor). Co-authored-by: cheaphelp[bot] <cheaphelp@users.noreply.github.com>
18
+ - surface service run result in `systemd status` (#94) ([cecc993](https://github.com/jacotay7/cheaphelp/commit/cecc9930d8d5fe57ceac855b285d57834c813f39) by Jacob Taylor). Co-authored-by: cheaphelp[bot] <cheaphelp@users.noreply.github.com>
19
+ - show today's spend vs daily budget footer (#95) ([29d8c5d](https://github.com/jacotay7/cheaphelp/commit/29d8c5df8db95c79b6b98a3855368e1d196eccbe) by Jacob Taylor). Co-authored-by: cheaphelp[bot] <cheaphelp@users.noreply.github.com>
20
+ - persist unparseable agent output to last_unparsed_<role>.log (#93) ([4ca4aaa](https://github.com/jacotay7/cheaphelp/commit/4ca4aaa89cf12b7298f7ef153bed62c0cbbf6c16) by Jacob Taylor). Co-authored-by: cheaphelp[bot] <cheaphelp@users.noreply.github.com>
21
+ - report systemd timer/service health in cheaphelp doctor (#92) ([f2958c2](https://github.com/jacotay7/cheaphelp/commit/f2958c248a77372561988b6cd5d3a17368d01cb2) by Jacob Taylor). Co-authored-by: cheaphelp[bot] <cheaphelp@users.noreply.github.com>
22
+ - add daily spend budget guardrail with warn/exceeded comments (#74) ([728aaf6](https://github.com/jacotay7/cheaphelp/commit/728aaf60f61e27f18719b5a168cfdb7bad0431f5) by Jacob Taylor). Co-authored-by: cheaphelp[bot] <cheaphelp@users.noreply.github.com>
23
+ - Label needs-human on comment; route back to responder on human reply (#73) ([3f3c493](https://github.com/jacotay7/cheaphelp/commit/3f3c49315b2a87f072edd588f986584ac07b5138) by Jacob Taylor). Co-authored-by: cheaphelp[bot] <cheaphelp@users.noreply.github.com>
24
+ - Allow `cheaphelp run` for many ticks (`-n` / `--continuous`) (#75) ([5b52ed9](https://github.com/jacotay7/cheaphelp/commit/5b52ed9586b24c3c257982bf2cc8765ac854c2bc) by Jacob Taylor). Co-authored-by: cheaphelp[bot] <cheaphelp@users.noreply.github.com>
25
+ - Add `cheaphelp retry` to un-stick issues labeled needs-human (#72) ([c1bead1](https://github.com/jacotay7/cheaphelp/commit/c1bead1fcabb762ee818fb1c257230af366eabe4) by Jacob Taylor). Co-authored-by: cheaphelp[bot] <cheaphelp@users.noreply.github.com>
26
+ - Act on PR review feedback instead of leaving issues stuck in-review (#68) ([25f5f3f](https://github.com/jacotay7/cheaphelp/commit/25f5f3fdca0735b00a6c6d95f003660865670d56) by Jacob Taylor). Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
27
+ - Add `cheaphelp config` subcommand (show/get/set) with auto-regen (#63) ([1d26895](https://github.com/jacotay7/cheaphelp/commit/1d26895af99eab3f8ea4af08b4ae118d140ff0bb) by Jacob Taylor). Co-authored-by: cheaphelp[bot] <cheaphelp@users.noreply.github.com>, Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
28
+ - track token usage and cost per tick, per role, and per issue (#64) ([e087550](https://github.com/jacotay7/cheaphelp/commit/e0875507cf49aa6fdca30315183296292e7fe6ec) by Jacob Taylor). Co-authored-by: cheaphelp[bot] <cheaphelp@users.noreply.github.com>, Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
29
+ - retry transient GitHub and OpenRouter failures with backoff (#62) ([2daca10](https://github.com/jacotay7/cheaphelp/commit/2daca1020f7ce4156e314d6b0927dd17d7594645) by Jacob Taylor). Co-authored-by: cheaphelp[bot] <cheaphelp@users.noreply.github.com>
30
+ - add `cheaphelp logs` subcommand for viewing and following run activity (#61) ([f3e99a3](https://github.com/jacotay7/cheaphelp/commit/f3e99a30252320c1122909d1c90ca549947c1a86) by Jacob Taylor). Co-authored-by: cheaphelp[bot] <cheaphelp@users.noreply.github.com>
31
+ - Blast-radius guardrail caps PR diff size (max files/lines) (#60) ([6037d91](https://github.com/jacotay7/cheaphelp/commit/6037d913867c2cb145e9928b97d0e8b98d47957a) by Jacob Taylor). Co-authored-by: cheaphelp[bot] <cheaphelp@users.noreply.github.com>
32
+ - Let agents follow a project's own contribution conventions (#59) ([7a8e8be](https://github.com/jacotay7/cheaphelp/commit/7a8e8bed6f699d7fa755a032bcf061494f481328) by Jacob Taylor). Co-authored-by: cheaphelp[bot] <cheaphelp@users.noreply.github.com>
33
+ - Prune build clones for closed issues; add `cheaphelp clean` (#45) ([302eec9](https://github.com/jacotay7/cheaphelp/commit/302eec9601892308fa0983f22660b8af0d2f7828) by Jacob Taylor). Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
34
+ - Retry timed-out tasks; re-prompt agents that emit no decision (#44) ([17e8ab6](https://github.com/jacotay7/cheaphelp/commit/17e8ab6b7cf95f4cfccb1ec9d93ba2863fc85a67) by Jacob Taylor). Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
35
+ - Hold issues until their dependencies close (#35 part 2) (#43) ([4aeb146](https://github.com/jacotay7/cheaphelp/commit/4aeb14659313a4b63ce8c2fa90226980024566e4) by Jacob Taylor). Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
36
+ - Parallel ticks via per-issue locks (#35 part 1) (#42) ([0ba4a4e](https://github.com/jacotay7/cheaphelp/commit/0ba4a4ecc83cf14da46048247880464c4262fc7d) by Jacob Taylor). Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
37
+ - Log each agent step as it starts; trim crash logs (#40) ([01efe1b](https://github.com/jacotay7/cheaphelp/commit/01efe1bb735bed7789245365522875dd7f6cbcd2) by Jacob Taylor). Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
38
+ - Cap worker tasks run per issue per tick (max_tasks_per_tick) (#39) ([5c7b138](https://github.com/jacotay7/cheaphelp/commit/5c7b138c75ee543690ce33d39671202639dad488) by Jacob Taylor). Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
39
+ - Cap issues processed per tick (--max-issues / max… (#38) ([a34dbfd](https://github.com/jacotay7/cheaphelp/commit/a34dbfd325067bb8ecbf20e72f9447cdfbd48251) by Jacob Taylor). Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
40
+ - Add cheaphelp status command (#27) ([96e0cb6](https://github.com/jacotay7/cheaphelp/commit/96e0cb645b172b79d090a0327d4e92d7e76ccecc) by Jacob Taylor). Co-authored-by: cheaphelp[bot] <cheaphelp@users.noreply.github.com>
41
+ - add workspace run-lock to serialise overlapping ticks (#25) ([bfc4778](https://github.com/jacotay7/cheaphelp/commit/bfc477837280eaa3aa82c923cc47dbfe6eff1fe2) by Jacob Taylor). Co-authored-by: cheaphelp[bot] <cheaphelp@users.noreply.github.com>, Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
42
+ - make opencode agent subprocess timeout configurable (#21) ([62a4e7a](https://github.com/jacotay7/cheaphelp/commit/62a4e7a81c2eb66c9bc2a7efd16bd6a50368b099) by Jacob Taylor). Co-authored-by: cheaphelp[bot] <cheaphelp@users.noreply.github.com>
43
+ - add `cheaphelp repo set` to update checks/autofix in place (#19) ([6f66999](https://github.com/jacotay7/cheaphelp/commit/6f669994b642016ebbed484ff37a2ea665a927f7) by Jacob Taylor). Co-authored-by: cheaphelp[bot] <cheaphelp@users.noreply.github.com>
44
+ - Prefix every GitHub message with a cheaphelp attribution header (#17) ([c001847](https://github.com/jacotay7/cheaphelp/commit/c0018477f42d4501ab3f230106da47de049e1671) by Jacob Taylor). Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
45
+ - Hand the exact quality-gate commands to the worker (#12) ([a5ddec5](https://github.com/jacotay7/cheaphelp/commit/a5ddec5d42f291d998912893a24d5fa915cff2db) by Jacob Taylor). Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
46
+
47
+ ### Bug Fixes
48
+
49
+ - stop finalize replies promising a 'spec below' (#99) ([942db6e](https://github.com/jacotay7/cheaphelp/commit/942db6e1b54a8fa416d98be6198c1e89f8034a08) by Jacob Taylor). Co-authored-by: cheaphelp[bot] <cheaphelp@users.noreply.github.com>
50
+ - balance-brace JSON extraction and retry unparseable clean exits (#98) ([1232a80](https://github.com/jacotay7/cheaphelp/commit/1232a805d58d6f22d254535f1cc0eca1572b541f) by Jacob Taylor). Co-authored-by: cheaphelp[bot] <cheaphelp@users.noreply.github.com>
51
+ - Drop stale bot_login args from responder test call sites (#69) ([e9be0c0](https://github.com/jacotay7/cheaphelp/commit/e9be0c0f76105340d90af285821b9b5432cee62c) by Jacob Taylor). Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
52
+ - Identify bot comments by marker only, not by author login (#67) ([e554d7b](https://github.com/jacotay7/cheaphelp/commit/e554d7bf5f43f0727ceb27fcd2705e43073534cc) by Jacob Taylor). Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
53
+ - Route push failures to needs-human; require workflow PAT scope (#65) ([587b8d5](https://github.com/jacotay7/cheaphelp/commit/587b8d598ae80aeb1dd1e2db3ac3241c727d2ee1) by Jacob Taylor). Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
54
+ - Re-validate issue state under its lock so overlapping ticks don't double-act (#58) ([24c279e](https://github.com/jacotay7/cheaphelp/commit/24c279e0ce4888f050b52a792ab34b17cd14aa1e) by Jacob Taylor). Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
55
+ - distinguish `repo set` no-op from real update (#34) ([264cd6c](https://github.com/jacotay7/cheaphelp/commit/264cd6c8243821527ad208a64bb0982b9157e5f7) by Jacob Taylor). Co-authored-by: cheaphelp[bot] <cheaphelp@users.noreply.github.com>
56
+ - Keep the spec at requirements altitude, ask only material questions (#14) ([04a9010](https://github.com/jacotay7/cheaphelp/commit/04a9010a347e90c536bf4b8670b73cd2dcc35de5) by Jacob Taylor). Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
57
+
58
+ ### Code Refactoring
59
+
60
+ - Don't run the full quality gate after every task (#29) ([cf0de8e](https://github.com/jacotay7/cheaphelp/commit/cf0de8e5a3c658ee9b9987ffb6c52217ce11b340) by Jacob Taylor). Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
@@ -0,0 +1,127 @@
1
+ # CLAUDE.md
2
+
3
+ Guidance for AI agents working in this repository.
4
+
5
+ ## What this is
6
+
7
+ `cheaphelp` is an AI software-engineer for GitHub repos. It installs as a
8
+ background service (systemd timer), watches registered repos, and runs a team of
9
+ narrow agents — via the **opencode** harness against cheap **OpenRouter** models
10
+ — to triage issues, plan, implement, and open PRs for human review.
11
+
12
+ The pipeline is a label-driven state machine. Each tick polls open issues and
13
+ dispatches by label:
14
+
15
+ ```
16
+ (no pipeline label) + human spoke last -> responder refine scope -> issues.md, label :ready
17
+ :ready / :needs-replan -> planner issues.md -> tasks, label :planned
18
+ :planned, tasks pending -> worker implement one task on the issue branch
19
+ :planned, all tasks done -> quality gate -> reviewer open PR (label :in-review) or replan
20
+ (gate fails -> fixer repairs + re-runs gate before replanning)
21
+ :in-review -> rework address new PR review feedback, or no-op
22
+ :needs-human, human replied -> responder re-engage a stuck issue
23
+ :needs-human, no new reply / :rejected -> (idle)
24
+ ```
25
+
26
+ A daily USD spend cap (`daily_budget_usd`, `spend.py`) can halt new agent turns
27
+ for the rest of the UTC day; see `orchestrator.tick` budget handling.
28
+
29
+ ## Workflow (IMPORTANT: branch protection)
30
+
31
+ `main` is protected. **Never commit or push to `main` directly.** All changes
32
+ land through a pull request:
33
+
34
+ 1. Branch off `main`: `git switch -c <type>-<short-name>` (e.g. `feat-json-output`).
35
+ 2. Make the change with tests.
36
+ 3. `make format && make check && make test` (all must pass).
37
+ 4. Commit (see convention below), push the branch, open a PR.
38
+
39
+ ## Dev commands
40
+
41
+ ```bash
42
+ make setup # install deps (uv sync)
43
+ make format # auto-format (ruff format + ruff --fix)
44
+ make check # lint + types + docs + api checks
45
+ make test # pytest
46
+ make run cheaphelp [ARGS...] # run the CLI
47
+ ```
48
+
49
+ Direct equivalents (no direnv):
50
+
51
+ ```bash
52
+ uv run ruff check src tests duties.py scripts --config config/ruff.toml
53
+ uv run ruff format src tests duties.py scripts --config config/ruff.toml
54
+ uv run python -m pytest -q
55
+ uv run cheaphelp <subcommand>
56
+ ```
57
+
58
+ Lint is `ruff` with `select = ["ALL"]` (config in `config/ruff.toml`); it is
59
+ strict (e.g. COM812 trailing commas, ANN annotations, D docstrings). Run
60
+ `make format` before `make check`. Python target is 3.10+.
61
+
62
+ ## Layout
63
+
64
+ All product code is under `src/cheaphelp/_internal/`:
65
+
66
+ | Module | Responsibility |
67
+ |--------|----------------|
68
+ | `config.py` | `Workspace` paths + `config.json` (`Config`) |
69
+ | `env.py` | `.env` secret parsing/writing (chmod 600) |
70
+ | `github.py` | minimal GitHub REST client (httpx) |
71
+ | `registry.py` | registered-repo store (`repos.json`) |
72
+ | `gitutil.py` | clones, commit, push, diff helpers |
73
+ | `lock.py` | per-repo file locks so concurrent ticks don't collide |
74
+ | `spend.py` | daily USD spend tracker for the budget guardrail |
75
+ | `conventions.py` | reads `CHEAPHELP.md`/`AGENTS.md`/`CONTRIBUTING.md` into agent context |
76
+ | `pr_state.py` | persists PR <-> issue link state for the rework stage |
77
+ | `opencode.py` | generate `opencode.json`, run agents headlessly, parse decisions |
78
+ | `templates/*.md` | bundled agent prompts (responder/planner/worker/reviewer/rework/fixer) |
79
+ | `tasks.py` | task manifest + per-issue task-state store |
80
+ | `responder.py` / `planner.py` / `worker.py` / `reviewer.py` / `rework.py` / `fixer.py` | per-role turn logic |
81
+ | `orchestrator.py` | one tick of the state machine (`tick()`, `classify()`, stage dispatch) |
82
+ | `cleanup.py` | prune build clones for closed issues / unregistered repos (keeps state) |
83
+ | `systemd.py` | user service + timer install (continuous-mode by default) |
84
+ | `commands.py` / `cli.py` | argparse CLI (`cmd_*` per subcommand) |
85
+
86
+ Tests live in `tests/`, one file per `src/cheaphelp/_internal/` module (plus
87
+ `test_cli_*.py` per CLI subcommand and `test_api.py`); shared fixtures in
88
+ `tests/conftest.py`.
89
+
90
+ ## Key conventions & invariants
91
+
92
+ - **Agents communicate via a single final ```json block.** Each role parses the
93
+ last fenced JSON block from agent output (`opencode.extract_decision`). If you
94
+ change a role's output contract, update both its prompt in `templates/<role>.md`
95
+ and the parser/`apply_*` logic in the matching module.
96
+ - **Workspace is the source of truth at runtime**, default `~/.cheaphelp`
97
+ (override `CHEAPHELP_HOME`): `config.json`, `.env`, `repos.json`, `agents/`
98
+ (editable prompt overrides), `opencode/opencode.json` (generated),
99
+ `state/<owner>__<repo>/issue-<n>/` (issues.md, plan.md, tasks.json, tasks/,
100
+ cost.json, pr_state.json), `state/daily_spend.json`, `clones/`, `logs/`.
101
+ After editing models/prompts/sandbox, regenerate with `cheaphelp agents sync`.
102
+ - **`tasks.json` is authoritative; the `.md` files are readable mirrors.** Use
103
+ `TaskStore` for all task state transitions.
104
+ - **cheaphelp owns git remotes**: workers/reviewer never push; the orchestrator
105
+ does (`gitutil.push_branch`). Agent bash is sandboxed (see `opencode.py`
106
+ `_READER_BASH` / `_WORKER_BASH`); only `worker` may edit files.
107
+ - **Defaults live in `config.py`** (`DEFAULT_MODELS`, `DEFAULT_LABELS`,
108
+ `DEFAULT_VARIANTS`, `DEFAULT_SANDBOX`). `Config.from_dict` merges over them, so
109
+ new keys must be added to the defaults *and* `from_dict`/`to_dict`.
110
+ - **Network isolation in tests**: never make real network/API calls; mock the
111
+ GitHub client and the agent layer. Set `CHEAPHELP_AGENT_MOCK=/path/to/decision.json`
112
+ to make `run_agent` return canned output instead of invoking opencode.
113
+ - **Fake GitHub clients**: use `tests.conftest.FakeGitHubClient` (a real
114
+ `GitHubClient` subclass) instead of writing a new ad-hoc duck-typed class —
115
+ ad-hoc fakes don't satisfy `ty`'s `GitHubClient` parameter types and need
116
+ `# ty: ignore[invalid-argument-type]` on every call. Seed `.issues`,
117
+ `.comments`, `.labels`, etc. and build payloads with `make_issue`/
118
+ `make_comment`/`make_pr_state`, also in `tests/conftest.py`.
119
+ - **Per-issue failures must not abort a tick** — `_process_repo` guards each
120
+ stage; preserve that resilience.
121
+
122
+ ## Commit messages
123
+
124
+ Angular/Karma convention: `<type>[(scope)]: Subject` (capitalized, no trailing
125
+ period). Types: `build`, `chore`, `ci`, `deps`, `docs`, `feat`, `fix`, `perf`,
126
+ `refactor`, `style`, `tests`. Don't update `CHANGELOG.md` (generated). Link the
127
+ related issue in the PR body (`Closes #<n>`).
@@ -0,0 +1,84 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation.
6
+
7
+ We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
8
+
9
+ ## Our Standards
10
+
11
+ Examples of behavior that contributes to a positive environment for our community include:
12
+
13
+ * Demonstrating empathy and kindness toward other people
14
+ * Being respectful of differing opinions, viewpoints, and experiences
15
+ * Giving and gracefully accepting constructive feedback
16
+ * Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
17
+ * Focusing on what is best not just for us as individuals, but for the overall community
18
+
19
+ Examples of unacceptable behavior include:
20
+
21
+ * The use of sexualized language or imagery, and sexual attention or advances of any kind
22
+ * Trolling, insulting or derogatory comments, and personal or political attacks
23
+ * Public or private harassment
24
+ * Publishing others' private information, such as a physical or email address, without their explicit permission
25
+ * Other conduct which could reasonably be considered inappropriate in a professional setting
26
+
27
+ ## Enforcement Responsibilities
28
+
29
+ Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
30
+
31
+ Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.
32
+
33
+ ## Scope
34
+
35
+ This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
36
+
37
+ ## Enforcement
38
+
39
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at jacobataylor7@gmail.com. All complaints will be reviewed and investigated promptly and fairly.
40
+
41
+ All community leaders are obligated to respect the privacy and security of the reporter of any incident.
42
+
43
+ ## Enforcement Guidelines
44
+
45
+ Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:
46
+
47
+ ### 1. Correction
48
+
49
+ **Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.
50
+
51
+ **Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.
52
+
53
+ ### 2. Warning
54
+
55
+ **Community Impact**: A violation through a single incident or series of actions.
56
+
57
+ **Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.
58
+
59
+ ### 3. Temporary Ban
60
+
61
+ **Community Impact**: A serious violation of community standards, including sustained inappropriate behavior.
62
+
63
+ **Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.
64
+
65
+ ### 4. Permanent Ban
66
+
67
+ **Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
68
+
69
+ **Consequence**: A permanent ban from any sort of public interaction within the community.
70
+
71
+ ## Attribution
72
+
73
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.1, available at [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
74
+
75
+ Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder][Mozilla CoC].
76
+
77
+ For answers to common questions about this code of conduct, see the FAQ at [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at [https://www.contributor-covenant.org/translations][translations].
78
+
79
+ [homepage]: https://www.contributor-covenant.org
80
+ [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
81
+ [Mozilla CoC]: https://github.com/mozilla/diversity
82
+ [FAQ]: https://www.contributor-covenant.org/faq
83
+ [translations]: https://www.contributor-covenant.org/translations
84
+
@@ -0,0 +1,112 @@
1
+ # Contributing
2
+
3
+ Contributions are welcome, and they are greatly appreciated. Every little bit helps, and credit will always be given.
4
+
5
+ **Please always create an issue before working on a new feature or a bug fix, so that we can discuss the implementation and make sure that your work will be merged.**
6
+
7
+ ## Environment setup
8
+
9
+ Install [uv](https://github.com/astral-sh/uv) and [direnv](https://direnv.net/), fork and clone the repository, then:
10
+
11
+ ```bash
12
+ cd cheaphelp
13
+ direnv allow
14
+ make setup
15
+ ```
16
+
17
+ You now have the dependencies installed.
18
+
19
+ You can run the application with `make run cheaphelp [ARGS...]`.
20
+
21
+ Run `make help` to see all the available actions!
22
+
23
+ ## Tasks
24
+
25
+ The entry-point to run commands and tasks is the `make` Python script, located in the `scripts` directory. Try running `make` to show the available commands and tasks. The *commands* do not need the Python dependencies to be installed, while the *tasks* do. The cross-platform tasks are written in Python, thanks to [duty](https://github.com/pawamoy/duty).
26
+
27
+ If you work in VSCode, we provide [an action to configure VSCode](https://pawamoy.github.io/copier-uv/work/#vscode-setup) for the project.
28
+
29
+ ## Development
30
+
31
+ As usual:
32
+
33
+ 1. create a new branch: `git switch -c feature-or-bugfix-name`
34
+ 1. edit the code and/or the documentation
35
+
36
+ **Before committing:**
37
+
38
+ 1. run `make format` to auto-format the code
39
+ 1. run `make check` to check everything (fix any warning)
40
+ 1. run `make test` to run the tests (fix any issue)
41
+ 1. if you updated the documentation or the project dependencies:
42
+ 1. run `make docs`
43
+ 1. go to http://localhost:8000 and check that everything looks good
44
+ 1. follow our [commit message convention](#commit-message-convention)
45
+
46
+ If you are unsure about how to fix or ignore a warning, just let the continuous integration fail, and we will help you during review.
47
+
48
+ Don't bother updating the changelog, we will take care of this.
49
+
50
+ ## Commit message convention
51
+
52
+ Commit messages must follow our convention based on the [Angular style](https://gist.github.com/stephenparish/9941e89d80e2bc58a153#format-of-the-commit-message) or the [Karma convention](https://karma-runner.github.io/4.0/dev/git-commit-msg.html):
53
+
54
+ ```
55
+ <type>[(scope)]: Subject
56
+
57
+ [Body]
58
+ ```
59
+
60
+ **Subject and body must be valid Markdown.** Subject must have proper casing (uppercase for first letter if it makes sense), but no dot at the end, and no punctuation in general.
61
+
62
+ Scope and body are optional. Type can be:
63
+
64
+ - `build`: About packaging, building wheels, etc.
65
+ - `chore`: About packaging or repo/files management.
66
+ - `ci`: About Continuous Integration.
67
+ - `deps`: Dependencies update.
68
+ - `docs`: About documentation.
69
+ - `feat`: New feature.
70
+ - `fix`: Bug fix.
71
+ - `perf`: About performance.
72
+ - `refactor`: Changes that are not features or bug fixes.
73
+ - `style`: A change in code style/format.
74
+ - `tests`: About tests.
75
+
76
+ If you write a body, please add trailers at the end (for example issues and PR references, or co-authors), without relying on GitHub's flavored Markdown:
77
+
78
+ ```
79
+ Body.
80
+
81
+ Issue #10: https://github.com/namespace/project/issues/10
82
+ Related to PR namespace/other-project#15: https://github.com/namespace/other-project/pull/15
83
+ ```
84
+
85
+ These "trailers" must appear at the end of the body, without any blank lines between them. The trailer title can contain any character except colons `:`. We expect a full URI for each trailer, not just GitHub autolinks (for example, full GitHub URLs for commits and issues, not the hash or the #issue-number).
86
+
87
+ We do not enforce a line length on commit messages summary and body, but please avoid very long summaries, and very long lines in the body, unless they are part of code blocks that must not be wrapped.
88
+
89
+ ## Pull requests guidelines
90
+
91
+ Link to any related issue in the Pull Request message.
92
+
93
+ During the review, we recommend using fixups:
94
+
95
+ ```bash
96
+ # SHA is the SHA of the commit you want to fix
97
+ git commit --fixup=SHA
98
+ ```
99
+
100
+ Once all the changes are approved, you can squash your commits:
101
+
102
+ ```bash
103
+ git rebase -i --autosquash main
104
+ ```
105
+
106
+ And force-push:
107
+
108
+ ```bash
109
+ git push -f
110
+ ```
111
+
112
+ If this seems all too complicated, you can push or force-push each new commit, and we will squash them ourselves if needed, before merging.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jacob Taylor
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,112 @@
1
+ Metadata-Version: 2.4
2
+ Name: cheaphelp
3
+ Version: 1.0.0
4
+ Summary: An AI software-engineer that triages GitHub issues, plans, implements, and reviews changes on your repos using cheap OpenRouter models via the opencode harness.
5
+ Author-Email: Jacob Taylor <jacobataylor7@gmail.com>
6
+ License-Expression: MIT
7
+ License-File: LICENSE
8
+ Classifier: Development Status :: 5 - Production/Stable
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Programming Language :: Python
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3 :: Only
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Programming Language :: Python :: 3.14
18
+ Classifier: Topic :: Documentation
19
+ Classifier: Topic :: Software Development
20
+ Classifier: Topic :: Utilities
21
+ Classifier: Typing :: Typed
22
+ Project-URL: Homepage, https://jacotay7.github.io/cheaphelp
23
+ Project-URL: Documentation, https://jacotay7.github.io/cheaphelp
24
+ Project-URL: Changelog, https://jacotay7.github.io/cheaphelp/changelog
25
+ Project-URL: Repository, https://github.com/jacotay7/cheaphelp
26
+ Project-URL: Issues, https://github.com/jacotay7/cheaphelp/issues
27
+ Requires-Python: >=3.10
28
+ Requires-Dist: httpx>=0.27
29
+ Description-Content-Type: text/markdown
30
+
31
+ # cheaphelp
32
+
33
+ [![ci](https://github.com/jacotay7/cheaphelp/actions/workflows/ci.yml/badge.svg)](https://github.com/jacotay7/cheaphelp/actions/workflows/ci.yml)
34
+ [![documentation](https://img.shields.io/badge/docs-zensical-FF9100.svg?style=flat)](https://jacotay7.github.io/cheaphelp/)
35
+
36
+ An AI software-engineer for your GitHub repositories. cheaphelp installs as a
37
+ background service on your machine, watches the repos you register, and runs a
38
+ team of narrow AI agents — powered by **cheap [OpenRouter](https://openrouter.ai)
39
+ models** through the **[opencode](https://opencode.ai)** terminal harness — to
40
+ triage issues, plan work, implement it, and open pull requests for human review.
41
+
42
+ > **Status: full pipeline wired and exercised live.** All roles run end-to-end
43
+ > against a real repository; expect to keep tuning prompts and hardening edge
44
+ > cases.
45
+
46
+ ## Install
47
+
48
+ The recommended way to install the `cheaphelp` CLI on your machine:
49
+
50
+ ```bash
51
+ pipx install cheaphelp
52
+ # or, if you don't use pipx:
53
+ pip install --user cheaphelp
54
+ ```
55
+
56
+ For development (running from a clone, contributing, or testing unreleased
57
+ changes), use `uv sync` inside the clone and invoke the CLI as
58
+ `uv run cheaphelp …` — see [Quick start](#quick-start) step 1.
59
+
60
+ ## Quick start
61
+
62
+ ```bash
63
+ # 1. (Development install — end users should `pipx install cheaphelp`, see
64
+ # the Install section above.) Clone, sync deps, and install the
65
+ # `cheaphelp` command globally.
66
+ git clone https://github.com/jacotay7/cheaphelp.git
67
+ cd cheaphelp
68
+ uv sync # install deps (needed before tool install)
69
+ uv tool install --from . cheaphelp # puts `cheaphelp` on $PATH
70
+
71
+ # 2. Create your machine-local workspace (~/.cheaphelp) and store secrets.
72
+ # Prompts for your tokens, or pass them as flags / set them later.
73
+ cheaphelp init
74
+
75
+ # 3. Check everything is wired up.
76
+ cheaphelp doctor
77
+
78
+ # 4. Register a repo to work on.
79
+ cheaphelp repo add owner/name
80
+ cheaphelp repo list
81
+
82
+ # 5. Dry-run one tick (shows what it *would* do, no changes).
83
+ cheaphelp run --dry-run
84
+
85
+ # 6. Run it for real (responder engages open issues).
86
+ cheaphelp run
87
+
88
+ # 7. Or drain the whole backlog now: repeat ticks until one is idle.
89
+ cheaphelp run --continuous
90
+
91
+ # 8. Install the background timer (default every 10 minutes; each firing
92
+ # runs `cheaphelp run --continuous` by default, see the docs).
93
+ cheaphelp systemd install --interval 10m
94
+ cheaphelp systemd status
95
+ ```
96
+
97
+ > **Upgrading.** After pulling new code, re-run `uv tool install --from . --reinstall cheaphelp` to refresh the global command. A plain `git pull` updates the source tree but does NOT refresh the installed binary, and `uv run cheaphelp` would then diverge from your checkout.
98
+
99
+ ## Documentation
100
+
101
+ - [Getting started](docs/getting-started.md) — install, requirements, running modes
102
+ - [Pipeline](docs/pipeline.md) — how the agents collaborate and the quality gate
103
+ - [Configuration](docs/configuration.md) — `config.json` fields, models, budget knobs
104
+ - [Workspace](docs/workspace.md) — files cheaphelp writes to disk
105
+ - [Sandboxing](docs/sandboxing.md) — how agents are isolated and its limits
106
+ - [Cost tracking](docs/cost-tracking.md) — daily budget and per-issue cost reporting
107
+ - [Background service](docs/background-service.md) — running under the systemd timer
108
+ - [Dev guide](docs/dev-guide.md) — for contributors (testing, source layout, mocking opencode)
109
+
110
+ ## For contributors
111
+
112
+ See [CONTRIBUTING.md](CONTRIBUTING.md) and the [Dev guide](docs/dev-guide.md).
@@ -0,0 +1,82 @@
1
+ # cheaphelp
2
+
3
+ [![ci](https://github.com/jacotay7/cheaphelp/actions/workflows/ci.yml/badge.svg)](https://github.com/jacotay7/cheaphelp/actions/workflows/ci.yml)
4
+ [![documentation](https://img.shields.io/badge/docs-zensical-FF9100.svg?style=flat)](https://jacotay7.github.io/cheaphelp/)
5
+
6
+ An AI software-engineer for your GitHub repositories. cheaphelp installs as a
7
+ background service on your machine, watches the repos you register, and runs a
8
+ team of narrow AI agents — powered by **cheap [OpenRouter](https://openrouter.ai)
9
+ models** through the **[opencode](https://opencode.ai)** terminal harness — to
10
+ triage issues, plan work, implement it, and open pull requests for human review.
11
+
12
+ > **Status: full pipeline wired and exercised live.** All roles run end-to-end
13
+ > against a real repository; expect to keep tuning prompts and hardening edge
14
+ > cases.
15
+
16
+ ## Install
17
+
18
+ The recommended way to install the `cheaphelp` CLI on your machine:
19
+
20
+ ```bash
21
+ pipx install cheaphelp
22
+ # or, if you don't use pipx:
23
+ pip install --user cheaphelp
24
+ ```
25
+
26
+ For development (running from a clone, contributing, or testing unreleased
27
+ changes), use `uv sync` inside the clone and invoke the CLI as
28
+ `uv run cheaphelp …` — see [Quick start](#quick-start) step 1.
29
+
30
+ ## Quick start
31
+
32
+ ```bash
33
+ # 1. (Development install — end users should `pipx install cheaphelp`, see
34
+ # the Install section above.) Clone, sync deps, and install the
35
+ # `cheaphelp` command globally.
36
+ git clone https://github.com/jacotay7/cheaphelp.git
37
+ cd cheaphelp
38
+ uv sync # install deps (needed before tool install)
39
+ uv tool install --from . cheaphelp # puts `cheaphelp` on $PATH
40
+
41
+ # 2. Create your machine-local workspace (~/.cheaphelp) and store secrets.
42
+ # Prompts for your tokens, or pass them as flags / set them later.
43
+ cheaphelp init
44
+
45
+ # 3. Check everything is wired up.
46
+ cheaphelp doctor
47
+
48
+ # 4. Register a repo to work on.
49
+ cheaphelp repo add owner/name
50
+ cheaphelp repo list
51
+
52
+ # 5. Dry-run one tick (shows what it *would* do, no changes).
53
+ cheaphelp run --dry-run
54
+
55
+ # 6. Run it for real (responder engages open issues).
56
+ cheaphelp run
57
+
58
+ # 7. Or drain the whole backlog now: repeat ticks until one is idle.
59
+ cheaphelp run --continuous
60
+
61
+ # 8. Install the background timer (default every 10 minutes; each firing
62
+ # runs `cheaphelp run --continuous` by default, see the docs).
63
+ cheaphelp systemd install --interval 10m
64
+ cheaphelp systemd status
65
+ ```
66
+
67
+ > **Upgrading.** After pulling new code, re-run `uv tool install --from . --reinstall cheaphelp` to refresh the global command. A plain `git pull` updates the source tree but does NOT refresh the installed binary, and `uv run cheaphelp` would then diverge from your checkout.
68
+
69
+ ## Documentation
70
+
71
+ - [Getting started](docs/getting-started.md) — install, requirements, running modes
72
+ - [Pipeline](docs/pipeline.md) — how the agents collaborate and the quality gate
73
+ - [Configuration](docs/configuration.md) — `config.json` fields, models, budget knobs
74
+ - [Workspace](docs/workspace.md) — files cheaphelp writes to disk
75
+ - [Sandboxing](docs/sandboxing.md) — how agents are isolated and its limits
76
+ - [Cost tracking](docs/cost-tracking.md) — daily budget and per-issue cost reporting
77
+ - [Background service](docs/background-service.md) — running under the systemd timer
78
+ - [Dev guide](docs/dev-guide.md) — for contributors (testing, source layout, mocking opencode)
79
+
80
+ ## For contributors
81
+
82
+ See [CONTRIBUTING.md](CONTRIBUTING.md) and the [Dev guide](docs/dev-guide.md).
@@ -0,0 +1,25 @@
1
+ [coverage:run]
2
+ branch = true
3
+ parallel = true
4
+ source =
5
+ src/
6
+ tests/
7
+
8
+ [coverage:paths]
9
+ equivalent =
10
+ src/
11
+ .venv/lib/*/site-packages/
12
+ .venvs/*/lib/*/site-packages/
13
+
14
+ [coverage:report]
15
+ precision = 2
16
+ omit =
17
+ src/*/__init__.py
18
+ src/*/__main__.py
19
+ tests/__init__.py
20
+ exclude_lines =
21
+ pragma: no cover
22
+ if TYPE_CHECKING
23
+
24
+ [coverage:json]
25
+ output = htmlcov/coverage.json
@@ -0,0 +1,9 @@
1
+ bump = "auto"
2
+ convention = "angular"
3
+ in-place = true
4
+ output = "CHANGELOG.md"
5
+ parse-refs = false
6
+ parse-trailers = true
7
+ sections = ["build", "deps", "feat", "fix", "refactor"]
8
+ template = "keepachangelog"
9
+ versioning = "pep440"