continuous-refactoring 0.3.0__tar.gz → 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 (78) hide show
  1. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/PKG-INFO +33 -25
  2. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/README.md +32 -24
  3. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/pyproject.toml +1 -1
  4. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/cli.py +37 -53
  5. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/migration_cli.py +37 -21
  6. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/planning.py +3 -1
  7. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/planning_state.py +10 -3
  8. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/prompts.py +41 -27
  9. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/refactor_attempts.py +3 -36
  10. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/review_cli.py +36 -120
  11. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/scope_candidates.py +17 -6
  12. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/conftest.py +1 -2
  13. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_cli_migrations.py +290 -31
  14. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_cli_taste_warning.py +2 -2
  15. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_continuous_refactoring.py +1 -1
  16. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_main_entrypoint.py +5 -4
  17. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_planning.py +53 -0
  18. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_planning_state.py +5 -7
  19. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_prompts.py +66 -13
  20. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_run_once.py +28 -35
  21. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_scope_candidates.py +14 -0
  22. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_taste_interview.py +19 -6
  23. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_taste_refine.py +3 -5
  24. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_taste_upgrade.py +6 -6
  25. continuous_refactoring-0.3.0/tests/test_cli_review.py +0 -642
  26. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/.gitignore +0 -0
  27. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/LICENSE +0 -0
  28. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/__init__.py +0 -0
  29. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/__main__.py +0 -0
  30. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/agent.py +0 -0
  31. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/artifacts.py +0 -0
  32. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/commit_messages.py +0 -0
  33. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/config.py +0 -0
  34. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/decisions.py +0 -0
  35. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/effort.py +0 -0
  36. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/failure_report.py +0 -0
  37. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/git.py +0 -0
  38. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/log_mirroring.py +0 -0
  39. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/loop.py +0 -0
  40. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/migration_consistency.py +0 -0
  41. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/migration_manifest_codec.py +0 -0
  42. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/migration_tick.py +0 -0
  43. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/migrations.py +0 -0
  44. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/phases.py +0 -0
  45. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/planning_publish.py +0 -0
  46. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/routing.py +0 -0
  47. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/routing_pipeline.py +0 -0
  48. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/scope_expansion.py +0 -0
  49. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/src/continuous_refactoring/targeting.py +0 -0
  50. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/fixtures/claude_stream_json/selection.stdout.log +0 -0
  51. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_claude_stream_json.py +0 -0
  52. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_cli_init_taste.py +0 -0
  53. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_cli_upgrade.py +0 -0
  54. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_cli_version.py +0 -0
  55. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_commit_messages.py +0 -0
  56. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_config.py +0 -0
  57. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_decisions.py +0 -0
  58. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_e2e.py +0 -0
  59. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_effort.py +0 -0
  60. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_failure_report.py +0 -0
  61. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_focus_on_live_migrations.py +0 -0
  62. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_git.py +0 -0
  63. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_loop_migration_tick.py +0 -0
  64. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_migration_consistency.py +0 -0
  65. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_migrations.py +0 -0
  66. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_no_driver_branching.py +0 -0
  67. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_phases.py +0 -0
  68. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_planning_publish.py +0 -0
  69. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_prompts_scope_selection.py +0 -0
  70. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_refactor_attempts.py +0 -0
  71. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_routing.py +0 -0
  72. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_run.py +0 -0
  73. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_run_once_regression.py +0 -0
  74. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_scope_expansion.py +0 -0
  75. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_scope_loop_integration.py +0 -0
  76. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_scope_selection.py +0 -0
  77. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_targeting.py +0 -0
  78. {continuous_refactoring-0.3.0 → continuous_refactoring-1.0.0}/tests/test_wake_up.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: continuous-refactoring
3
- Version: 0.3.0
3
+ Version: 1.0.0
4
4
  Summary: Continuous refactoring loop for AI coding agents
5
5
  Project-URL: Repository, https://github.com/bigH/continuous-refactoring
6
6
  Project-URL: Issues, https://github.com/bigH/continuous-refactoring/issues
@@ -69,6 +69,10 @@ uv pip install -e .
69
69
 
70
70
  That gives you the `continuous-refactoring` command.
71
71
 
