cadence-runner 0.19.2__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 (56) hide show
  1. cadence_runner-0.19.2/LICENSE +21 -0
  2. cadence_runner-0.19.2/PKG-INFO +289 -0
  3. cadence_runner-0.19.2/README.md +263 -0
  4. cadence_runner-0.19.2/pyproject.toml +94 -0
  5. cadence_runner-0.19.2/src/cadence/__init__.py +1 -0
  6. cadence_runner-0.19.2/src/cadence/cli.py +627 -0
  7. cadence_runner-0.19.2/src/cadence/config.py +227 -0
  8. cadence_runner-0.19.2/src/cadence/defaults/__init__.py +0 -0
  9. cadence_runner-0.19.2/src/cadence/defaults/agents/__init__.py +0 -0
  10. cadence_runner-0.19.2/src/cadence/defaults/agents/implementation.txt +26 -0
  11. cadence_runner-0.19.2/src/cadence/defaults/agents/quality.txt +37 -0
  12. cadence_runner-0.19.2/src/cadence/defaults/agents/simplification.txt +50 -0
  13. cadence_runner-0.19.2/src/cadence/defaults/agents/testing.txt +51 -0
  14. cadence_runner-0.19.2/src/cadence/defaults/prompts/__init__.py +0 -0
  15. cadence_runner-0.19.2/src/cadence/defaults/prompts/make_plan.txt +137 -0
  16. cadence_runner-0.19.2/src/cadence/defaults/prompts/review_first.txt +78 -0
  17. cadence_runner-0.19.2/src/cadence/defaults/prompts/review_second.txt +63 -0
  18. cadence_runner-0.19.2/src/cadence/defaults/prompts/task.txt +41 -0
  19. cadence_runner-0.19.2/src/cadence/executor/__init__.py +0 -0
  20. cadence_runner-0.19.2/src/cadence/executor/claude_executor.py +368 -0
  21. cadence_runner-0.19.2/src/cadence/executor/events.py +125 -0
  22. cadence_runner-0.19.2/src/cadence/executor/process_group.py +38 -0
  23. cadence_runner-0.19.2/src/cadence/git/__init__.py +10 -0
  24. cadence_runner-0.19.2/src/cadence/git/backend.py +260 -0
  25. cadence_runner-0.19.2/src/cadence/git/service.py +142 -0
  26. cadence_runner-0.19.2/src/cadence/input.py +69 -0
  27. cadence_runner-0.19.2/src/cadence/plan/__init__.py +27 -0
  28. cadence_runner-0.19.2/src/cadence/plan/parse.py +141 -0
  29. cadence_runner-0.19.2/src/cadence/plan/plan.py +15 -0
  30. cadence_runner-0.19.2/src/cadence/processor/__init__.py +0 -0
  31. cadence_runner-0.19.2/src/cadence/processor/agents.py +110 -0
  32. cadence_runner-0.19.2/src/cadence/processor/prompts.py +279 -0
  33. cadence_runner-0.19.2/src/cadence/processor/runner.py +524 -0
  34. cadence_runner-0.19.2/src/cadence/processor/signals.py +83 -0
  35. cadence_runner-0.19.2/src/cadence/progress/__init__.py +1 -0
  36. cadence_runner-0.19.2/src/cadence/progress/colors.py +40 -0
  37. cadence_runner-0.19.2/src/cadence/progress/flock.py +26 -0
  38. cadence_runner-0.19.2/src/cadence/progress/logger.py +254 -0
  39. cadence_runner-0.19.2/src/cadence/status.py +65 -0
  40. cadence_runner-0.19.2/tests/__init__.py +0 -0
  41. cadence_runner-0.19.2/tests/test_agents.py +203 -0
  42. cadence_runner-0.19.2/tests/test_cli.py +2209 -0
  43. cadence_runner-0.19.2/tests/test_config.py +359 -0
  44. cadence_runner-0.19.2/tests/test_events.py +196 -0
  45. cadence_runner-0.19.2/tests/test_executor.py +881 -0
  46. cadence_runner-0.19.2/tests/test_git.py +122 -0
  47. cadence_runner-0.19.2/tests/test_git_service.py +557 -0
  48. cadence_runner-0.19.2/tests/test_input.py +100 -0
  49. cadence_runner-0.19.2/tests/test_partial_line.py +45 -0
  50. cadence_runner-0.19.2/tests/test_plan.py +213 -0
  51. cadence_runner-0.19.2/tests/test_processor.py +1021 -0
  52. cadence_runner-0.19.2/tests/test_progress.py +512 -0
  53. cadence_runner-0.19.2/tests/test_prompts.py +510 -0
  54. cadence_runner-0.19.2/tests/test_signals.py +159 -0
  55. cadence_runner-0.19.2/tests/test_status.py +125 -0
  56. cadence_runner-0.19.2/tests/test_watchdog.py +58 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Drozdetskiy
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,289 @@
1
+ Metadata-Version: 2.1
2
+ Name: cadence-runner
3
+ Version: 0.19.2
4
+ Summary: CLI tool for autonomous task execution via Claude Code
5
+ Keywords: claude,claude-code,cli,automation,agent
6
+ Author-Email: Mikhail Drozdetskiy <m.drozdetskiy@gmail.com>
7
+ License: MIT
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: Environment :: Console
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Operating System :: MacOS
13
+ Classifier: Operating System :: POSIX :: Linux
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.14
16
+ Classifier: Topic :: Software Development
17
+ Classifier: Topic :: Utilities
18
+ Project-URL: Homepage, https://github.com/Drozdetskiy/cadence
19
+ Project-URL: Repository, https://github.com/Drozdetskiy/cadence
20
+ Project-URL: Issues, https://github.com/Drozdetskiy/cadence/issues
21
+ Requires-Python: >=3.14
22
+ Requires-Dist: typer>=0.9
23
+ Requires-Dist: rich>=13.0
24
+ Requires-Dist: PyYAML>=6.0
25
+ Description-Content-Type: text/markdown
26
+
27
+ # cadence
28
+
29
+ Autonomous task-execution pipeline on top of [Claude Code](https://docs.anthropic.com/en/docs/claude-code).
30
+
31
+ `cadence` drives Claude through a structured loop: plan → branch → iterative implementation → multi-agent code review → review-loop until clean. It is a thin orchestrator — Claude does the work, `cadence` keeps it on rails (signals, retries, idle/session timeouts, break/resume, per-phase models, git integration).
32
+
33
+ ## What it does
34
+
35
+ | Stage | Trigger | What happens |
36
+ |---|---|---|
37
+ | **plan** | `cadence --plan <file>` | Interactive Q&A with Claude, draft review (accept / revise / reject), final plan written to `<file>-plan.md` |
38
+ | **task** | `cadence --task <plan>` | Branch created from plan filename, one `### Task N:` section per iteration, each completed and committed |
39
+ | **review** | implicit after `--task`, or `cadence --review` | First pass launches 4 parallel agents (quality, implementation, testing, simplification); subsequent passes loop on critical/major findings until no commits are produced |
40
+
41
+ Phases communicate with the runner via signal markers (e.g. `<<<CADENCE:PLAN_READY>>>`, `<<<CADENCE:ALL_TASKS_DONE>>>`, `<<<CADENCE:REVIEW_DONE>>>`, `<<<CADENCE:QUESTION>>>`, `<<<CADENCE:TASK_FAILED>>>`).
42
+
43
+ ## Installation
44
+
45
+ ```bash
46
+ # from source, editable
47
+ pip install -e .
48
+
49
+ # or with pdm
50
+ pdm install
51
+ ```
52
+
53
+ Requires:
54
+ - Python **3.14+**
55
+ - [Claude Code](https://docs.anthropic.com/en/docs/claude-code) on `PATH`
56
+ - a git repository (the `--task` and `--review` modes operate on the working tree)
57
+
58
+ ## Usage
59
+
60
+ Tasks live in their own subdirectory under `cdc-tasks/<NNNN-slug>/` (configurable via `tasks_root`). The free-form description goes into a file named `preprompt`; the generated plan is written next to it as `plan` (the `preprompt` → `plan` mapping is built into `--plan`). A per-task `config.yaml` next to the prompt is auto-discovered.
61
+
62
+ ```
63
+ cdc-tasks/
64
+ 0001-my-feature/
65
+ preprompt # free-form task description (input)
66
+ plan # generated by --plan, consumed by --task
67
+ config.yaml # optional per-task overrides (auto-discovered)
68
+ ```
69
+
70
+ ```bash
71
+ # 1. Create a plan from a free-form task description
72
+ cadence --plan cdc-tasks/0001-my-feature/preprompt
73
+ # → writes cdc-tasks/0001-my-feature/plan
74
+
75
+ # 2. Create a plan and chain straight into implementation
76
+ cadence --plan cdc-tasks/0001-my-feature/preprompt --impl
77
+
78
+ # 3. Execute an existing plan: branch + tasks + review
79
+ cadence --task cdc-tasks/0001-my-feature/plan
80
+
81
+ # 4. Review the current branch only (no plan, no branch creation)
82
+ cadence --review
83
+ cadence --review --base develop # override base branch
84
+ cadence --review --config cdc-tasks/0001-my-feature/config.yaml # per-run overrides
85
+
86
+ # Misc
87
+ cadence --version
88
+ ```
89
+
90
+ Flag rules:
91
+ - `--plan`, `--task`, `--review` are mutually exclusive.
92
+ - `--impl` requires `--plan` (and is incompatible with `--review`).
93
+ - `--base` is only valid with `--review`. Resolution priority: `--base` > `default_branch` in config (defaults to `main`).
94
+
95
+ ### Plan file format
96
+
97
+ Plans are markdown with a strict structure the runner parses on every iteration:
98
+
99
+ ```markdown
100
+ # Title
101
+
102
+ ## Overview
103
+
104
+
105
+ ## Context
106
+ - Files involved: …
107
+
108
+ ### Task 1: Setup
109
+ - [ ] step one
110
+ - [ ] step two
111
+ - [ ] write tests
112
+ - [ ] run test suite
113
+
114
+ ### Task 2: …
115
+ - [ ] …
116
+ ```
117
+
118
+ - `### Task N:` or `### Iteration N:` headers delimit work units.
119
+ - `- [ ]` / `- [x]` checkboxes inside Task sections drive progress.
120
+ - Checkboxes outside Task sections (Overview, Context, Success criteria) do not block completion.
121
+ - After a successful `--task` run the file is renamed in place to `<stem>-completed<ext>` (no commit — plan files are typically gitignored).
122
+
123
+ ## Configuration
124
+
125
+ ### Local config: `.cadence/config.yaml`
126
+
127
+ Project-scoped, no global config. Loaded from cwd (or `CADENCE_CONFIG_DIR`). All keys are optional — missing keys fall back to defaults.
128
+
129
+ ```yaml
130
+ # Claude executor
131
+ claude_command: claude
132
+ claude_args: "--dangerously-skip-permissions --verbose"
133
+ plan_model: claude-opus-4-7
134
+ task_model: claude-opus-4-7
135
+ review_model: claude-opus-4-7
136
+
137
+ # Iteration / timing
138
+ iteration_delay_ms: 2000
139
+ task_retry_count: 1
140
+ max_iterations: 50
141
+ session_timeout: "0" # "30m", "1h30m", … 0 = disabled
142
+ idle_timeout: "0"
143
+ wait_on_limit: "0" # >0 → retry on rate-limit instead of failing
144
+
145
+ # VCS / paths
146
+ tasks_root: cdc-tasks # root for per-task subdirectories (preprompt/plan/config.yaml)
147
+ default_branch: main # override per-project in local config
148
+ commit_trailer: "" # appended to all cadence-made commits
149
+ commit_format: | # appended to task/review prompts (default shown below)
150
+ Format: <branch-name>. Added: <what>. Changed: <what>. Deleted: <what>. ...
151
+
152
+ # Output
153
+ colors:
154
+ task: "#2e8b57"
155
+ review: "#1a9e9e"
156
+ warn: "#d4930d"
157
+ error: "#cc0000"
158
+ ```
159
+
160
+ See [`docs/config.md`](docs/config.md) for the full key reference (timeouts, error patterns, color palette).
161
+
162
+ ### Per-run overrides: `--config`
163
+
164
+ `--config <path>` loads a YAML file that overrides per-phase models and/or `default_branch`. Each key is optional:
165
+
166
+ ```yaml
167
+ plan:
168
+ model: claude-opus-4-7
169
+ task:
170
+ model: claude-opus-4-7
171
+ review:
172
+ model: claude-opus-4-7
173
+ default_branch: develop
174
+ ```
175
+
176
+ If `--config` is omitted, cadence auto-discovers `config.yaml` next to the plan/task file — typically `cdc-tasks/<NNNN-slug>/config.yaml` (no parent walk). For `--review` (no plan/task file) auto-discovery is skipped — only an explicit `--config` is honored. An explicit path that does not exist is a hard error; an auto-discovered missing file is silently ignored. YAML parse errors are always fatal.
177
+
178
+ ### Commit message format
179
+
180
+ `commit_format` is appended verbatim to every task and review prompt, telling Claude how to write the commit subject. Plan creation does not commit, so the format is not added there.
181
+
182
+ The built-in default produces messages like:
183
+
184
+ ```
185
+ 0014-no-plan-commit-on-start. Changed: cadence no longer auto-commits the plan file when starting a task. Deleted: now-unused commit_plan_file / file_has_changes helpers.
186
+ ```
187
+
188
+ Pattern: `<branch-name>. Added: <what>. Changed: <what>. Deleted: <what>.` — sections are included only when they apply, one short clause each, English, single line.
189
+
190
+ Override from `.cadence/config.yaml` with any free-form text. Example of a tighter restatement (the shipped default also includes Good/Bad examples and guidance about implementation details belonging in the diff — see `Config.commit_format` in `src/cadence/config.py` for the verbatim text):
191
+
192
+ ```yaml
193
+ commit_format: |
194
+ Format: <branch-name>. Added: <what>. Changed: <what>. Deleted: <what>.
195
+ Include only the sections that apply. English, single line.
196
+ Each section is one short clause describing the user-visible outcome.
197
+ Author as the user — no Co-Authored-By trailer (unless `commit_trailer` is configured).
198
+ ```
199
+
200
+ Switch to Conventional Commits:
201
+
202
+ ```yaml
203
+ commit_format: |
204
+ Use Conventional Commits: <type>(<scope>): <subject>
205
+ Types: feat, fix, refactor, docs, test, chore.
206
+ Subject is imperative, lowercase, no trailing period, ≤72 chars.
207
+ Example: feat(executor): add idle-timeout retry
208
+ ```
209
+
210
+ If you need finer control than a free-form block (e.g. different wording per phase), drop a custom `task.txt` / `review_first.txt` / `review_second.txt` under `.cadence/prompts/` — the format block is appended to whatever prompt body you supply.
211
+
212
+ ### Customizing prompts and agents
213
+
214
+ `cadence` ships with embedded defaults under `src/cadence/defaults/`. To customize, drop replacements into the project:
215
+
216
+ ```
217
+ .cadence/
218
+ config.yaml
219
+ prompts/
220
+ make_plan.txt # overrides plan-creation prompt
221
+ task.txt # overrides task-iteration prompt
222
+ review_first.txt # overrides initial review prompt
223
+ review_second.txt # overrides review-loop prompt
224
+ agents/
225
+ quality.txt # custom review agents (referenced as {{agent:quality}})
226
+ implementation.txt
227
+ testing.txt
228
+ simplification.txt
229
+ my-extra-agent.txt # add new agents — auto-discovered
230
+ ```
231
+
232
+ Per-file fallback: if a local file is empty or contains only `# comments`, the embedded default is used. Agents support optional YAML frontmatter:
233
+
234
+ ```
235
+ ---
236
+ model: sonnet # haiku | sonnet | opus (or full IDs, normalized)
237
+ agent: code-reviewer # subagent type for the Task tool
238
+ ---
239
+ Agent prompt body…
240
+ ```
241
+
242
+ Prompts can reference agents inline with `{{agent:name}}`; the runner expands these into full Task tool invocations, with base variables (`{{PLAN_FILE}}`, `{{DEFAULT_BRANCH}}`, etc.) substituted into the agent body.
243
+
244
+ ## Runtime controls
245
+
246
+ - **Ctrl+C** — graceful shutdown (twice within 5s force-exits).
247
+ - **Ctrl+\\** (`SIGQUIT`, Unix) — break the current task; the runner kills the active Claude session and prompts to resume or abort. Resume restarts the same task with a fresh session and re-reads the plan file.
248
+ - **Rate limits** — if `wait_on_limit > 0` and Claude output matches `claude_limit_patterns`, cadence sleeps and retries indefinitely until cancellation.
249
+ - **Session / idle timeouts** — kill stuck sessions; review-loop iterations skip the no-commit detection if the previous session timed out.
250
+
251
+ ## Project layout
252
+
253
+ ```
254
+ src/cadence/
255
+ cli.py Typer entrypoint, mode dispatch, signal handling
256
+ config.py Config dataclass, YAML loading, --config overrides
257
+ status.py Phase / Mode / Signal constants
258
+ input.py Interactive Q&A collector
259
+ executor/ Claude subprocess + JSON-stream parsing
260
+ git/ Service layer over `git` CLI
261
+ plan/ Markdown plan parser, branch-name extraction
262
+ processor/ Runner — orchestrates plan/task/review phases
263
+ progress/ File+stdout logger with colors and flock
264
+ defaults/
265
+ prompts/ Embedded prompt templates
266
+ agents/ Embedded review agents
267
+ ```
268
+
269
+ Deeper module references live in [`docs/`](docs/): `config.md`, `processor.md`, `executor.md`, `git-and-plans.md`, `progress-and-input.md`.
270
+
271
+ ## Development
272
+
273
+ ```bash
274
+ make install # pdm install --dev
275
+ make test # pytest tests/ -v
276
+ make test-cov # with coverage
277
+ make lint # ruff check
278
+ make typecheck # mypy --strict
279
+ make check # lint + typecheck + test
280
+ ```
281
+
282
+ Conventions:
283
+ - Python 3.14+, `mypy --strict`.
284
+ - `Protocol`-based interfaces for all `Runner` dependencies (Executor, Logger, InputCollector, GitChecker) — tests mock these directly, never the real Claude CLI or a real git repo.
285
+ - Signals are literal strings of the form `<<<CADENCE:NAME>>>` and matched against raw non-JSON CLI output only (so the same literal inside stream-json events does not trigger false positives).
286
+
287
+ ## License
288
+
289
+ MIT. See [`LICENSE`](LICENSE).
@@ -0,0 +1,263 @@
1
+ # cadence
2
+
3
+ Autonomous task-execution pipeline on top of [Claude Code](https://docs.anthropic.com/en/docs/claude-code).
4
+
5
+ `cadence` drives Claude through a structured loop: plan → branch → iterative implementation → multi-agent code review → review-loop until clean. It is a thin orchestrator — Claude does the work, `cadence` keeps it on rails (signals, retries, idle/session timeouts, break/resume, per-phase models, git integration).
6
+
7
+ ## What it does
8
+
9
+ | Stage | Trigger | What happens |
10
+ |---|---|---|
11
+ | **plan** | `cadence --plan <file>` | Interactive Q&A with Claude, draft review (accept / revise / reject), final plan written to `<file>-plan.md` |
12
+ | **task** | `cadence --task <plan>` | Branch created from plan filename, one `### Task N:` section per iteration, each completed and committed |
13
+ | **review** | implicit after `--task`, or `cadence --review` | First pass launches 4 parallel agents (quality, implementation, testing, simplification); subsequent passes loop on critical/major findings until no commits are produced |
14
+
15
+ Phases communicate with the runner via signal markers (e.g. `<<<CADENCE:PLAN_READY>>>`, `<<<CADENCE:ALL_TASKS_DONE>>>`, `<<<CADENCE:REVIEW_DONE>>>`, `<<<CADENCE:QUESTION>>>`, `<<<CADENCE:TASK_FAILED>>>`).
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ # from source, editable
21
+ pip install -e .
22
+
23
+ # or with pdm
24
+ pdm install
25
+ ```
26
+
27
+ Requires:
28
+ - Python **3.14+**
29
+ - [Claude Code](https://docs.anthropic.com/en/docs/claude-code) on `PATH`
30
+ - a git repository (the `--task` and `--review` modes operate on the working tree)
31
+
32
+ ## Usage
33
+
34
+ Tasks live in their own subdirectory under `cdc-tasks/<NNNN-slug>/` (configurable via `tasks_root`). The free-form description goes into a file named `preprompt`; the generated plan is written next to it as `plan` (the `preprompt` → `plan` mapping is built into `--plan`). A per-task `config.yaml` next to the prompt is auto-discovered.
35
+
36
+ ```
37
+ cdc-tasks/
38
+ 0001-my-feature/
39
+ preprompt # free-form task description (input)
40
+ plan # generated by --plan, consumed by --task
41
+ config.yaml # optional per-task overrides (auto-discovered)
42
+ ```
43
+
44
+ ```bash
45
+ # 1. Create a plan from a free-form task description
46
+ cadence --plan cdc-tasks/0001-my-feature/preprompt
47
+ # → writes cdc-tasks/0001-my-feature/plan
48
+
49
+ # 2. Create a plan and chain straight into implementation
50
+ cadence --plan cdc-tasks/0001-my-feature/preprompt --impl
51
+
52
+ # 3. Execute an existing plan: branch + tasks + review
53
+ cadence --task cdc-tasks/0001-my-feature/plan
54
+
55
+ # 4. Review the current branch only (no plan, no branch creation)
56
+ cadence --review
57
+ cadence --review --base develop # override base branch
58
+ cadence --review --config cdc-tasks/0001-my-feature/config.yaml # per-run overrides
59
+
60
+ # Misc
61
+ cadence --version
62
+ ```
63
+
64
+ Flag rules:
65
+ - `--plan`, `--task`, `--review` are mutually exclusive.
66
+ - `--impl` requires `--plan` (and is incompatible with `--review`).
67
+ - `--base` is only valid with `--review`. Resolution priority: `--base` > `default_branch` in config (defaults to `main`).
68
+
69
+ ### Plan file format
70
+
71
+ Plans are markdown with a strict structure the runner parses on every iteration:
72
+
73
+ ```markdown
74
+ # Title
75
+
76
+ ## Overview
77
+
78
+
79
+ ## Context
80
+ - Files involved: …
81
+
82
+ ### Task 1: Setup
83
+ - [ ] step one
84
+ - [ ] step two
85
+ - [ ] write tests
86
+ - [ ] run test suite
87
+
88
+ ### Task 2: …
89
+ - [ ] …
90
+ ```
91
+
92
+ - `### Task N:` or `### Iteration N:` headers delimit work units.
93
+ - `- [ ]` / `- [x]` checkboxes inside Task sections drive progress.
94
+ - Checkboxes outside Task sections (Overview, Context, Success criteria) do not block completion.
95
+ - After a successful `--task` run the file is renamed in place to `<stem>-completed<ext>` (no commit — plan files are typically gitignored).
96
+
97
+ ## Configuration
98
+
99
+ ### Local config: `.cadence/config.yaml`
100
+
101
+ Project-scoped, no global config. Loaded from cwd (or `CADENCE_CONFIG_DIR`). All keys are optional — missing keys fall back to defaults.
102
+
103
+ ```yaml
104
+ # Claude executor
105
+ claude_command: claude
106
+ claude_args: "--dangerously-skip-permissions --verbose"
107
+ plan_model: claude-opus-4-7
108
+ task_model: claude-opus-4-7
109
+ review_model: claude-opus-4-7
110
+
111
+ # Iteration / timing
112
+ iteration_delay_ms: 2000
113
+ task_retry_count: 1
114
+ max_iterations: 50
115
+ session_timeout: "0" # "30m", "1h30m", … 0 = disabled
116
+ idle_timeout: "0"
117
+ wait_on_limit: "0" # >0 → retry on rate-limit instead of failing
118
+
119
+ # VCS / paths
120
+ tasks_root: cdc-tasks # root for per-task subdirectories (preprompt/plan/config.yaml)
121
+ default_branch: main # override per-project in local config
122
+ commit_trailer: "" # appended to all cadence-made commits
123
+ commit_format: | # appended to task/review prompts (default shown below)
124
+ Format: <branch-name>. Added: <what>. Changed: <what>. Deleted: <what>. ...
125
+
126
+ # Output
127
+ colors:
128
+ task: "#2e8b57"
129
+ review: "#1a9e9e"
130
+ warn: "#d4930d"
131
+ error: "#cc0000"
132
+ ```
133
+
134
+ See [`docs/config.md`](docs/config.md) for the full key reference (timeouts, error patterns, color palette).
135
+
136
+ ### Per-run overrides: `--config`
137
+
138
+ `--config <path>` loads a YAML file that overrides per-phase models and/or `default_branch`. Each key is optional:
139
+
140
+ ```yaml
141
+ plan:
142
+ model: claude-opus-4-7
143
+ task:
144
+ model: claude-opus-4-7
145
+ review:
146
+ model: claude-opus-4-7
147
+ default_branch: develop
148
+ ```
149
+
150
+ If `--config` is omitted, cadence auto-discovers `config.yaml` next to the plan/task file — typically `cdc-tasks/<NNNN-slug>/config.yaml` (no parent walk). For `--review` (no plan/task file) auto-discovery is skipped — only an explicit `--config` is honored. An explicit path that does not exist is a hard error; an auto-discovered missing file is silently ignored. YAML parse errors are always fatal.
151
+
152
+ ### Commit message format
153
+
154
+ `commit_format` is appended verbatim to every task and review prompt, telling Claude how to write the commit subject. Plan creation does not commit, so the format is not added there.
155
+
156
+ The built-in default produces messages like:
157
+
158
+ ```
159
+ 0014-no-plan-commit-on-start. Changed: cadence no longer auto-commits the plan file when starting a task. Deleted: now-unused commit_plan_file / file_has_changes helpers.
160
+ ```
161
+
162
+ Pattern: `<branch-name>. Added: <what>. Changed: <what>. Deleted: <what>.` — sections are included only when they apply, one short clause each, English, single line.
163
+
164
+ Override from `.cadence/config.yaml` with any free-form text. Example of a tighter restatement (the shipped default also includes Good/Bad examples and guidance about implementation details belonging in the diff — see `Config.commit_format` in `src/cadence/config.py` for the verbatim text):
165
+
166
+ ```yaml
167
+ commit_format: |
168
+ Format: <branch-name>. Added: <what>. Changed: <what>. Deleted: <what>.
169
+ Include only the sections that apply. English, single line.
170
+ Each section is one short clause describing the user-visible outcome.
171
+ Author as the user — no Co-Authored-By trailer (unless `commit_trailer` is configured).
172
+ ```
173
+
174
+ Switch to Conventional Commits:
175
+
176
+ ```yaml
177
+ commit_format: |
178
+ Use Conventional Commits: <type>(<scope>): <subject>
179
+ Types: feat, fix, refactor, docs, test, chore.
180
+ Subject is imperative, lowercase, no trailing period, ≤72 chars.
181
+ Example: feat(executor): add idle-timeout retry
182
+ ```
183
+
184
+ If you need finer control than a free-form block (e.g. different wording per phase), drop a custom `task.txt` / `review_first.txt` / `review_second.txt` under `.cadence/prompts/` — the format block is appended to whatever prompt body you supply.
185
+
186
+ ### Customizing prompts and agents
187
+
188
+ `cadence` ships with embedded defaults under `src/cadence/defaults/`. To customize, drop replacements into the project:
189
+
190
+ ```
191
+ .cadence/
192
+ config.yaml
193
+ prompts/
194
+ make_plan.txt # overrides plan-creation prompt
195
+ task.txt # overrides task-iteration prompt
196
+ review_first.txt # overrides initial review prompt
197
+ review_second.txt # overrides review-loop prompt
198
+ agents/
199
+ quality.txt # custom review agents (referenced as {{agent:quality}})
200
+ implementation.txt
201
+ testing.txt
202
+ simplification.txt
203
+ my-extra-agent.txt # add new agents — auto-discovered
204
+ ```
205
+
206
+ Per-file fallback: if a local file is empty or contains only `# comments`, the embedded default is used. Agents support optional YAML frontmatter:
207
+
208
+ ```
209
+ ---
210
+ model: sonnet # haiku | sonnet | opus (or full IDs, normalized)
211
+ agent: code-reviewer # subagent type for the Task tool
212
+ ---
213
+ Agent prompt body…
214
+ ```
215
+
216
+ Prompts can reference agents inline with `{{agent:name}}`; the runner expands these into full Task tool invocations, with base variables (`{{PLAN_FILE}}`, `{{DEFAULT_BRANCH}}`, etc.) substituted into the agent body.
217
+
218
+ ## Runtime controls
219
+
220
+ - **Ctrl+C** — graceful shutdown (twice within 5s force-exits).
221
+ - **Ctrl+\\** (`SIGQUIT`, Unix) — break the current task; the runner kills the active Claude session and prompts to resume or abort. Resume restarts the same task with a fresh session and re-reads the plan file.
222
+ - **Rate limits** — if `wait_on_limit > 0` and Claude output matches `claude_limit_patterns`, cadence sleeps and retries indefinitely until cancellation.
223
+ - **Session / idle timeouts** — kill stuck sessions; review-loop iterations skip the no-commit detection if the previous session timed out.
224
+
225
+ ## Project layout
226
+
227
+ ```
228
+ src/cadence/
229
+ cli.py Typer entrypoint, mode dispatch, signal handling
230
+ config.py Config dataclass, YAML loading, --config overrides
231
+ status.py Phase / Mode / Signal constants
232
+ input.py Interactive Q&A collector
233
+ executor/ Claude subprocess + JSON-stream parsing
234
+ git/ Service layer over `git` CLI
235
+ plan/ Markdown plan parser, branch-name extraction
236
+ processor/ Runner — orchestrates plan/task/review phases
237
+ progress/ File+stdout logger with colors and flock
238
+ defaults/
239
+ prompts/ Embedded prompt templates
240
+ agents/ Embedded review agents
241
+ ```
242
+
243
+ Deeper module references live in [`docs/`](docs/): `config.md`, `processor.md`, `executor.md`, `git-and-plans.md`, `progress-and-input.md`.
244
+
245
+ ## Development
246
+
247
+ ```bash
248
+ make install # pdm install --dev
249
+ make test # pytest tests/ -v
250
+ make test-cov # with coverage
251
+ make lint # ruff check
252
+ make typecheck # mypy --strict
253
+ make check # lint + typecheck + test
254
+ ```
255
+
256
+ Conventions:
257
+ - Python 3.14+, `mypy --strict`.
258
+ - `Protocol`-based interfaces for all `Runner` dependencies (Executor, Logger, InputCollector, GitChecker) — tests mock these directly, never the real Claude CLI or a real git repo.
259
+ - Signals are literal strings of the form `<<<CADENCE:NAME>>>` and matched against raw non-JSON CLI output only (so the same literal inside stream-json events does not trigger false positives).
260
+
261
+ ## License
262
+
263
+ MIT. See [`LICENSE`](LICENSE).
@@ -0,0 +1,94 @@
1
+ [project]
2
+ name = "cadence-runner"
3
+ dynamic = []
4
+ description = "CLI tool for autonomous task execution via Claude Code"
5
+ readme = "README.md"
6
+ authors = [
7
+ { name = "Mikhail Drozdetskiy", email = "m.drozdetskiy@gmail.com" },
8
+ ]
9
+ keywords = [
10
+ "claude",
11
+ "claude-code",
12
+ "cli",
13
+ "automation",
14
+ "agent",
15
+ ]
16
+ classifiers = [
17
+ "Development Status :: 4 - Beta",
18
+ "Environment :: Console",
19
+ "Intended Audience :: Developers",
20
+ "License :: OSI Approved :: MIT License",
21
+ "Operating System :: MacOS",
22
+ "Operating System :: POSIX :: Linux",
23
+ "Programming Language :: Python :: 3",
24
+ "Programming Language :: Python :: 3.14",
25
+ "Topic :: Software Development",
26
+ "Topic :: Utilities",
27
+ ]
28
+ requires-python = ">=3.14"
29
+ dependencies = [
30
+ "typer>=0.9",
31
+ "rich>=13.0",
32
+ "PyYAML>=6.0",
33
+ ]
34
+ version = "0.19.2"
35
+
36
+ [project.license]
37
+ text = "MIT"
38
+
39
+ [project.urls]
40
+ Homepage = "https://github.com/Drozdetskiy/cadence"
41
+ Repository = "https://github.com/Drozdetskiy/cadence"
42
+ Issues = "https://github.com/Drozdetskiy/cadence/issues"
43
+
44
+ [project.scripts]
45
+ cadence = "cadence.cli:app"
46
+
47
+ [build-system]
48
+ requires = [
49
+ "pdm-backend",
50
+ ]
51
+ build-backend = "pdm.backend"
52
+
53
+ [tool.pdm.version]
54
+ source = "file"
55
+ path = "src/cadence/__init__.py"
56
+
57
+ [tool.pdm.dev-dependencies]
58
+ dev = [
59
+ "pytest>=8.0",
60
+ "ruff>=0.4",
61
+ "mypy>=1.10",
62
+ "pytest-cov>=5.0",
63
+ "pytest-mock>=3.14",
64
+ "types-PyYAML",
65
+ ]
66
+
67
+ [tool.ruff]
68
+ target-version = "py314"
69
+ line-length = 100
70
+ src = [
71
+ "src",
72
+ "tests",
73
+ ]
74
+
75
+ [tool.ruff.lint]
76
+ select = [
77
+ "E",
78
+ "F",
79
+ "I",
80
+ "UP",
81
+ "B",
82
+ "SIM",
83
+ "RUF",
84
+ ]
85
+
86
+ [tool.mypy]
87
+ strict = true
88
+ python_version = "3.14"
89
+ mypy_path = "src"
90
+
91
+ [tool.pytest.ini_options]
92
+ testpaths = [
93
+ "tests",
94
+ ]
@@ -0,0 +1 @@
1
+ __version__ = "0.19.2"