claude-code-generator 0.1.0__tar.gz → 0.2.1__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.
- {claude_code_generator-0.1.0/src/claude_code_generator.egg-info → claude_code_generator-0.2.1}/PKG-INFO +23 -7
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/README.md +22 -6
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/pyproject.toml +5 -1
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1/src/claude_code_generator.egg-info}/PKG-INFO +23 -7
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/src/claude_code_generator.egg-info/SOURCES.txt +38 -1
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/src/code_generator/__init__.py +1 -1
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/src/code_generator/cli.py +2 -0
- claude_code_generator-0.2.1/src/code_generator/commands/_detect.py +59 -0
- claude_code_generator-0.2.1/src/code_generator/commands/_dispatch.py +278 -0
- claude_code_generator-0.2.1/src/code_generator/commands/_resume.py +73 -0
- claude_code_generator-0.2.1/src/code_generator/commands/generate.py +126 -0
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/src/code_generator/commands/init.py +1 -3
- claude_code_generator-0.2.1/src/code_generator/commands/optimize.py +158 -0
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/src/code_generator/commands/review.py +18 -28
- claude_code_generator-0.2.1/src/code_generator/commands/status.py +192 -0
- claude_code_generator-0.2.1/src/code_generator/effort.py +164 -0
- claude_code_generator-0.2.1/src/code_generator/gh/__init__.py +51 -0
- claude_code_generator-0.2.1/src/code_generator/gh/core.py +111 -0
- claude_code_generator-0.2.1/src/code_generator/gh/issues.py +66 -0
- claude_code_generator-0.2.1/src/code_generator/gh/labels.py +102 -0
- claude_code_generator-0.2.1/src/code_generator/gh/milestones.py +89 -0
- claude_code_generator-0.2.1/src/code_generator/git_ops.py +213 -0
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/src/code_generator/logging_setup.py +61 -0
- claude_code_generator-0.2.1/src/code_generator/orchestrator/_comments.py +72 -0
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/src/code_generator/orchestrator/cycle_loop.py +239 -123
- claude_code_generator-0.2.1/src/code_generator/orchestrator/phase0_complexity.py +315 -0
- claude_code_generator-0.2.1/src/code_generator/orchestrator/phase1_plan.py +252 -0
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/src/code_generator/orchestrator/phase2_review.py +54 -35
- claude_code_generator-0.2.1/src/code_generator/orchestrator/phase3_4_implement.py +306 -0
- claude_code_generator-0.2.1/src/code_generator/orchestrator/phase5_closure.py +246 -0
- claude_code_generator-0.2.1/src/code_generator/orchestrator/phase6_test.py +117 -0
- claude_code_generator-0.2.1/src/code_generator/orchestrator/phase7_commit.py +336 -0
- claude_code_generator-0.2.1/src/code_generator/prompts/__init__.py +146 -0
- claude_code_generator-0.2.1/src/code_generator/prompts/prompt-optimize-requirements.md +70 -0
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/src/code_generator/prompts/prompt-phase-0-complexity.md +64 -4
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/src/code_generator/prompts/prompt-phase-1-planning.md +14 -5
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/src/code_generator/prompts/prompt-phase-2-issue-review.md +5 -1
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/src/code_generator/prompts/prompt-phase-3-implementation.md +8 -4
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/src/code_generator/prompts/prompt-phase-5-final-review.md +25 -1
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/src/code_generator/prompts/prompt-phase-7-commit.md +53 -6
- claude_code_generator-0.2.1/src/code_generator/requirements_structure.py +78 -0
- claude_code_generator-0.2.1/src/code_generator/runner/__init__.py +52 -0
- claude_code_generator-0.2.1/src/code_generator/runner/message_parsing.py +162 -0
- claude_code_generator-0.2.1/src/code_generator/runner/options.py +41 -0
- claude_code_generator-0.2.1/src/code_generator/runner/protocol.py +60 -0
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/src/code_generator/runner/rate_limit.py +70 -6
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/src/code_generator/runner/retry.py +5 -9
- claude_code_generator-0.2.1/src/code_generator/runner/sdk_runner.py +211 -0
- claude_code_generator-0.2.1/src/code_generator/runner/subprocess_runner.py +334 -0
- claude_code_generator-0.2.1/src/code_generator/runner/types.py +166 -0
- claude_code_generator-0.2.1/src/code_generator/runner/utils.py +16 -0
- claude_code_generator-0.2.1/src/code_generator/state.py +364 -0
- claude_code_generator-0.2.1/tests/test_comments.py +342 -0
- claude_code_generator-0.2.1/tests/test_commit_message.py +138 -0
- claude_code_generator-0.2.1/tests/test_cycle_loop.py +1476 -0
- claude_code_generator-0.2.1/tests/test_cycle_loop_multicycle.py +903 -0
- claude_code_generator-0.2.1/tests/test_delta_planning.py +493 -0
- claude_code_generator-0.2.1/tests/test_detect.py +259 -0
- claude_code_generator-0.2.1/tests/test_effort.py +274 -0
- claude_code_generator-0.2.1/tests/test_generate.py +419 -0
- claude_code_generator-0.2.1/tests/test_generate_resume.py +1339 -0
- claude_code_generator-0.2.1/tests/test_gh.py +347 -0
- claude_code_generator-0.2.1/tests/test_gh_labels.py +150 -0
- claude_code_generator-0.2.1/tests/test_gh_milestones.py +158 -0
- claude_code_generator-0.2.1/tests/test_gh_submodules.py +223 -0
- claude_code_generator-0.2.1/tests/test_git_ops.py +506 -0
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/tests/test_init.py +4 -12
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/tests/test_logging_setup.py +1 -3
- claude_code_generator-0.2.1/tests/test_message_parsing.py +432 -0
- claude_code_generator-0.2.1/tests/test_optimize.py +621 -0
- claude_code_generator-0.2.1/tests/test_options.py +95 -0
- claude_code_generator-0.2.1/tests/test_phase0.py +401 -0
- claude_code_generator-0.2.1/tests/test_phase1.py +687 -0
- claude_code_generator-0.2.1/tests/test_phase2.py +506 -0
- claude_code_generator-0.2.1/tests/test_phase3_4.py +1080 -0
- claude_code_generator-0.2.1/tests/test_phase5.py +787 -0
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/tests/test_phase6.py +95 -0
- claude_code_generator-0.2.1/tests/test_phase7.py +1036 -0
- claude_code_generator-0.2.1/tests/test_phase_token_logging.py +742 -0
- claude_code_generator-0.2.1/tests/test_prompts.py +433 -0
- claude_code_generator-0.2.1/tests/test_rate_limit.py +871 -0
- claude_code_generator-0.2.1/tests/test_requirements_structure.py +290 -0
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/tests/test_retry.py +75 -0
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/tests/test_review.py +3 -9
- claude_code_generator-0.2.1/tests/test_runner_protocol.py +208 -0
- claude_code_generator-0.2.1/tests/test_runner_protocol_annotations.py +214 -0
- claude_code_generator-0.2.1/tests/test_runner_types.py +311 -0
- claude_code_generator-0.2.1/tests/test_runner_utils.py +104 -0
- claude_code_generator-0.2.1/tests/test_sdk_runner.py +902 -0
- claude_code_generator-0.2.1/tests/test_state.py +1154 -0
- claude_code_generator-0.2.1/tests/test_status.py +541 -0
- claude_code_generator-0.2.1/tests/test_subprocess_runner.py +1147 -0
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/tests/test_version.py +11 -0
- claude_code_generator-0.1.0/src/code_generator/commands/generate.py +0 -252
- claude_code_generator-0.1.0/src/code_generator/commands/status.py +0 -83
- claude_code_generator-0.1.0/src/code_generator/gh.py +0 -331
- claude_code_generator-0.1.0/src/code_generator/orchestrator/phase0_complexity.py +0 -159
- claude_code_generator-0.1.0/src/code_generator/orchestrator/phase1_plan.py +0 -170
- claude_code_generator-0.1.0/src/code_generator/orchestrator/phase3_4_implement.py +0 -164
- claude_code_generator-0.1.0/src/code_generator/orchestrator/phase5_closure.py +0 -154
- claude_code_generator-0.1.0/src/code_generator/orchestrator/phase6_test.py +0 -98
- claude_code_generator-0.1.0/src/code_generator/orchestrator/phase7_commit.py +0 -167
- claude_code_generator-0.1.0/src/code_generator/prompts/__init__.py +0 -86
- claude_code_generator-0.1.0/src/code_generator/runner/__init__.py +0 -26
- claude_code_generator-0.1.0/src/code_generator/runner/sdk_runner.py +0 -267
- claude_code_generator-0.1.0/src/code_generator/runner/subprocess_runner.py +0 -200
- claude_code_generator-0.1.0/src/code_generator/state.py +0 -178
- claude_code_generator-0.1.0/tests/test_cycle_loop.py +0 -573
- claude_code_generator-0.1.0/tests/test_generate.py +0 -180
- claude_code_generator-0.1.0/tests/test_generate_resume.py +0 -436
- claude_code_generator-0.1.0/tests/test_gh.py +0 -365
- claude_code_generator-0.1.0/tests/test_phase0.py +0 -175
- claude_code_generator-0.1.0/tests/test_phase1.py +0 -223
- claude_code_generator-0.1.0/tests/test_phase2.py +0 -224
- claude_code_generator-0.1.0/tests/test_phase3_4.py +0 -229
- claude_code_generator-0.1.0/tests/test_phase5.py +0 -200
- claude_code_generator-0.1.0/tests/test_phase7.py +0 -257
- claude_code_generator-0.1.0/tests/test_prompts.py +0 -185
- claude_code_generator-0.1.0/tests/test_rate_limit.py +0 -260
- claude_code_generator-0.1.0/tests/test_sdk_runner.py +0 -285
- claude_code_generator-0.1.0/tests/test_state.py +0 -224
- claude_code_generator-0.1.0/tests/test_status.py +0 -106
- claude_code_generator-0.1.0/tests/test_subprocess_runner.py +0 -213
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/LICENSE +0 -0
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/setup.cfg +0 -0
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/src/claude_code_generator.egg-info/dependency_links.txt +0 -0
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/src/claude_code_generator.egg-info/entry_points.txt +0 -0
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/src/claude_code_generator.egg-info/requires.txt +0 -0
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/src/claude_code_generator.egg-info/top_level.txt +0 -0
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/src/code_generator/agents.py +0 -0
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/src/code_generator/commands/__init__.py +0 -0
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/src/code_generator/env.py +0 -0
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/src/code_generator/orchestrator/__init__.py +0 -0
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/src/code_generator/prompts/prompt-phase-6-test.md +0 -0
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/src/code_generator/prompts/prompt-review.md +0 -0
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/src/code_generator/templates/__init__.py +0 -0
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/src/code_generator/templates/angular.md +0 -0
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/src/code_generator/templates/base.md +0 -0
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/src/code_generator/templates/fastapi.md +0 -0
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/src/code_generator/templates/finance.md +0 -0
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/src/code_generator/templates/fullstack.md +0 -0
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/src/code_generator/templates/nestjs.md +0 -0
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/src/code_generator/templates/python-cli.md +0 -0
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/tests/test_agents.py +0 -0
- {claude_code_generator-0.1.0 → claude_code_generator-0.2.1}/tests/test_env.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: claude-code-generator
|
|
3
|
-
Version: 0.1
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Orchestrator CLI that drives Claude Code end-to-end to generate whole projects from a requirements.md file.
|
|
5
5
|
Author: Silvio Baratto
|
|
6
6
|
License: MIT
|
|
@@ -31,7 +31,7 @@ Dynamic: license-file
|
|
|
31
31
|
|
|
32
32
|
# code-generator
|
|
33
33
|
|
|
34
|
-
A Python CLI that orchestrates Claude Code end-to-end to generate a whole project from a `requirements.md` file.
|
|
34
|
+
A Python CLI that orchestrates Claude Code end-to-end to generate a whole project from a `requirements.md` file. Five commands — `init`, `optimize`, `generate`, `review`, `status`. Works for any project type: Python CLI, FastAPI, Angular, NestJS, full-stack, finance, BAML/LLM.
|
|
35
35
|
|
|
36
36
|
> **Max subscription only.** This tool uses **exclusively** the Claude Max subscription. It strips every environment variable that could route a call through the API and aborts on startup if any are still present. There is no path to API credit billing — see [Safety constraints](#safety-constraints) below.
|
|
37
37
|
|
|
@@ -68,6 +68,20 @@ code-generator init --template fastapi
|
|
|
68
68
|
$EDITOR .code-generator/requirements.md
|
|
69
69
|
```
|
|
70
70
|
|
|
71
|
+
### `code-generator optimize [--dry-run] [--force]`
|
|
72
|
+
|
|
73
|
+
Pre-flight rewrite of `.code-generator/requirements.md` into the canonical structure the orchestrator expects: `# Title` → `## Description` → `## Tech Stack` → `## Goals` → `## Scope` (numbered `### N.` subsections with per-section `Acceptance criteria` checklists) → `## Non-goals` → `## Constraints` → `## Global acceptance criteria`.
|
|
74
|
+
|
|
75
|
+
Runs a single Opus 4.6 session with a dedicated prompt, preserves the original intent verbatim when ambiguous (never invents new scope), and writes the rewrite back to disk atomically. The pre-optimize original is saved to `.code-generator/requirements.backup-<UTC-timestamp>.md` so you can always `diff` and recover. The command is stateless — it never reads or writes `state.json` and never calls `gh`.
|
|
76
|
+
|
|
77
|
+
Short-circuits and exits 0 if the file is already canonical. Use `--force` to re-optimize anyway. Use `--dry-run` to print the proposed rewrite to stdout without touching the file or creating a backup.
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
code-generator optimize --dry-run # preview
|
|
81
|
+
code-generator optimize # commit the rewrite
|
|
82
|
+
code-generator generate # then run the pipeline
|
|
83
|
+
```
|
|
84
|
+
|
|
71
85
|
### `code-generator generate [flags]`
|
|
72
86
|
|
|
73
87
|
Read `.code-generator/requirements.md` and orchestrate Claude Code through the 0→7 phase pipeline:
|
|
@@ -80,7 +94,9 @@ Read `.code-generator/requirements.md` and orchestrate Claude Code through the 0
|
|
|
80
94
|
| 3-4 | Implementation, fresh SDK session per issue (TDD) | Sonnet 4.6 |
|
|
81
95
|
| 5 | Closure + cross-module review | Opus 4.6 |
|
|
82
96
|
| 6 | Test suite, max 3 retries on failure | Sonnet 4.6 |
|
|
83
|
-
| 7 | Commit message + git add/commit/push |
|
|
97
|
+
| 7 | Commit message + git add/commit/push | Opus 4.6 |
|
|
98
|
+
|
|
99
|
+
Every phase logs a completion summary with token counts (`in`, `cache_read`, `cache_write`, `out`) and persists them to `state.json`.
|
|
84
100
|
|
|
85
101
|
Flags:
|
|
86
102
|
|
|
@@ -102,7 +118,7 @@ Run a standalone Opus 4.6 review of the current codebase against the design prin
|
|
|
102
118
|
|
|
103
119
|
### `code-generator status`
|
|
104
120
|
|
|
105
|
-
Print a Rich table with the current mode, current cycle, current phase, open/closed issue counts, the rate-limit pause state (with minutes remaining if paused), and
|
|
121
|
+
Print a Rich table with the current mode, current cycle, current phase, open/closed issue counts, the rate-limit pause state (with minutes remaining if paused), per-cycle token consumption columns (`in | cache_read | cache_write | out`), wall-clock elapsed time, and any `last_error` highlighted in red.
|
|
106
122
|
|
|
107
123
|
## Safety constraints
|
|
108
124
|
|
|
@@ -115,7 +131,7 @@ The tool enforces eight non-negotiables (see `CLAUDE.md` for the full list):
|
|
|
115
131
|
5. **Wait-and-resume rate-limit handling.** Rate limits are not retried with exponential backoff — the tool sleeps until `resets_at + 60s` and resumes the same session. Backoff (10→20→40→80→120s) only applies to non-rate-limit transient errors.
|
|
116
132
|
6. **Fresh SDK session per issue.** The implementation phase never reuses conversational context across issues — each issue is a `/clear`-equivalent fresh session.
|
|
117
133
|
7. **Atomic state writes.** `.code-generator/state.json` is updated via `tmp → os.replace(tmp, STATE)` so a crash mid-write cannot corrupt it.
|
|
118
|
-
8. **Fixed model per phase.** Opus 4.6 for phases 0/1/2/5; Sonnet 4.6 for phases 3/4/6
|
|
134
|
+
8. **Fixed model per phase.** Opus 4.6 for phases 0/1/2/5/7; Sonnet 4.6 for phases 3/4/6.
|
|
119
135
|
|
|
120
136
|
## Troubleshooting
|
|
121
137
|
|
|
@@ -151,9 +167,9 @@ src/code_generator/
|
|
|
151
167
|
│ ├── phase3_4_implement.py # TDD loop, fresh session per issue
|
|
152
168
|
│ ├── phase5_closure.py # closure + fix-issue feedback loop
|
|
153
169
|
│ ├── phase6_test.py # test runner, max 3 retries
|
|
154
|
-
│ ├── phase7_commit.py #
|
|
170
|
+
│ ├── phase7_commit.py # Opus commit message + push with rebase retry
|
|
155
171
|
│ └── cycle_loop.py # multi-cycle driver
|
|
156
|
-
└── commands/ # init, status, generate, review (Typer commands)
|
|
172
|
+
└── commands/ # init, optimize, status, generate, review (Typer commands)
|
|
157
173
|
```
|
|
158
174
|
|
|
159
175
|
## Development
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# code-generator
|
|
2
2
|
|
|
3
|
-
A Python CLI that orchestrates Claude Code end-to-end to generate a whole project from a `requirements.md` file.
|
|
3
|
+
A Python CLI that orchestrates Claude Code end-to-end to generate a whole project from a `requirements.md` file. Five commands — `init`, `optimize`, `generate`, `review`, `status`. Works for any project type: Python CLI, FastAPI, Angular, NestJS, full-stack, finance, BAML/LLM.
|
|
4
4
|
|
|
5
5
|
> **Max subscription only.** This tool uses **exclusively** the Claude Max subscription. It strips every environment variable that could route a call through the API and aborts on startup if any are still present. There is no path to API credit billing — see [Safety constraints](#safety-constraints) below.
|
|
6
6
|
|
|
@@ -37,6 +37,20 @@ code-generator init --template fastapi
|
|
|
37
37
|
$EDITOR .code-generator/requirements.md
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
+
### `code-generator optimize [--dry-run] [--force]`
|
|
41
|
+
|
|
42
|
+
Pre-flight rewrite of `.code-generator/requirements.md` into the canonical structure the orchestrator expects: `# Title` → `## Description` → `## Tech Stack` → `## Goals` → `## Scope` (numbered `### N.` subsections with per-section `Acceptance criteria` checklists) → `## Non-goals` → `## Constraints` → `## Global acceptance criteria`.
|
|
43
|
+
|
|
44
|
+
Runs a single Opus 4.6 session with a dedicated prompt, preserves the original intent verbatim when ambiguous (never invents new scope), and writes the rewrite back to disk atomically. The pre-optimize original is saved to `.code-generator/requirements.backup-<UTC-timestamp>.md` so you can always `diff` and recover. The command is stateless — it never reads or writes `state.json` and never calls `gh`.
|
|
45
|
+
|
|
46
|
+
Short-circuits and exits 0 if the file is already canonical. Use `--force` to re-optimize anyway. Use `--dry-run` to print the proposed rewrite to stdout without touching the file or creating a backup.
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
code-generator optimize --dry-run # preview
|
|
50
|
+
code-generator optimize # commit the rewrite
|
|
51
|
+
code-generator generate # then run the pipeline
|
|
52
|
+
```
|
|
53
|
+
|
|
40
54
|
### `code-generator generate [flags]`
|
|
41
55
|
|
|
42
56
|
Read `.code-generator/requirements.md` and orchestrate Claude Code through the 0→7 phase pipeline:
|
|
@@ -49,7 +63,9 @@ Read `.code-generator/requirements.md` and orchestrate Claude Code through the 0
|
|
|
49
63
|
| 3-4 | Implementation, fresh SDK session per issue (TDD) | Sonnet 4.6 |
|
|
50
64
|
| 5 | Closure + cross-module review | Opus 4.6 |
|
|
51
65
|
| 6 | Test suite, max 3 retries on failure | Sonnet 4.6 |
|
|
52
|
-
| 7 | Commit message + git add/commit/push |
|
|
66
|
+
| 7 | Commit message + git add/commit/push | Opus 4.6 |
|
|
67
|
+
|
|
68
|
+
Every phase logs a completion summary with token counts (`in`, `cache_read`, `cache_write`, `out`) and persists them to `state.json`.
|
|
53
69
|
|
|
54
70
|
Flags:
|
|
55
71
|
|
|
@@ -71,7 +87,7 @@ Run a standalone Opus 4.6 review of the current codebase against the design prin
|
|
|
71
87
|
|
|
72
88
|
### `code-generator status`
|
|
73
89
|
|
|
74
|
-
Print a Rich table with the current mode, current cycle, current phase, open/closed issue counts, the rate-limit pause state (with minutes remaining if paused), and
|
|
90
|
+
Print a Rich table with the current mode, current cycle, current phase, open/closed issue counts, the rate-limit pause state (with minutes remaining if paused), per-cycle token consumption columns (`in | cache_read | cache_write | out`), wall-clock elapsed time, and any `last_error` highlighted in red.
|
|
75
91
|
|
|
76
92
|
## Safety constraints
|
|
77
93
|
|
|
@@ -84,7 +100,7 @@ The tool enforces eight non-negotiables (see `CLAUDE.md` for the full list):
|
|
|
84
100
|
5. **Wait-and-resume rate-limit handling.** Rate limits are not retried with exponential backoff — the tool sleeps until `resets_at + 60s` and resumes the same session. Backoff (10→20→40→80→120s) only applies to non-rate-limit transient errors.
|
|
85
101
|
6. **Fresh SDK session per issue.** The implementation phase never reuses conversational context across issues — each issue is a `/clear`-equivalent fresh session.
|
|
86
102
|
7. **Atomic state writes.** `.code-generator/state.json` is updated via `tmp → os.replace(tmp, STATE)` so a crash mid-write cannot corrupt it.
|
|
87
|
-
8. **Fixed model per phase.** Opus 4.6 for phases 0/1/2/5; Sonnet 4.6 for phases 3/4/6
|
|
103
|
+
8. **Fixed model per phase.** Opus 4.6 for phases 0/1/2/5/7; Sonnet 4.6 for phases 3/4/6.
|
|
88
104
|
|
|
89
105
|
## Troubleshooting
|
|
90
106
|
|
|
@@ -120,9 +136,9 @@ src/code_generator/
|
|
|
120
136
|
│ ├── phase3_4_implement.py # TDD loop, fresh session per issue
|
|
121
137
|
│ ├── phase5_closure.py # closure + fix-issue feedback loop
|
|
122
138
|
│ ├── phase6_test.py # test runner, max 3 retries
|
|
123
|
-
│ ├── phase7_commit.py #
|
|
139
|
+
│ ├── phase7_commit.py # Opus commit message + push with rebase retry
|
|
124
140
|
│ └── cycle_loop.py # multi-cycle driver
|
|
125
|
-
└── commands/ # init, status, generate, review (Typer commands)
|
|
141
|
+
└── commands/ # init, optimize, status, generate, review (Typer commands)
|
|
126
142
|
```
|
|
127
143
|
|
|
128
144
|
## Development
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "claude-code-generator"
|
|
7
|
-
version = "0.1
|
|
7
|
+
version = "0.2.1"
|
|
8
8
|
description = "Orchestrator CLI that drives Claude Code end-to-end to generate whole projects from a requirements.md file."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "MIT" }
|
|
@@ -69,3 +69,7 @@ ignore = []
|
|
|
69
69
|
[tool.pytest.ini_options]
|
|
70
70
|
testpaths = ["tests"]
|
|
71
71
|
asyncio_mode = "auto"
|
|
72
|
+
|
|
73
|
+
[tool.pyright]
|
|
74
|
+
# Test mocks intentionally use unused parameters to match the production interface signature.
|
|
75
|
+
reportUnusedParameter = "none"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: claude-code-generator
|
|
3
|
-
Version: 0.1
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Orchestrator CLI that drives Claude Code end-to-end to generate whole projects from a requirements.md file.
|
|
5
5
|
Author: Silvio Baratto
|
|
6
6
|
License: MIT
|
|
@@ -31,7 +31,7 @@ Dynamic: license-file
|
|
|
31
31
|
|
|
32
32
|
# code-generator
|
|
33
33
|
|
|
34
|
-
A Python CLI that orchestrates Claude Code end-to-end to generate a whole project from a `requirements.md` file.
|
|
34
|
+
A Python CLI that orchestrates Claude Code end-to-end to generate a whole project from a `requirements.md` file. Five commands — `init`, `optimize`, `generate`, `review`, `status`. Works for any project type: Python CLI, FastAPI, Angular, NestJS, full-stack, finance, BAML/LLM.
|
|
35
35
|
|
|
36
36
|
> **Max subscription only.** This tool uses **exclusively** the Claude Max subscription. It strips every environment variable that could route a call through the API and aborts on startup if any are still present. There is no path to API credit billing — see [Safety constraints](#safety-constraints) below.
|
|
37
37
|
|
|
@@ -68,6 +68,20 @@ code-generator init --template fastapi
|
|
|
68
68
|
$EDITOR .code-generator/requirements.md
|
|
69
69
|
```
|
|
70
70
|
|
|
71
|
+
### `code-generator optimize [--dry-run] [--force]`
|
|
72
|
+
|
|
73
|
+
Pre-flight rewrite of `.code-generator/requirements.md` into the canonical structure the orchestrator expects: `# Title` → `## Description` → `## Tech Stack` → `## Goals` → `## Scope` (numbered `### N.` subsections with per-section `Acceptance criteria` checklists) → `## Non-goals` → `## Constraints` → `## Global acceptance criteria`.
|
|
74
|
+
|
|
75
|
+
Runs a single Opus 4.6 session with a dedicated prompt, preserves the original intent verbatim when ambiguous (never invents new scope), and writes the rewrite back to disk atomically. The pre-optimize original is saved to `.code-generator/requirements.backup-<UTC-timestamp>.md` so you can always `diff` and recover. The command is stateless — it never reads or writes `state.json` and never calls `gh`.
|
|
76
|
+
|
|
77
|
+
Short-circuits and exits 0 if the file is already canonical. Use `--force` to re-optimize anyway. Use `--dry-run` to print the proposed rewrite to stdout without touching the file or creating a backup.
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
code-generator optimize --dry-run # preview
|
|
81
|
+
code-generator optimize # commit the rewrite
|
|
82
|
+
code-generator generate # then run the pipeline
|
|
83
|
+
```
|
|
84
|
+
|
|
71
85
|
### `code-generator generate [flags]`
|
|
72
86
|
|
|
73
87
|
Read `.code-generator/requirements.md` and orchestrate Claude Code through the 0→7 phase pipeline:
|
|
@@ -80,7 +94,9 @@ Read `.code-generator/requirements.md` and orchestrate Claude Code through the 0
|
|
|
80
94
|
| 3-4 | Implementation, fresh SDK session per issue (TDD) | Sonnet 4.6 |
|
|
81
95
|
| 5 | Closure + cross-module review | Opus 4.6 |
|
|
82
96
|
| 6 | Test suite, max 3 retries on failure | Sonnet 4.6 |
|
|
83
|
-
| 7 | Commit message + git add/commit/push |
|
|
97
|
+
| 7 | Commit message + git add/commit/push | Opus 4.6 |
|
|
98
|
+
|
|
99
|
+
Every phase logs a completion summary with token counts (`in`, `cache_read`, `cache_write`, `out`) and persists them to `state.json`.
|
|
84
100
|
|
|
85
101
|
Flags:
|
|
86
102
|
|
|
@@ -102,7 +118,7 @@ Run a standalone Opus 4.6 review of the current codebase against the design prin
|
|
|
102
118
|
|
|
103
119
|
### `code-generator status`
|
|
104
120
|
|
|
105
|
-
Print a Rich table with the current mode, current cycle, current phase, open/closed issue counts, the rate-limit pause state (with minutes remaining if paused), and
|
|
121
|
+
Print a Rich table with the current mode, current cycle, current phase, open/closed issue counts, the rate-limit pause state (with minutes remaining if paused), per-cycle token consumption columns (`in | cache_read | cache_write | out`), wall-clock elapsed time, and any `last_error` highlighted in red.
|
|
106
122
|
|
|
107
123
|
## Safety constraints
|
|
108
124
|
|
|
@@ -115,7 +131,7 @@ The tool enforces eight non-negotiables (see `CLAUDE.md` for the full list):
|
|
|
115
131
|
5. **Wait-and-resume rate-limit handling.** Rate limits are not retried with exponential backoff — the tool sleeps until `resets_at + 60s` and resumes the same session. Backoff (10→20→40→80→120s) only applies to non-rate-limit transient errors.
|
|
116
132
|
6. **Fresh SDK session per issue.** The implementation phase never reuses conversational context across issues — each issue is a `/clear`-equivalent fresh session.
|
|
117
133
|
7. **Atomic state writes.** `.code-generator/state.json` is updated via `tmp → os.replace(tmp, STATE)` so a crash mid-write cannot corrupt it.
|
|
118
|
-
8. **Fixed model per phase.** Opus 4.6 for phases 0/1/2/5; Sonnet 4.6 for phases 3/4/6
|
|
134
|
+
8. **Fixed model per phase.** Opus 4.6 for phases 0/1/2/5/7; Sonnet 4.6 for phases 3/4/6.
|
|
119
135
|
|
|
120
136
|
## Troubleshooting
|
|
121
137
|
|
|
@@ -151,9 +167,9 @@ src/code_generator/
|
|
|
151
167
|
│ ├── phase3_4_implement.py # TDD loop, fresh session per issue
|
|
152
168
|
│ ├── phase5_closure.py # closure + fix-issue feedback loop
|
|
153
169
|
│ ├── phase6_test.py # test runner, max 3 retries
|
|
154
|
-
│ ├── phase7_commit.py #
|
|
170
|
+
│ ├── phase7_commit.py # Opus commit message + push with rebase retry
|
|
155
171
|
│ └── cycle_loop.py # multi-cycle driver
|
|
156
|
-
└── commands/ # init, status, generate, review (Typer commands)
|
|
172
|
+
└── commands/ # init, optimize, status, generate, review (Typer commands)
|
|
157
173
|
```
|
|
158
174
|
|
|
159
175
|
## Development
|
|
@@ -10,16 +10,28 @@ src/claude_code_generator.egg-info/top_level.txt
|
|
|
10
10
|
src/code_generator/__init__.py
|
|
11
11
|
src/code_generator/agents.py
|
|
12
12
|
src/code_generator/cli.py
|
|
13
|
+
src/code_generator/effort.py
|
|
13
14
|
src/code_generator/env.py
|
|
14
|
-
src/code_generator/
|
|
15
|
+
src/code_generator/git_ops.py
|
|
15
16
|
src/code_generator/logging_setup.py
|
|
17
|
+
src/code_generator/requirements_structure.py
|
|
16
18
|
src/code_generator/state.py
|
|
17
19
|
src/code_generator/commands/__init__.py
|
|
20
|
+
src/code_generator/commands/_detect.py
|
|
21
|
+
src/code_generator/commands/_dispatch.py
|
|
22
|
+
src/code_generator/commands/_resume.py
|
|
18
23
|
src/code_generator/commands/generate.py
|
|
19
24
|
src/code_generator/commands/init.py
|
|
25
|
+
src/code_generator/commands/optimize.py
|
|
20
26
|
src/code_generator/commands/review.py
|
|
21
27
|
src/code_generator/commands/status.py
|
|
28
|
+
src/code_generator/gh/__init__.py
|
|
29
|
+
src/code_generator/gh/core.py
|
|
30
|
+
src/code_generator/gh/issues.py
|
|
31
|
+
src/code_generator/gh/labels.py
|
|
32
|
+
src/code_generator/gh/milestones.py
|
|
22
33
|
src/code_generator/orchestrator/__init__.py
|
|
34
|
+
src/code_generator/orchestrator/_comments.py
|
|
23
35
|
src/code_generator/orchestrator/cycle_loop.py
|
|
24
36
|
src/code_generator/orchestrator/phase0_complexity.py
|
|
25
37
|
src/code_generator/orchestrator/phase1_plan.py
|
|
@@ -29,6 +41,7 @@ src/code_generator/orchestrator/phase5_closure.py
|
|
|
29
41
|
src/code_generator/orchestrator/phase6_test.py
|
|
30
42
|
src/code_generator/orchestrator/phase7_commit.py
|
|
31
43
|
src/code_generator/prompts/__init__.py
|
|
44
|
+
src/code_generator/prompts/prompt-optimize-requirements.md
|
|
32
45
|
src/code_generator/prompts/prompt-phase-0-complexity.md
|
|
33
46
|
src/code_generator/prompts/prompt-phase-1-planning.md
|
|
34
47
|
src/code_generator/prompts/prompt-phase-2-issue-review.md
|
|
@@ -38,10 +51,15 @@ src/code_generator/prompts/prompt-phase-6-test.md
|
|
|
38
51
|
src/code_generator/prompts/prompt-phase-7-commit.md
|
|
39
52
|
src/code_generator/prompts/prompt-review.md
|
|
40
53
|
src/code_generator/runner/__init__.py
|
|
54
|
+
src/code_generator/runner/message_parsing.py
|
|
55
|
+
src/code_generator/runner/options.py
|
|
56
|
+
src/code_generator/runner/protocol.py
|
|
41
57
|
src/code_generator/runner/rate_limit.py
|
|
42
58
|
src/code_generator/runner/retry.py
|
|
43
59
|
src/code_generator/runner/sdk_runner.py
|
|
44
60
|
src/code_generator/runner/subprocess_runner.py
|
|
61
|
+
src/code_generator/runner/types.py
|
|
62
|
+
src/code_generator/runner/utils.py
|
|
45
63
|
src/code_generator/templates/__init__.py
|
|
46
64
|
src/code_generator/templates/angular.md
|
|
47
65
|
src/code_generator/templates/base.md
|
|
@@ -51,13 +69,26 @@ src/code_generator/templates/fullstack.md
|
|
|
51
69
|
src/code_generator/templates/nestjs.md
|
|
52
70
|
src/code_generator/templates/python-cli.md
|
|
53
71
|
tests/test_agents.py
|
|
72
|
+
tests/test_comments.py
|
|
73
|
+
tests/test_commit_message.py
|
|
54
74
|
tests/test_cycle_loop.py
|
|
75
|
+
tests/test_cycle_loop_multicycle.py
|
|
76
|
+
tests/test_delta_planning.py
|
|
77
|
+
tests/test_detect.py
|
|
78
|
+
tests/test_effort.py
|
|
55
79
|
tests/test_env.py
|
|
56
80
|
tests/test_generate.py
|
|
57
81
|
tests/test_generate_resume.py
|
|
58
82
|
tests/test_gh.py
|
|
83
|
+
tests/test_gh_labels.py
|
|
84
|
+
tests/test_gh_milestones.py
|
|
85
|
+
tests/test_gh_submodules.py
|
|
86
|
+
tests/test_git_ops.py
|
|
59
87
|
tests/test_init.py
|
|
60
88
|
tests/test_logging_setup.py
|
|
89
|
+
tests/test_message_parsing.py
|
|
90
|
+
tests/test_optimize.py
|
|
91
|
+
tests/test_options.py
|
|
61
92
|
tests/test_phase0.py
|
|
62
93
|
tests/test_phase1.py
|
|
63
94
|
tests/test_phase2.py
|
|
@@ -65,10 +96,16 @@ tests/test_phase3_4.py
|
|
|
65
96
|
tests/test_phase5.py
|
|
66
97
|
tests/test_phase6.py
|
|
67
98
|
tests/test_phase7.py
|
|
99
|
+
tests/test_phase_token_logging.py
|
|
68
100
|
tests/test_prompts.py
|
|
69
101
|
tests/test_rate_limit.py
|
|
102
|
+
tests/test_requirements_structure.py
|
|
70
103
|
tests/test_retry.py
|
|
71
104
|
tests/test_review.py
|
|
105
|
+
tests/test_runner_protocol.py
|
|
106
|
+
tests/test_runner_protocol_annotations.py
|
|
107
|
+
tests/test_runner_types.py
|
|
108
|
+
tests/test_runner_utils.py
|
|
72
109
|
tests/test_sdk_runner.py
|
|
73
110
|
tests/test_state.py
|
|
74
111
|
tests/test_status.py
|
|
@@ -11,6 +11,7 @@ import typer
|
|
|
11
11
|
import code_generator
|
|
12
12
|
from code_generator.commands.generate import generate_command
|
|
13
13
|
from code_generator.commands.init import init_command
|
|
14
|
+
from code_generator.commands.optimize import optimize_command
|
|
14
15
|
from code_generator.commands.review import review_command
|
|
15
16
|
from code_generator.commands.status import status_command
|
|
16
17
|
|
|
@@ -46,4 +47,5 @@ def root(
|
|
|
46
47
|
app.command(name="init")(init_command)
|
|
47
48
|
app.command(name="status")(status_command)
|
|
48
49
|
app.command(name="generate")(generate_command)
|
|
50
|
+
app.command(name="optimize")(optimize_command)
|
|
49
51
|
app.command(name="review")(review_command)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"""Re-run detection for the generate command.
|
|
2
|
+
|
|
3
|
+
Compares the current requirements.md hash against the stored hash in state to
|
|
4
|
+
decide the correct execution path on startup.
|
|
5
|
+
|
|
6
|
+
The sole exported function is a pure function (no I/O) so it is trivially
|
|
7
|
+
unit-testable.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from typing import TYPE_CHECKING, Literal
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from code_generator import state as state_module
|
|
16
|
+
|
|
17
|
+
RunMode = Literal["first-run", "resume", "no-op", "delta"]
|
|
18
|
+
|
|
19
|
+
__all__ = ["RunMode", "detect_run_mode"]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _run_is_complete(state: state_module.State) -> bool:
|
|
23
|
+
"""Return True when the generation run is fully complete.
|
|
24
|
+
|
|
25
|
+
Single mode: complete when phase == 7 (final commit phase).
|
|
26
|
+
Multi-cycle mode: complete when every cycle has status "completed"
|
|
27
|
+
and at least one cycle exists.
|
|
28
|
+
"""
|
|
29
|
+
if state.mode == "multi-cycle":
|
|
30
|
+
return len(state.cycles) > 0 and all(c.status == "completed" for c in state.cycles)
|
|
31
|
+
return state.phase == 7
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def detect_run_mode(state: state_module.State, current_hash: str) -> RunMode:
|
|
35
|
+
"""Determine how the generate command should proceed given existing state.
|
|
36
|
+
|
|
37
|
+
This is a pure function: it reads ``state`` and ``current_hash`` and
|
|
38
|
+
returns a decision literal. It never performs I/O.
|
|
39
|
+
|
|
40
|
+
Decision rules (evaluated in order):
|
|
41
|
+
1. No stored hash → ``"first-run"`` (treat as a brand-new run)
|
|
42
|
+
2. Hashes differ → ``"delta"`` (requirements changed)
|
|
43
|
+
3. Run complete → ``"no-op"`` (nothing left to do)
|
|
44
|
+
4. Otherwise → ``"resume"`` (same requirements, incomplete run)
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
state: Loaded root state (may have requirements_hash=None for old runs).
|
|
48
|
+
current_hash: SHA-256 hex digest of the current requirements.md.
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
One of ``"first-run"``, ``"resume"``, ``"no-op"``, or ``"delta"``.
|
|
52
|
+
"""
|
|
53
|
+
if state.requirements_hash is None:
|
|
54
|
+
return "first-run"
|
|
55
|
+
if state.requirements_hash != current_hash:
|
|
56
|
+
return "delta"
|
|
57
|
+
if _run_is_complete(state):
|
|
58
|
+
return "no-op"
|
|
59
|
+
return "resume"
|