72
+ The CLI itself can be installed without `uv`, but the default validation command
73
+ is `uv run pytest`. Pass `--validation-command pytest` or a project-specific
74
+ script when the target repo does not use `uv`.
75
+
72
76
  Maintainers: see the [release checklist](https://github.com/bigH/continuous-refactoring/blob/main/docs/release.md).
73
77
 
74
78
  ## Fastest way to get one refactor
@@ -124,8 +128,8 @@ continuous-refactoring init --in-repo-taste
124
128
 
125
129
  # 2. (Optional) Write your refactoring taste — either edit the file, have an agent interview you,
126
130
  # or refine an existing draft collaboratively
127
- continuous-refactoring taste --interview --with codex --model gpt-5 --effort high
128
- continuous-refactoring taste --refine --with codex --model gpt-5 --effort high
131
+ continuous-refactoring taste --interview --with codex --model gpt-5
132
+ continuous-refactoring taste --refine --with codex --model gpt-5
129
133
 
130
134
  # 3. Do one pass
131
135
  continuous-refactoring run-once \
@@ -141,22 +145,23 @@ continuous-refactoring run \
141
145
  --sleep 5
142
146
  ```
143
147
 
148
+ Active taste agent modes require `--with` and `--model`; taste agent sessions
149
+ always run at fixed `medium` effort.
150
+
144
151
  ## Subcommands
145
152
 
146
153
  | Command | What it does |
147
154
  |---|---|
148
155
  | `init` | Registers this directory as a project, creates a default `taste.md`, and can store `--live-migrations-dir` or `--in-repo-taste`. |
149
- | `taste` | Prints the active taste file path. Add `--interview` to have an agent author it, `--refine` to iteratively improve an existing taste doc, `--upgrade` to refresh stale taste dimensions, `--global` for the shared file, and `--force` to let `--interview` overwrite custom content after writing a `.bak`. |
156
+ | `taste` | Prints the active taste file path. Add `--interview` to have an agent author it, `--refine` to iteratively improve an existing taste doc, `--upgrade` to refresh stale taste dimensions, `--global` for the shared file, and `--force` to let `--interview` overwrite custom content after writing a `.bak`. Active agent modes require `--with` and `--model`, then run at fixed `medium` effort. |
150
157
  | `run-once` | Single pass on one resolved target. No retry. If there is a diff and validation passes, it commits locally and prints the diffstat. |
151
158
  | `run` | The loop. Iterates refactor actions, retries on failure, and commits successful changes locally. Add `--focus-on-live-migrations` to bypass targeting and work only on eligible live migrations. |
152
159
  | `upgrade` | Checks that the global config manifest is current, rewrites it idempotently, and warns if the global taste file is stale. |
153
- | `migration list` | Lists visible migrations. Add `--status <status>` or `--awaiting-review` to filter. |
160
+ | `migration list` | Lists visible migrations as TSV with headers. Add `--status <status>` or `--awaiting-review` to filter, or `--no-headers` for parsing. |
154
161
  | `migration doctor <slug-or-path>` | Validates one visible migration's consistency. |
155
162
  | `migration doctor --all` | Validates every visible migration plus internal transaction state. |
156
- | `migration review <slug-or-path>` | Starts staged review for a migration awaiting human review. Requires `--with`, `--model`, and `--effort`. |
157
- | `migration refine <slug-or-path>` | Records feedback for a planning or unexecuted ready migration and runs one staged planning revision. Requires `--message <text>` or `--file <path>`, plus `--with`, `--model`, and `--effort`; add `--show-agent-logs` to mirror the planning agent. |
158
-
159
- Legacy `review list` and `review perform <migration>` remain compatibility aliases; prefer `migration list --awaiting-review` and `migration review`.
163
+ | `migration review <slug-or-path>` | Starts staged review for a migration awaiting human review. Requires `--with` and `--model`; review runs at fixed internal `high` effort. |
164
+ | `migration refine <slug-or-path>` | Records feedback for a planning or unexecuted ready migration and runs one staged planning revision. Requires `--message <text>` or `--file <path>`, plus `--with` and `--model`; refine runs at fixed internal `high` effort. Add `--show-agent-logs` to mirror the planning agent. |
160
165
 
161
166
  ## Targeting / Useful flags
162
167
 
@@ -174,8 +179,9 @@ These flags are not mutually exclusive, but only the highest-priority populated
174
179
  - `--scope-instruction "clean up the auth module"` — extra free-text scoping. If selected file patterns resolve nothing, this becomes the useful fallback context.
175
180
 
176
181
  If `--globs` or `--extensions` match no tracked files and there is no
177
- `--scope-instruction`, `run` completes successfully with zero refactor actions.
178
- `--paths` is literal input and is not filtered through `git ls-files`.
182
+ `--scope-instruction`, `run` completes successfully with zero refactor actions;
183
+ `run-once` falls back to a no-file `general refactoring` target. `--paths` is
184
+ literal input and is not filtered through `git ls-files`.
179
185
 
180
186
  If you provide none of `--targets`, `--globs`, `--extensions`, or `--paths`,
181
187
  then `run` and `run-once` require `--scope-instruction`; the driver still
@@ -186,12 +192,13 @@ scope text as context for that target.
186
192
 
187
193
  - `init --live-migrations-dir PATH` — enables the larger-refactoring workflow for this project. The path is stored repo-relative in the project registry and created if missing.
188
194
  - `init --in-repo-taste [PATH]` — stores this project's taste file in the repo and remembers the repo-relative path. Defaults to `.continuous-refactoring/taste.md`; re-run `init --in-repo-taste ...` to choose a different path.
189
- - `migration list` — shows visible migrations; `--awaiting-review` narrows to human-review handoffs.
195
+ - `migration list` — shows visible migrations as TSV with headers; `--awaiting-review` narrows to human-review handoffs and `--no-headers` keeps parser-friendly rows only.
190
196
  - `migration doctor <slug-or-path>` / `migration doctor --all` — read-only consistency checks. Doctor reports problems; it does not repair them.
191
- - `migration review <slug-or-path> --with ... --model ... --effort ...` — resolves an `awaiting_human_review` migration through a staged workspace.
192
- - `migration refine <slug-or-path> (--message <text>|--file <path>) --with ... --model ... --effort ... [--show-agent-logs]` — adds user feedback to a planning or unexecuted ready migration and resumes planning through the `revise` step when reopening ready work.
193
- - `taste --refine` — opens a collaborative editing session for the taste file. The agent keeps refining until you tell it to write, then the session ends automatically after the settled write.
194
- - `taste --upgrade` — re-interviews for taste dimensions added since your last version. No-op when already current; use `taste --refine` if you want to rework the doc anyway.
197
+ - `migration review <slug-or-path> --with ... --model ...` — resolves an `awaiting_human_review` migration through a staged workspace at fixed internal `high` effort.
198
+ - `migration refine <slug-or-path> (--message <text>|--file <path>) --with ... --model ... [--show-agent-logs]` — adds user feedback to a planning or unexecuted ready migration and resumes planning through the `revise` step when reopening ready work at fixed internal `high` effort.
199
+ - `taste --refine --with ... --model ...` — opens a collaborative editing session for the taste file. The agent keeps refining until you tell it to write, then the session ends automatically after the settled write.
200
+ - `taste --upgrade --with ... --model ...` — re-interviews for taste dimensions added since your last version. No-op when already current; use `taste --refine` if you want to rework the doc anyway.
201
+ - Taste agent sessions always use fixed `medium` effort.
195
202
  - `taste --force` — only applies to `--interview`; it allows a customized taste file to be overwritten after backing it up to `taste.md.bak`.
196
203
 
197
204
  Canonical migration commands:
@@ -200,11 +207,12 @@ Canonical migration commands:
200
207
  continuous-refactoring migration list
201
208
  continuous-refactoring migration list --status planning
202
209
  continuous-refactoring migration list --awaiting-review
210
+ continuous-refactoring migration list --no-headers
203
211
  continuous-refactoring migration doctor <slug-or-path>
204
212
  continuous-refactoring migration doctor --all
205
- continuous-refactoring migration review <slug-or-path> --with codex --model gpt-5 --effort high
206
- continuous-refactoring migration refine <slug-or-path> --message "split the risky phase" --with codex --model gpt-5 --effort high
207
- continuous-refactoring migration refine <slug-or-path> --file feedback.md --with codex --model gpt-5 --effort high
213
+ continuous-refactoring migration review <slug-or-path> --with codex --model gpt-5
214
+ continuous-refactoring migration refine <slug-or-path> --message "split the risky phase" --with codex --model gpt-5
215
+ continuous-refactoring migration refine <slug-or-path> --file feedback.md --with codex --model gpt-5
208
216
  ```
209
217
 
210
218
  ### Shared `run` / `run-once` flags
@@ -213,7 +221,7 @@ continuous-refactoring migration refine <slug-or-path> --file feedback.md --with
213
221
  - `--default-effort` — default effort for run calls. Defaults to `low`. Valid labels are `low`, `medium`, `high`, `xhigh`.
214
222
  - `--max-allowed-effort` — cap for target overrides and migration escalation. Defaults to `xhigh`.
215
223
  - `--repo-root PATH` — repository root; defaults to the current directory.
216
- - `--validation-command` — defaults to `uv run pytest`. Swap it for whatever keeps your repo honest.
224
+ - `--validation-command` — defaults to `uv run pytest`. This is parsed with `shlex.split` and run without a shell, so simple commands like `pytest -q` work, but shell syntax such as `cmd && cmd`, pipes, redirects, or leading `VAR=value` assignments is not interpreted. Put compound validation in a script.
217
225
  - `--timeout` — per-agent-call timeout in seconds.
218
226
  - `--show-agent-logs` / `--show-command-logs` — mirror output to your terminal instead of just logging.
219
227
  - `--refactoring-prompt` — override the default refactoring prompt.
@@ -242,9 +250,9 @@ continuous-refactoring migration refine <slug-or-path> --file feedback.md --with
242
250
  Each run writes to `$TMPDIR/continuous-refactoring/<run-id>/`:
243
251
 
244
252
  - `summary.json` — rolling status, counts, per-attempt stats
245
- - `events.jsonl` — structured event log with call roles such as `classify`,
246
- `planning.<step>`, `phase.ready-check`, `phase.execute`, and
247
- `phase.validation`
253
+ - `events.jsonl` — structured event log with call roles such as
254
+ `scope-expansion`, `classify`, `planning.<step>`, `planning.publish`,
255
+ `phase.ready-check`, `phase.execute`, and `phase.validation`
248
256
  - `run.log` — human-readable log
249
257
  - `attempt-NNN/[retry-NN/]refactor/` — per-attempt agent + test stdout/stderr
250
258
  - `baseline/initial/` — baseline validation stdout/stderr before work starts
@@ -271,7 +279,7 @@ The taste file is a short bullet list of your refactoring preferences. It gets i
271
279
  - Project taste: `~/.local/share/continuous-refactoring/projects/<uuid>/taste.md`, or the repo-local path chosen with `init --in-repo-taste [PATH]`
272
280
  - Global taste: `~/.local/share/continuous-refactoring/global/taste.md`
273
281
 
274
- Project taste wins over global. Use `taste` to print the active path, `taste --interview` to bootstrap one, `taste --refine` to rework it with an agent, or edit the file directly any time.
282
+ Project taste wins over global. Use `taste` to print the active path, `taste --interview --with ... --model ...` to bootstrap one, `taste --refine --with ... --model ...` to rework it with an agent, or edit the file directly any time.
275
283
 
276
284
  ## Larger refactorings
277
285
 
@@ -346,7 +354,7 @@ Before executing a phase, a ready-check agent verifies that the current phase pr
346
354
 
347
355
  - **ready: yes** — phase executes; on green tests, the phase is marked done, any prior deferral markers are cleared, and the migration advances immediately to the next phase.
348
356
  - **ready: no** — manifest activity is bumped, a retry cooldown is started, and a future `wake_up_on` is recorded when needed; the tick moves on.
349
- - **ready: unverifiable** — the migration is flagged `awaiting_human_review` and put on cooldown. Automated migration ticks skip flagged migrations until review clears the flag. Use `migration list --awaiting-review` to find it and `migration review <slug-or-path> --with ... --model ... --effort ...` to resolve it interactively.
357
+ - **ready: unverifiable** — the migration is marked `awaiting_human_review` and put on cooldown. Automated migration ticks skip migrations awaiting human review until review clears the flag. Use `migration list --awaiting-review` to find it and `migration review <slug-or-path> --with ... --model ...` to resolve it interactively.
350
358
 
351
359
  Human-facing migration references use the relative phase spec path, for example `phase-2-failure-report.md`. The manifest cursor stores the phase `name`, not a numeric index.
352
360
 
@@ -46,6 +46,10 @@ uv pip install -e .
46
46
 
47
47
  That gives you the `continuous-refactoring` command.
48
48
 
49
+ The CLI itself can be installed without `uv`, but the default validation command
50
+ is `uv run pytest`. Pass `--validation-command pytest` or a project-specific
51
+ script when the target repo does not use `uv`.
52
+
49
53
  Maintainers: see the [release checklist](https://github.com/bigH/continuous-refactoring/blob/main/docs/release.md).
50
54
 
51
55
  ## Fastest way to get one refactor
@@ -101,8 +105,8 @@ continuous-refactoring init --in-repo-taste
101
105
 
102
106
  # 2. (Optional) Write your refactoring taste — either edit the file, have an agent interview you,
103
107
  # or refine an existing draft collaboratively
104
- continuous-refactoring taste --interview --with codex --model gpt-5 --effort high
105
- continuous-refactoring taste --refine --with codex --model gpt-5 --effort high
108
+ continuous-refactoring taste --interview --with codex --model gpt-5
109
+ continuous-refactoring taste --refine --with codex --model gpt-5
106
110
 
107
111
  # 3. Do one pass
108
112
  continuous-refactoring run-once \
@@ -118,22 +122,23 @@ continuous-refactoring run \
118
122
  --sleep 5
119
123
  ```
120
124
 
125
+ Active taste agent modes require `--with` and `--model`; taste agent sessions
126
+ always run at fixed `medium` effort.
127
+
121
128
  ## Subcommands
122
129
 
123
130
  | Command | What it does |
124
131
  |---|---|
125
132
  | `init` | Registers this directory as a project, creates a default `taste.md`, and can store `--live-migrations-dir` or `--in-repo-taste`. |
126
- | `taste` | Prints the active taste file path. Add `--interview` to have an agent author it, `--refine` to iteratively improve an existing taste doc, `--upgrade` to refresh stale taste dimensions, `--global` for the shared file, and `--force` to let `--interview` overwrite custom content after writing a `.bak`. |
133
+ | `taste` | Prints the active taste file path. Add `--interview` to have an agent author it, `--refine` to iteratively improve an existing taste doc, `--upgrade` to refresh stale taste dimensions, `--global` for the shared file, and `--force` to let `--interview` overwrite custom content after writing a `.bak`. Active agent modes require `--with` and `--model`, then run at fixed `medium` effort. |
127
134
  | `run-once` | Single pass on one resolved target. No retry. If there is a diff and validation passes, it commits locally and prints the diffstat. |
128
135
  | `run` | The loop. Iterates refactor actions, retries on failure, and commits successful changes locally. Add `--focus-on-live-migrations` to bypass targeting and work only on eligible live migrations. |
129
136
  | `upgrade` | Checks that the global config manifest is current, rewrites it idempotently, and warns if the global taste file is stale. |
130
- | `migration list` | Lists visible migrations. Add `--status <status>` or `--awaiting-review` to filter. |
137
+ | `migration list` | Lists visible migrations as TSV with headers. Add `--status <status>` or `--awaiting-review` to filter, or `--no-headers` for parsing. |
131
138
  | `migration doctor <slug-or-path>` | Validates one visible migration's consistency. |
132
139
  | `migration doctor --all` | Validates every visible migration plus internal transaction state. |
133
- | `migration review <slug-or-path>` | Starts staged review for a migration awaiting human review. Requires `--with`, `--model`, and `--effort`. |
134
- | `migration refine <slug-or-path>` | Records feedback for a planning or unexecuted ready migration and runs one staged planning revision. Requires `--message <text>` or `--file <path>`, plus `--with`, `--model`, and `--effort`; add `--show-agent-logs` to mirror the planning agent. |
135
-
136
- Legacy `review list` and `review perform <migration>` remain compatibility aliases; prefer `migration list --awaiting-review` and `migration review`.
140
+ | `migration review <slug-or-path>` | Starts staged review for a migration awaiting human review. Requires `--with` and `--model`; review runs at fixed internal `high` effort. |
141
+ | `migration refine <slug-or-path>` | Records feedback for a planning or unexecuted ready migration and runs one staged planning revision. Requires `--message <text>` or `--file <path>`, plus `--with` and `--model`; refine runs at fixed internal `high` effort. Add `--show-agent-logs` to mirror the planning agent. |
137
142
 
138
143
  ## Targeting / Useful flags
139
144
 
@@ -151,8 +156,9 @@ These flags are not mutually exclusive, but only the highest-priority populated
151
156
  - `--scope-instruction "clean up the auth module"` — extra free-text scoping. If selected file patterns resolve nothing, this becomes the useful fallback context.
152
157
 
153
158
  If `--globs` or `--extensions` match no tracked files and there is no
154
- `--scope-instruction`, `run` completes successfully with zero refactor actions.
155
- `--paths` is literal input and is not filtered through `git ls-files`.
159
+ `--scope-instruction`, `run` completes successfully with zero refactor actions;
160
+ `run-once` falls back to a no-file `general refactoring` target. `--paths` is
161
+ literal input and is not filtered through `git ls-files`.
156
162
 
157
163
  If you provide none of `--targets`, `--globs`, `--extensions`, or `--paths`,
158
164
  then `run` and `run-once` require `--scope-instruction`; the driver still
@@ -163,12 +169,13 @@ scope text as context for that target.
163
169
 
164
170
  - `init --live-migrations-dir PATH` — enables the larger-refactoring workflow for this project. The path is stored repo-relative in the project registry and created if missing.
165
171
  - `init --in-repo-taste [PATH]` — stores this project's taste file in the repo and remembers the repo-relative path. Defaults to `.continuous-refactoring/taste.md`; re-run `init --in-repo-taste ...` to choose a different path.
166
- - `migration list` — shows visible migrations; `--awaiting-review` narrows to human-review handoffs.
172
+ - `migration list` — shows visible migrations as TSV with headers; `--awaiting-review` narrows to human-review handoffs and `--no-headers` keeps parser-friendly rows only.
167
173
  - `migration doctor <slug-or-path>` / `migration doctor --all` — read-only consistency checks. Doctor reports problems; it does not repair them.
168
- - `migration review <slug-or-path> --with ... --model ... --effort ...` — resolves an `awaiting_human_review` migration through a staged workspace.
169
- - `migration refine <slug-or-path> (--message <text>|--file <path>) --with ... --model ... --effort ... [--show-agent-logs]` — adds user feedback to a planning or unexecuted ready migration and resumes planning through the `revise` step when reopening ready work.
170
- - `taste --refine` — opens a collaborative editing session for the taste file. The agent keeps refining until you tell it to write, then the session ends automatically after the settled write.
171
- - `taste --upgrade` — re-interviews for taste dimensions added since your last version. No-op when already current; use `taste --refine` if you want to rework the doc anyway.
174
+ - `migration review <slug-or-path> --with ... --model ...` — resolves an `awaiting_human_review` migration through a staged workspace at fixed internal `high` effort.
175
+ - `migration refine <slug-or-path> (--message <text>|--file <path>) --with ... --model ... [--show-agent-logs]` — adds user feedback to a planning or unexecuted ready migration and resumes planning through the `revise` step when reopening ready work at fixed internal `high` effort.
176
+ - `taste --refine --with ... --model ...` — opens a collaborative editing session for the taste file. The agent keeps refining until you tell it to write, then the session ends automatically after the settled write.
177
+ - `taste --upgrade --with ... --model ...` — re-interviews for taste dimensions added since your last version. No-op when already current; use `taste --refine` if you want to rework the doc anyway.
178
+ - Taste agent sessions always use fixed `medium` effort.
172
179
  - `taste --force` — only applies to `--interview`; it allows a customized taste file to be overwritten after backing it up to `taste.md.bak`.
173
180
 
174
181
  Canonical migration commands:
@@ -177,11 +184,12 @@ Canonical migration commands:
177
184
  continuous-refactoring migration list
178
185
  continuous-refactoring migration list --status planning
179
186
  continuous-refactoring migration list --awaiting-review
187
+ continuous-refactoring migration list --no-headers
180
188
  continuous-refactoring migration doctor <slug-or-path>
181
189
  continuous-refactoring migration doctor --all
182
- continuous-refactoring migration review <slug-or-path> --with codex --model gpt-5 --effort high
183
- continuous-refactoring migration refine <slug-or-path> --message "split the risky phase" --with codex --model gpt-5 --effort high
184
- continuous-refactoring migration refine <slug-or-path> --file feedback.md --with codex --model gpt-5 --effort high
190
+ continuous-refactoring migration review <slug-or-path> --with codex --model gpt-5
191
+ continuous-refactoring migration refine <slug-or-path> --message "split the risky phase" --with codex --model gpt-5
192
+ continuous-refactoring migration refine <slug-or-path> --file feedback.md --with codex --model gpt-5
185
193
  ```
186
194
 
187
195
  ### Shared `run` / `run-once` flags
@@ -190,7 +198,7 @@ continuous-refactoring migration refine <slug-or-path> --file feedback.md --with
190
198
  - `--default-effort` — default effort for run calls. Defaults to `low`. Valid labels are `low`, `medium`, `high`, `xhigh`.
191
199
  - `--max-allowed-effort` — cap for target overrides and migration escalation. Defaults to `xhigh`.
192
200
  - `--repo-root PATH` — repository root; defaults to the current directory.
193
- - `--validation-command` — defaults to `uv run pytest`. Swap it for whatever keeps your repo honest.
201
+ - `--validation-command` — defaults to `uv run pytest`. This is parsed with `shlex.split` and run without a shell, so simple commands like `pytest -q` work, but shell syntax such as `cmd && cmd`, pipes, redirects, or leading `VAR=value` assignments is not interpreted. Put compound validation in a script.
194
202
  - `--timeout` — per-agent-call timeout in seconds.
195
203
  - `--show-agent-logs` / `--show-command-logs` — mirror output to your terminal instead of just logging.
196
204
  - `--refactoring-prompt` — override the default refactoring prompt.
@@ -219,9 +227,9 @@ continuous-refactoring migration refine <slug-or-path> --file feedback.md --with
219
227
  Each run writes to `$TMPDIR/continuous-refactoring/<run-id>/`:
220
228
 
221
229
  - `summary.json` — rolling status, counts, per-attempt stats
222
- - `events.jsonl` — structured event log with call roles such as `classify`,
223
- `planning.<step>`, `phase.ready-check`, `phase.execute`, and
224
- `phase.validation`
230
+ - `events.jsonl` — structured event log with call roles such as
231
+ `scope-expansion`, `classify`, `planning.<step>`, `planning.publish`,
232
+ `phase.ready-check`, `phase.execute`, and `phase.validation`
225
233
  - `run.log` — human-readable log
226
234
  - `attempt-NNN/[retry-NN/]refactor/` — per-attempt agent + test stdout/stderr
227
235
  - `baseline/initial/` — baseline validation stdout/stderr before work starts
@@ -248,7 +256,7 @@ The taste file is a short bullet list of your refactoring preferences. It gets i
248
256
  - Project taste: `~/.local/share/continuous-refactoring/projects/<uuid>/taste.md`, or the repo-local path chosen with `init --in-repo-taste [PATH]`
249
257
  - Global taste: `~/.local/share/continuous-refactoring/global/taste.md`
250
258
 
251
- Project taste wins over global. Use `taste` to print the active path, `taste --interview` to bootstrap one, `taste --refine` to rework it with an agent, or edit the file directly any time.
259
+ Project taste wins over global. Use `taste` to print the active path, `taste --interview --with ... --model ...` to bootstrap one, `taste --refine --with ... --model ...` to rework it with an agent, or edit the file directly any time.
252
260
 
253
261
  ## Larger refactorings
254
262
 
@@ -323,7 +331,7 @@ Before executing a phase, a ready-check agent verifies that the current phase pr
323
331
 
324
332
  - **ready: yes** — phase executes; on green tests, the phase is marked done, any prior deferral markers are cleared, and the migration advances immediately to the next phase.
325
333
  - **ready: no** — manifest activity is bumped, a retry cooldown is started, and a future `wake_up_on` is recorded when needed; the tick moves on.
326
- - **ready: unverifiable** — the migration is flagged `awaiting_human_review` and put on cooldown. Automated migration ticks skip flagged migrations until review clears the flag. Use `migration list --awaiting-review` to find it and `migration review <slug-or-path> --with ... --model ... --effort ...` to resolve it interactively.
334
+ - **ready: unverifiable** — the migration is marked `awaiting_human_review` and put on cooldown. Automated migration ticks skip migrations awaiting human review until review clears the flag. Use `migration list --awaiting-review` to find it and `migration review <slug-or-path> --with ... --model ...` to resolve it interactively.
327
335
 
328
336
  Human-facing migration references use the relative phase spec path, for example `phase-2-failure-report.md`. The manifest cursor stores the phase `name`, not a numeric index.
329
337
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "continuous-refactoring"
3
- version = "0.3.0"
3
+ version = "1.0.0"
4
4
  description = "Continuous refactoring loop for AI coding agents"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -32,7 +32,6 @@ from continuous_refactoring.loop import (
32
32
  )
33
33
  from continuous_refactoring.migration_cli import handle_migration
34
34
  from continuous_refactoring.migrations import MIGRATION_STATUSES
35
- from continuous_refactoring.review_cli import handle_review
36
35
 
37
36
  _PACKAGE_DISTRIBUTION = "continuous-refactoring"
38
37
  _TASTE_WARNING = "warning: taste out of date — run `continuous-refactoring taste --upgrade`"
@@ -40,6 +39,7 @@ _GLOBAL_TASTE_WARNING = (
40
39
  "warning: global taste is out of date — "
41
40
  "run 'continuous-refactoring taste --upgrade' to update."
42
41
  )
42
+ _TASTE_AGENT_EFFORT = "medium"
43
43
 
44
44
 
45
45
  def _version_banner() -> str:
@@ -155,6 +155,10 @@ def _add_taste_parser(subparsers: argparse._SubParsersAction) -> None:
155
155
  taste_parser = subparsers.add_parser(
156
156
  "taste",
157
157
  help="Manage refactoring taste files.",
158
+ description=(
159
+ "Manage project or global taste files. Agent-backed modes require "
160
+ "--with and --model."
161
+ ),
158
162
  )
159
163
  taste_parser.set_defaults(handler=_handle_taste)
160
164
  taste_parser.add_argument(
@@ -191,11 +195,6 @@ def _add_taste_parser(subparsers: argparse._SubParsersAction) -> None:
191
195
  default=None,
192
196
  help="Model name for --interview, --upgrade, or --refine.",
193
197
  )
194
- taste_parser.add_argument(
195
- "--effort",
196
- default=None,
197
- help="Effort level for --interview, --upgrade, or --refine.",
198
- )
199
198
  taste_parser.add_argument(
200
199
  "--force",
201
200
  action="store_true",
@@ -206,7 +205,8 @@ def _add_taste_parser(subparsers: argparse._SubParsersAction) -> None:
206
205
  def _add_run_once_parser(subparsers: argparse._SubParsersAction) -> None:
207
206
  run_once_parser = subparsers.add_parser(
208
207
  "run-once",
209
- help="Single refactoring attempt (one agent call, no fix retry).",
208
+ help="Run one routed refactoring action without fix retry.",
209
+ description="Run one routed refactoring action without fix retry.",
210
210
  )
211
211
  run_once_parser.set_defaults(handler=_handle_run_once)
212
212
  _add_common_args(run_once_parser)
@@ -215,7 +215,8 @@ def _add_run_once_parser(subparsers: argparse._SubParsersAction) -> None:
215
215
  def _add_run_parser(subparsers: argparse._SubParsersAction) -> None:
216
216
  run_parser = subparsers.add_parser(
217
217
  "run",
218
- help="Continuous refactoring loop with fix-prompt retry.",
218
+ help="Run routed refactoring actions with fix-prompt retry.",
219
+ description="Run routed refactoring actions with fix-prompt retry.",
219
220
  )
220
221
  run_parser.set_defaults(handler=_handle_run)
221
222
  _add_common_args(run_parser)
@@ -229,13 +230,14 @@ def _add_run_parser(subparsers: argparse._SubParsersAction) -> None:
229
230
  "--max-refactors",
230
231
  type=int,
231
232
  default=None,
232
- help="Refactor actions to run.",
233
+ help="Actions to run.",
233
234
  )
234
235
  run_parser.add_argument(
235
236
  "--focus-on-live-migrations",
236
237
  action="store_true",
237
238
  help=(
238
- "Iterate only on live migrations until every one is done or blocked. "
239
+ "Iterate only on eligible live migrations until done, deferred, "
240
+ "blocked, or failure budget trips. "
239
241
  "Bypasses targeting and --max-refactors requirements."
240
242
  ),
241
243
  )
@@ -258,31 +260,11 @@ def _add_run_parser(subparsers: argparse._SubParsersAction) -> None:
258
260
  )
259
261
 
260
262
 
261
- def _add_review_parser(subparsers: argparse._SubParsersAction) -> None:
262
- review_parser = subparsers.add_parser(
263
- "review",
264
- help="Review migrations awaiting human review.",
265
- )
266
- review_parser.set_defaults(handler=handle_review)
267
- review_sub = review_parser.add_subparsers(dest="review_command")
268
- review_sub.add_parser("list", help="List migrations flagged for review.")
269
- perform_parser = review_sub.add_parser(
270
- "perform",
271
- help="Perform review on a flagged migration.",
272
- )
273
- perform_parser.add_argument("migration", help="Migration name to review.")
274
- perform_parser.add_argument(
275
- "--with", dest="agent", choices=("codex", "claude"), required=True,
276
- help="Agent backend.",
277
- )
278
- perform_parser.add_argument("--model", required=True, help="Model name.")
279
- perform_parser.add_argument("--effort", required=True, help="Effort level.")
280
-
281
-
282
263
  def _add_migration_parser(subparsers: argparse._SubParsersAction) -> None:
283
264
  migration_parser = subparsers.add_parser(
284
265
  "migration",
285
- help="Inspect live migrations.",
266
+ help="Inspect and manage live migrations.",
267
+ description="Inspect and manage live migrations.",
286
268
  )
287
269
  migration_parser.set_defaults(handler=handle_migration)
288
270
  migration_sub = migration_parser.add_subparsers(dest="migration_command")
@@ -302,6 +284,11 @@ def _add_migration_parser(subparsers: argparse._SubParsersAction) -> None:
302
284
  action="store_true",
303
285
  help="Only show migrations awaiting human review.",
304
286
  )
287
+ list_parser.add_argument(
288
+ "--no-headers",
289
+ action="store_true",
290
+ help="Omit the TSV header row.",
291
+ )
305
292
 
306
293
  doctor_parser = migration_sub.add_parser(
307
294
  "doctor",
@@ -320,7 +307,11 @@ def _add_migration_parser(subparsers: argparse._SubParsersAction) -> None:
320
307
 
321
308
  review_parser = migration_sub.add_parser(
322
309
  "review",
323
- help="Perform staged review on a flagged migration.",
310
+ help="Resolve a migration awaiting human review in a staged workspace.",
311
+ description=(
312
+ "Resolve a migration awaiting human review in a staged workspace. "
313
+ "Requires --with and --model."
314
+ ),
324
315
  )
325
316
  review_parser.add_argument("target", help="Migration slug or contained path.")
326
317
  review_parser.add_argument(
@@ -328,13 +319,11 @@ def _add_migration_parser(subparsers: argparse._SubParsersAction) -> None:
328
319
  help="Agent backend.",
329
320
  )
330
321
  review_parser.add_argument("--model", required=True, help="Model name.")
331
- review_parser.add_argument(
332
- "--effort", choices=EFFORT_TIERS, required=True, help="Effort level."
333
- )
334
322
 
335
323
  refine_parser = migration_sub.add_parser(
336
324
  "refine",
337
- help="Refine a planning migration with user feedback.",
325
+ help="Apply feedback to a planning or unexecuted ready migration.",
326
+ description="Apply feedback to a planning or unexecuted ready migration.",
338
327
  )
339
328
  refine_parser.add_argument("target", help="Migration slug or contained path.")
340
329
  feedback_group = refine_parser.add_mutually_exclusive_group(required=True)
@@ -349,9 +338,6 @@ def _add_migration_parser(subparsers: argparse._SubParsersAction) -> None:
349
338
  help="Agent backend.",
350
339
  )
351
340
  refine_parser.add_argument("--model", required=True, help="Model name.")
352
- refine_parser.add_argument(
353
- "--effort", choices=EFFORT_TIERS, required=True, help="Effort level."
354
- )
355
341
  refine_parser.add_argument(
356
342
  "--show-agent-logs",
357
343
  action="store_true",
@@ -380,7 +366,6 @@ def build_parser() -> argparse.ArgumentParser:
380
366
  )
381
367
  upgrade_parser.set_defaults(handler=_handle_upgrade)
382
368
  _add_migration_parser(subparsers)
383
- _add_review_parser(subparsers)
384
369
 
385
370
  return parser
386
371
 
@@ -499,7 +484,9 @@ def _configure_repo_taste(
499
484
  if not current.exists():
500
485
  ensure_taste_file(destination)
501
486
  return
502
- if current.resolve() == destination.resolve():
487
+ current_resolved = current.resolve()
488
+ destination_resolved = destination.resolve()
489
+ if current_resolved == destination_resolved:
503
490
  return
504
491
  if not current.is_file():
505
492
  raise ContinuousRefactorError(
@@ -529,15 +516,17 @@ def _configure_live_migrations_dir(
529
516
  if current is None or not current.exists():
530
517
  destination.mkdir(parents=True, exist_ok=True)
531
518
  return
519
+ current_resolved = current.resolve()
520
+ destination_resolved = destination.resolve()
532
521
  if not current.is_dir():
533
522
  raise ContinuousRefactorError(
534
523
  f"Configured live migrations path is not a directory: {current}"
535
524
  )
536
- if current.resolve() == destination.resolve():
525
+ if current_resolved == destination_resolved:
537
526
  return
538
527
  if (
539
- destination.resolve().is_relative_to(current.resolve())
540
- or current.resolve().is_relative_to(destination.resolve())
528
+ destination_resolved.is_relative_to(current_resolved)
529
+ or current_resolved.is_relative_to(destination_resolved)
541
530
  ):
542
531
  raise ContinuousRefactorError(
543
532
  "Live migrations directory cannot be moved into itself or one of "
@@ -620,9 +609,7 @@ def _active_taste_mode(args: argparse.Namespace) -> str | None:
620
609
 
621
610
 
622
611
  def _taste_agent_flags_set(args: argparse.Namespace) -> bool:
623
- return any(
624
- getattr(args, name, None) is not None for name in ("agent", "model", "effort")
625
- )
612
+ return any(getattr(args, name, None) is not None for name in ("agent", "model"))
626
613
 
627
614
 
628
615
  def _require_taste_action_flags(
@@ -630,14 +617,12 @@ def _require_taste_action_flags(
630
617
  action: str,
631
618
  agent: str | None,
632
619
  model: str | None,
633
- effort: str | None,
634
620
  ) -> None:
635
621
  missing = [
636
622
  flag
637
623
  for flag, value in (
638
624
  ("--with", agent),
639
625
  ("--model", model),
640
- ("--effort", effort),
641
626
  )
642
627
  if not value
643
628
  ]
@@ -661,7 +646,7 @@ def _run_taste_agent(
661
646
  returncode = run_agent_interactive_until_settled(
662
647
  args.agent,
663
648
  args.model,
664
- args.effort,
649
+ _TASTE_AGENT_EFFORT,
665
650
  prompt,
666
651
  Path.cwd().resolve(),
667
652
  content_path=path,
@@ -729,7 +714,7 @@ def _handle_taste(args: argparse.Namespace) -> None:
729
714
  if mode is None:
730
715
  if _taste_agent_flags_set(args):
731
716
  print(
732
- "Error: --with/--model/--effort require --interview, --upgrade, or --refine.",
717
+ "Error: --with/--model require --interview, --upgrade, or --refine.",
733
718
  file=sys.stderr,
734
719
  )
735
720
  raise SystemExit(2)
@@ -741,7 +726,6 @@ def _handle_taste(args: argparse.Namespace) -> None:
741
726
  action=mode,
742
727
  agent=getattr(args, "agent", None),
743
728
  model=getattr(args, "model", None),
744
- effort=getattr(args, "effort", None),
745
729
  )
746
730
  return _TASTE_MODE_HANDLERS[mode](args)
747
731