claude-code-generator 0.2.4__tar.gz → 0.4.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.2.4/src/claude_code_generator.egg-info → claude_code_generator-0.4.1}/PKG-INFO +31 -11
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/README.md +20 -9
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/pyproject.toml +23 -2
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1/src/claude_code_generator.egg-info}/PKG-INFO +31 -11
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/claude_code_generator.egg-info/SOURCES.txt +54 -0
- claude_code_generator-0.4.1/src/claude_code_generator.egg-info/requires.txt +21 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/__init__.py +1 -1
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/cli.py +2 -0
- claude_code_generator-0.4.1/src/code_generator/commands/_bench_io.py +39 -0
- claude_code_generator-0.4.1/src/code_generator/commands/_crash_recovery.py +52 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/commands/_dispatch.py +102 -1
- claude_code_generator-0.4.1/src/code_generator/commands/_validators.py +27 -0
- claude_code_generator-0.4.1/src/code_generator/commands/bench.py +271 -0
- claude_code_generator-0.4.1/src/code_generator/commands/bench_compare.py +249 -0
- claude_code_generator-0.4.1/src/code_generator/commands/bench_export.py +207 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/commands/generate.py +113 -1
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/commands/optimize.py +22 -6
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/commands/review.py +26 -7
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/commands/status.py +111 -41
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/effort.py +25 -16
- claude_code_generator-0.4.1/src/code_generator/env.py +148 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/gh/__init__.py +1 -3
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/gh/core.py +36 -23
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/gh/issues.py +40 -7
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/gh/labels.py +55 -19
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/gh/milestones.py +20 -10
- claude_code_generator-0.4.1/src/code_generator/memory.py +175 -0
- claude_code_generator-0.4.1/src/code_generator/orchestrator/_client_lifecycle.py +163 -0
- claude_code_generator-0.4.1/src/code_generator/orchestrator/_comments.py +120 -0
- claude_code_generator-0.4.1/src/code_generator/orchestrator/_memory_writers.py +126 -0
- claude_code_generator-0.4.1/src/code_generator/orchestrator/_phase5_precommit.py +165 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/orchestrator/cycle_loop.py +176 -23
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/orchestrator/phase0_complexity.py +19 -9
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/orchestrator/phase1_plan.py +43 -16
- claude_code_generator-0.4.1/src/code_generator/orchestrator/phase2_review.py +657 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/orchestrator/phase3_4_implement.py +112 -23
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/orchestrator/phase5_closure.py +176 -23
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/orchestrator/phase6_test.py +8 -2
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/orchestrator/phase7_commit.py +22 -23
- claude_code_generator-0.4.1/src/code_generator/preflight.py +259 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/prompts/__init__.py +45 -5
- claude_code_generator-0.4.1/src/code_generator/prompts/hashes.py +34 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/prompts/prompt-optimize-requirements.md +1 -1
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/prompts/prompt-phase-0-complexity.md +9 -1
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/prompts/prompt-phase-1-planning.md +29 -20
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/prompts/prompt-phase-2-issue-review.md +40 -18
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/prompts/prompt-phase-3-implementation.md +36 -18
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/prompts/prompt-phase-5-final-review.md +51 -36
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/prompts/prompt-phase-6-test.md +8 -4
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/prompts/prompt-phase-7-commit.md +25 -27
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/prompts/prompt-review.md +10 -6
- claude_code_generator-0.4.1/src/code_generator/repo_info.py +161 -0
- claude_code_generator-0.4.1/src/code_generator/repomap.py +233 -0
- claude_code_generator-0.4.1/src/code_generator/runner/_telemetry.py +47 -0
- claude_code_generator-0.4.1/src/code_generator/runner/batch.py +201 -0
- claude_code_generator-0.4.1/src/code_generator/runner/fake_runner.py +66 -0
- claude_code_generator-0.4.1/src/code_generator/runner/mcp.py +125 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/runner/message_parsing.py +32 -3
- claude_code_generator-0.4.1/src/code_generator/runner/options.py +603 -0
- claude_code_generator-0.4.1/src/code_generator/runner/sdk_runner.py +322 -0
- claude_code_generator-0.4.1/src/code_generator/runner/soft_reset.py +103 -0
- claude_code_generator-0.4.1/src/code_generator/runner/state_guard.py +80 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/runner/subprocess_runner.py +21 -4
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/runner/types.py +17 -4
- claude_code_generator-0.4.1/src/code_generator/state.py +777 -0
- claude_code_generator-0.4.1/src/code_generator/state_retention.py +102 -0
- claude_code_generator-0.4.1/tests/test_bench.py +331 -0
- claude_code_generator-0.4.1/tests/test_bench_compare.py +312 -0
- claude_code_generator-0.4.1/tests/test_bench_export.py +388 -0
- claude_code_generator-0.4.1/tests/test_bench_fixture.py +144 -0
- claude_code_generator-0.4.1/tests/test_bench_regression.py +114 -0
- claude_code_generator-0.4.1/tests/test_changelog.py +114 -0
- claude_code_generator-0.4.1/tests/test_claude_md.py +33 -0
- claude_code_generator-0.4.1/tests/test_client_lifecycle.py +581 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_comments.py +17 -9
- claude_code_generator-0.4.1/tests/test_crash_recovery.py +490 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_cycle_loop.py +131 -9
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_cycle_loop_multicycle.py +12 -12
- claude_code_generator-0.4.1/tests/test_dependencies.py +23 -0
- claude_code_generator-0.4.1/tests/test_docs_no_default_max_turns.py +139 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_effort.py +22 -9
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_env.py +65 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_generate.py +157 -11
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_generate_resume.py +23 -1
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_gh.py +23 -45
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_gh_labels.py +14 -11
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_gh_milestones.py +51 -63
- claude_code_generator-0.4.1/tests/test_gh_repo_threading.py +385 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_gh_submodules.py +21 -8
- claude_code_generator-0.4.1/tests/test_max_turns_cli_flag.py +420 -0
- claude_code_generator-0.4.1/tests/test_mcp.py +235 -0
- claude_code_generator-0.4.1/tests/test_memory.py +238 -0
- claude_code_generator-0.4.1/tests/test_memory_writers.py +334 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_message_parsing.py +53 -0
- claude_code_generator-0.4.1/tests/test_no_max_turns_in_call_sites.py +103 -0
- claude_code_generator-0.4.1/tests/test_no_max_turns_literal.py +87 -0
- claude_code_generator-0.4.1/tests/test_non_goals_grep_guard.py +302 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_optimize.py +21 -8
- claude_code_generator-0.4.1/tests/test_options.py +1174 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_phase0.py +1 -1
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_phase1.py +23 -3
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_phase2.py +401 -6
- claude_code_generator-0.4.1/tests/test_phase2_batch.py +602 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_phase3_4.py +742 -17
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_phase5.py +421 -14
- claude_code_generator-0.4.1/tests/test_phase5_precommit.py +409 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_phase7.py +95 -11
- claude_code_generator-0.4.1/tests/test_phase_mcp_regression.py +193 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_phase_token_logging.py +26 -1
- claude_code_generator-0.4.1/tests/test_preflight.py +443 -0
- claude_code_generator-0.4.1/tests/test_prompt_drift.py +254 -0
- claude_code_generator-0.4.1/tests/test_prompt_prefix_snapshots.py +144 -0
- claude_code_generator-0.4.1/tests/test_prompt_prefix_stability.py +239 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_prompts.py +234 -7
- claude_code_generator-0.4.1/tests/test_repo_info.py +249 -0
- claude_code_generator-0.4.1/tests/test_repomap.py +110 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_runner_types.py +51 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_sdk_runner.py +78 -2
- claude_code_generator-0.4.1/tests/test_sdk_runner_shared.py +398 -0
- claude_code_generator-0.4.1/tests/test_session_mode.py +294 -0
- claude_code_generator-0.4.1/tests/test_state.py +2610 -0
- claude_code_generator-0.4.1/tests/test_state_guard.py +100 -0
- claude_code_generator-0.4.1/tests/test_state_retention.py +297 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_status.py +276 -1
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_subprocess_runner.py +240 -2
- claude_code_generator-0.4.1/tests/test_telemetry.py +193 -0
- claude_code_generator-0.2.4/src/claude_code_generator.egg-info/requires.txt +0 -8
- claude_code_generator-0.2.4/src/code_generator/env.py +0 -55
- claude_code_generator-0.2.4/src/code_generator/orchestrator/_comments.py +0 -72
- claude_code_generator-0.2.4/src/code_generator/orchestrator/phase2_review.py +0 -158
- claude_code_generator-0.2.4/src/code_generator/runner/options.py +0 -41
- claude_code_generator-0.2.4/src/code_generator/runner/sdk_runner.py +0 -211
- claude_code_generator-0.2.4/src/code_generator/state.py +0 -366
- claude_code_generator-0.2.4/tests/test_options.py +0 -95
- claude_code_generator-0.2.4/tests/test_state.py +0 -1154
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/LICENSE +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/setup.cfg +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/claude_code_generator.egg-info/dependency_links.txt +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/claude_code_generator.egg-info/entry_points.txt +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/claude_code_generator.egg-info/top_level.txt +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/agents.py +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/commands/__init__.py +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/commands/_detect.py +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/commands/_resume.py +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/commands/init.py +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/git_ops.py +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/logging_setup.py +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/orchestrator/__init__.py +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/requirements_structure.py +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/runner/__init__.py +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/runner/protocol.py +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/runner/rate_limit.py +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/runner/retry.py +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/runner/utils.py +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/templates/__init__.py +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/templates/angular.md +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/templates/base.md +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/templates/fastapi.md +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/templates/finance.md +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/templates/fullstack.md +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/templates/nestjs.md +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/src/code_generator/templates/python-cli.md +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_agents.py +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_commit_message.py +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_delta_planning.py +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_detect.py +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_git_ops.py +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_init.py +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_logging_setup.py +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_phase6.py +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_rate_limit.py +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_requirements_structure.py +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_retry.py +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_review.py +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_runner_protocol.py +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_runner_protocol_annotations.py +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_runner_utils.py +0 -0
- {claude_code_generator-0.2.4 → claude_code_generator-0.4.1}/tests/test_version.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: claude-code-generator
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.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
|
|
@@ -20,13 +20,22 @@ Classifier: Topic :: Software Development :: Code Generators
|
|
|
20
20
|
Requires-Python: >=3.11
|
|
21
21
|
Description-Content-Type: text/markdown
|
|
22
22
|
License-File: LICENSE
|
|
23
|
-
Requires-Dist: claude-agent-sdk
|
|
23
|
+
Requires-Dist: claude-agent-sdk<0.2.0,>=0.1.61
|
|
24
24
|
Requires-Dist: typer
|
|
25
25
|
Requires-Dist: rich
|
|
26
26
|
Provides-Extra: dev
|
|
27
27
|
Requires-Dist: pytest; extra == "dev"
|
|
28
28
|
Requires-Dist: pytest-asyncio; extra == "dev"
|
|
29
29
|
Requires-Dist: ruff; extra == "dev"
|
|
30
|
+
Provides-Extra: repomap
|
|
31
|
+
Requires-Dist: tree-sitter<0.22,>=0.21; extra == "repomap"
|
|
32
|
+
Requires-Dist: tree-sitter-languages>=1.10; extra == "repomap"
|
|
33
|
+
Provides-Extra: mcp
|
|
34
|
+
Requires-Dist: mcp<2.0,>=1.0; extra == "mcp"
|
|
35
|
+
Provides-Extra: batch
|
|
36
|
+
Requires-Dist: anthropic>=0.35; extra == "batch"
|
|
37
|
+
Provides-Extra: all
|
|
38
|
+
Requires-Dist: claude-code-generator[batch,mcp,repomap]; extra == "all"
|
|
30
39
|
Dynamic: license-file
|
|
31
40
|
|
|
32
41
|
# code-generator
|
|
@@ -72,7 +81,7 @@ $EDITOR .code-generator/requirements.md
|
|
|
72
81
|
|
|
73
82
|
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
83
|
|
|
75
|
-
Runs a single Opus 4.
|
|
84
|
+
Runs a single Opus 4.7 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
85
|
|
|
77
86
|
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
87
|
|
|
@@ -88,13 +97,13 @@ Read `.code-generator/requirements.md` and orchestrate Claude Code through the 0
|
|
|
88
97
|
|
|
89
98
|
| Phase | Action | Model |
|
|
90
99
|
|---|---|---|
|
|
91
|
-
| 0 | Complexity analysis (single vs multi-cycle) | Opus 4.
|
|
92
|
-
| 1 | Planning — creates GitHub issues + milestone | Opus 4.
|
|
93
|
-
| 2 | Per-issue review | Opus 4.
|
|
100
|
+
| 0 | Complexity analysis (single vs multi-cycle) | Opus 4.7 |
|
|
101
|
+
| 1 | Planning — creates GitHub issues + milestone | Opus 4.7 |
|
|
102
|
+
| 2 | Per-issue review | Opus 4.7 |
|
|
94
103
|
| 3-4 | Implementation, fresh SDK session per issue (TDD) | Sonnet 4.6 |
|
|
95
|
-
| 5 | Closure + cross-module review | Opus 4.
|
|
104
|
+
| 5 | Closure + cross-module review | Opus 4.7 |
|
|
96
105
|
| 6 | Test suite, max 3 retries on failure | Sonnet 4.6 |
|
|
97
|
-
| 7 | Commit message + git add/commit/push | Opus 4.
|
|
106
|
+
| 7 | Commit message + git add/commit/push | Opus 4.7 |
|
|
98
107
|
|
|
99
108
|
Every phase logs a completion summary with token counts (`in`, `cache_read`, `cache_write`, `out`) and persists them to `state.json`.
|
|
100
109
|
|
|
@@ -107,6 +116,11 @@ Flags:
|
|
|
107
116
|
| `--continue` | Resume from the last completed phase (reads `state.json`) | false |
|
|
108
117
|
| `--mode auto\|single\|multi-cycle` | Force a mode (default `auto` runs Phase 0 first) | auto |
|
|
109
118
|
| `--cycle N` | Resume from cycle N (multi-cycle only) | — |
|
|
119
|
+
| `--max-turns N` | Opt-in per-session turn cap for debugging or strict cost control (positive integer); omit for no cap | — |
|
|
120
|
+
|
|
121
|
+
#### Turn budgets
|
|
122
|
+
|
|
123
|
+
No per-session turn budget is set by default. Sessions terminate via `end_turn` on the model side; the real safety nets are rate-limit handling, overage abort (non-negotiable #4), and task budgets — **not** a guessed integer. `--max-turns N` exists on `generate`, `optimize`, and `review` as an opt-in for debugging or strict cost control; it is not for production.
|
|
110
124
|
|
|
111
125
|
In multi-cycle mode each cycle is a GitHub Milestone and produces a committable, working increment. Each cycle starts a fresh SDK session and re-reads the committed codebase, so the model never relies on stale conversational context.
|
|
112
126
|
|
|
@@ -114,7 +128,7 @@ If the Max subscription hits a rate limit, the tool **pauses** — it persists t
|
|
|
114
128
|
|
|
115
129
|
### `code-generator review [--create-issues] [--severity LEVEL]`
|
|
116
130
|
|
|
117
|
-
Run a standalone Opus 4.
|
|
131
|
+
Run a standalone Opus 4.7 review of the current codebase against the design principles in `requirements.md` §4 (SOLID, Clean Code, TDD, YAGNI/KISS/DRY). With `--create-issues`, every finding becomes a GitHub Issue.
|
|
118
132
|
|
|
119
133
|
### `code-generator status`
|
|
120
134
|
|
|
@@ -122,7 +136,7 @@ Print a Rich table with the current mode, current cycle, current phase, open/clo
|
|
|
122
136
|
|
|
123
137
|
## Safety constraints
|
|
124
138
|
|
|
125
|
-
The tool enforces
|
|
139
|
+
The tool enforces nine non-negotiables (see `CLAUDE.md` for the full list):
|
|
126
140
|
|
|
127
141
|
1. **Max subscription only, zero API credits.** Before any SDK or subprocess call, the tool strips `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, `ANTHROPIC_BEDROCK_API_KEY`, `ANTHROPIC_VERTEX_PROJECT_ID`, `CLAUDE_CODE_USE_BEDROCK`, `CLAUDE_CODE_USE_VERTEX` from the environment. A startup check refuses to run if any are present.
|
|
128
142
|
2. **Never `--bare`.** The CLI flag `--bare` skips OAuth and forces API credits — it is **never** passed by this tool. If Anthropic ever makes `--bare` the default for `claude -p`, pin the CLI version or pass the opposite flag explicitly.
|
|
@@ -131,7 +145,7 @@ The tool enforces eight non-negotiables (see `CLAUDE.md` for the full list):
|
|
|
131
145
|
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.
|
|
132
146
|
6. **Fresh SDK session per issue.** The implementation phase never reuses conversational context across issues — each issue is a `/clear`-equivalent fresh session.
|
|
133
147
|
7. **Atomic state writes.** `.code-generator/state.json` is updated via `tmp → os.replace(tmp, STATE)` so a crash mid-write cannot corrupt it.
|
|
134
|
-
8. **Fixed model per phase.** Opus 4.
|
|
148
|
+
8. **Fixed model per phase.** Opus 4.7 for phases 0/1/2/5/7; Sonnet 4.6 for phases 3/4/6.
|
|
135
149
|
|
|
136
150
|
## Troubleshooting
|
|
137
151
|
|
|
@@ -183,6 +197,12 @@ pytest -q
|
|
|
183
197
|
ruff check src tests
|
|
184
198
|
```
|
|
185
199
|
|
|
200
|
+
## Benchmarking
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
code-generator bench --fake --cycles 3 --output bench.json
|
|
204
|
+
```
|
|
205
|
+
|
|
186
206
|
## Reference
|
|
187
207
|
|
|
188
208
|
The full specification lives in [`requirements.md`](requirements.md). Each prompt file (`prompt-phase-*.md`, `prompt-review.md`) is loaded verbatim by the orchestrator with `{NAME}` placeholders substituted at runtime — edit the prompts there, not inline in Python.
|
|
@@ -41,7 +41,7 @@ $EDITOR .code-generator/requirements.md
|
|
|
41
41
|
|
|
42
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
43
|
|
|
44
|
-
Runs a single Opus 4.
|
|
44
|
+
Runs a single Opus 4.7 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
45
|
|
|
46
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
47
|
|
|
@@ -57,13 +57,13 @@ Read `.code-generator/requirements.md` and orchestrate Claude Code through the 0
|
|
|
57
57
|
|
|
58
58
|
| Phase | Action | Model |
|
|
59
59
|
|---|---|---|
|
|
60
|
-
| 0 | Complexity analysis (single vs multi-cycle) | Opus 4.
|
|
61
|
-
| 1 | Planning — creates GitHub issues + milestone | Opus 4.
|
|
62
|
-
| 2 | Per-issue review | Opus 4.
|
|
60
|
+
| 0 | Complexity analysis (single vs multi-cycle) | Opus 4.7 |
|
|
61
|
+
| 1 | Planning — creates GitHub issues + milestone | Opus 4.7 |
|
|
62
|
+
| 2 | Per-issue review | Opus 4.7 |
|
|
63
63
|
| 3-4 | Implementation, fresh SDK session per issue (TDD) | Sonnet 4.6 |
|
|
64
|
-
| 5 | Closure + cross-module review | Opus 4.
|
|
64
|
+
| 5 | Closure + cross-module review | Opus 4.7 |
|
|
65
65
|
| 6 | Test suite, max 3 retries on failure | Sonnet 4.6 |
|
|
66
|
-
| 7 | Commit message + git add/commit/push | Opus 4.
|
|
66
|
+
| 7 | Commit message + git add/commit/push | Opus 4.7 |
|
|
67
67
|
|
|
68
68
|
Every phase logs a completion summary with token counts (`in`, `cache_read`, `cache_write`, `out`) and persists them to `state.json`.
|
|
69
69
|
|
|
@@ -76,6 +76,11 @@ Flags:
|
|
|
76
76
|
| `--continue` | Resume from the last completed phase (reads `state.json`) | false |
|
|
77
77
|
| `--mode auto\|single\|multi-cycle` | Force a mode (default `auto` runs Phase 0 first) | auto |
|
|
78
78
|
| `--cycle N` | Resume from cycle N (multi-cycle only) | — |
|
|
79
|
+
| `--max-turns N` | Opt-in per-session turn cap for debugging or strict cost control (positive integer); omit for no cap | — |
|
|
80
|
+
|
|
81
|
+
#### Turn budgets
|
|
82
|
+
|
|
83
|
+
No per-session turn budget is set by default. Sessions terminate via `end_turn` on the model side; the real safety nets are rate-limit handling, overage abort (non-negotiable #4), and task budgets — **not** a guessed integer. `--max-turns N` exists on `generate`, `optimize`, and `review` as an opt-in for debugging or strict cost control; it is not for production.
|
|
79
84
|
|
|
80
85
|
In multi-cycle mode each cycle is a GitHub Milestone and produces a committable, working increment. Each cycle starts a fresh SDK session and re-reads the committed codebase, so the model never relies on stale conversational context.
|
|
81
86
|
|
|
@@ -83,7 +88,7 @@ If the Max subscription hits a rate limit, the tool **pauses** — it persists t
|
|
|
83
88
|
|
|
84
89
|
### `code-generator review [--create-issues] [--severity LEVEL]`
|
|
85
90
|
|
|
86
|
-
Run a standalone Opus 4.
|
|
91
|
+
Run a standalone Opus 4.7 review of the current codebase against the design principles in `requirements.md` §4 (SOLID, Clean Code, TDD, YAGNI/KISS/DRY). With `--create-issues`, every finding becomes a GitHub Issue.
|
|
87
92
|
|
|
88
93
|
### `code-generator status`
|
|
89
94
|
|
|
@@ -91,7 +96,7 @@ Print a Rich table with the current mode, current cycle, current phase, open/clo
|
|
|
91
96
|
|
|
92
97
|
## Safety constraints
|
|
93
98
|
|
|
94
|
-
The tool enforces
|
|
99
|
+
The tool enforces nine non-negotiables (see `CLAUDE.md` for the full list):
|
|
95
100
|
|
|
96
101
|
1. **Max subscription only, zero API credits.** Before any SDK or subprocess call, the tool strips `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, `ANTHROPIC_BEDROCK_API_KEY`, `ANTHROPIC_VERTEX_PROJECT_ID`, `CLAUDE_CODE_USE_BEDROCK`, `CLAUDE_CODE_USE_VERTEX` from the environment. A startup check refuses to run if any are present.
|
|
97
102
|
2. **Never `--bare`.** The CLI flag `--bare` skips OAuth and forces API credits — it is **never** passed by this tool. If Anthropic ever makes `--bare` the default for `claude -p`, pin the CLI version or pass the opposite flag explicitly.
|
|
@@ -100,7 +105,7 @@ The tool enforces eight non-negotiables (see `CLAUDE.md` for the full list):
|
|
|
100
105
|
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.
|
|
101
106
|
6. **Fresh SDK session per issue.** The implementation phase never reuses conversational context across issues — each issue is a `/clear`-equivalent fresh session.
|
|
102
107
|
7. **Atomic state writes.** `.code-generator/state.json` is updated via `tmp → os.replace(tmp, STATE)` so a crash mid-write cannot corrupt it.
|
|
103
|
-
8. **Fixed model per phase.** Opus 4.
|
|
108
|
+
8. **Fixed model per phase.** Opus 4.7 for phases 0/1/2/5/7; Sonnet 4.6 for phases 3/4/6.
|
|
104
109
|
|
|
105
110
|
## Troubleshooting
|
|
106
111
|
|
|
@@ -152,6 +157,12 @@ pytest -q
|
|
|
152
157
|
ruff check src tests
|
|
153
158
|
```
|
|
154
159
|
|
|
160
|
+
## Benchmarking
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
code-generator bench --fake --cycles 3 --output bench.json
|
|
164
|
+
```
|
|
165
|
+
|
|
155
166
|
## Reference
|
|
156
167
|
|
|
157
168
|
The full specification lives in [`requirements.md`](requirements.md). Each prompt file (`prompt-phase-*.md`, `prompt-review.md`) is loaded verbatim by the orchestrator with `{NAME}` placeholders substituted at runtime — edit the prompts there, not inline in Python.
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "claude-code-generator"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.4.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" }
|
|
@@ -23,7 +23,7 @@ classifiers = [
|
|
|
23
23
|
]
|
|
24
24
|
requires-python = ">=3.11"
|
|
25
25
|
dependencies = [
|
|
26
|
-
"claude-agent-sdk",
|
|
26
|
+
"claude-agent-sdk>=0.1.61,<0.2.0",
|
|
27
27
|
"typer",
|
|
28
28
|
"rich",
|
|
29
29
|
]
|
|
@@ -39,6 +39,27 @@ dev = [
|
|
|
39
39
|
"pytest-asyncio",
|
|
40
40
|
"ruff",
|
|
41
41
|
]
|
|
42
|
+
repomap = [
|
|
43
|
+
"tree-sitter>=0.21,<0.22",
|
|
44
|
+
"tree-sitter-languages>=1.10",
|
|
45
|
+
]
|
|
46
|
+
mcp = [
|
|
47
|
+
# Python MCP client library — the codebase-memory-mcp and serena binaries
|
|
48
|
+
# are external and must be installed separately:
|
|
49
|
+
# cargo install codebase-memory-mcp (or brew install codebase-memory-mcp)
|
|
50
|
+
# pip install serena (or uvx serena for zero-install)
|
|
51
|
+
"mcp>=1.0,<2.0",
|
|
52
|
+
]
|
|
53
|
+
batch = [
|
|
54
|
+
# Anthropic SDK for the Messages Batches API (§6).
|
|
55
|
+
# Install via: pipx install "claude-code-generator[batch]"
|
|
56
|
+
"anthropic>=0.35",
|
|
57
|
+
]
|
|
58
|
+
all = [
|
|
59
|
+
# Everything pip can install. External binaries (codebase-memory-mcp Rust
|
|
60
|
+
# crate, serena) must be installed separately — see README.
|
|
61
|
+
"claude-code-generator[repomap,mcp,batch]",
|
|
62
|
+
]
|
|
42
63
|
|
|
43
64
|
[project.scripts]
|
|
44
65
|
code-generator = "code_generator.cli:app"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: claude-code-generator
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.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
|
|
@@ -20,13 +20,22 @@ Classifier: Topic :: Software Development :: Code Generators
|
|
|
20
20
|
Requires-Python: >=3.11
|
|
21
21
|
Description-Content-Type: text/markdown
|
|
22
22
|
License-File: LICENSE
|
|
23
|
-
Requires-Dist: claude-agent-sdk
|
|
23
|
+
Requires-Dist: claude-agent-sdk<0.2.0,>=0.1.61
|
|
24
24
|
Requires-Dist: typer
|
|
25
25
|
Requires-Dist: rich
|
|
26
26
|
Provides-Extra: dev
|
|
27
27
|
Requires-Dist: pytest; extra == "dev"
|
|
28
28
|
Requires-Dist: pytest-asyncio; extra == "dev"
|
|
29
29
|
Requires-Dist: ruff; extra == "dev"
|
|
30
|
+
Provides-Extra: repomap
|
|
31
|
+
Requires-Dist: tree-sitter<0.22,>=0.21; extra == "repomap"
|
|
32
|
+
Requires-Dist: tree-sitter-languages>=1.10; extra == "repomap"
|
|
33
|
+
Provides-Extra: mcp
|
|
34
|
+
Requires-Dist: mcp<2.0,>=1.0; extra == "mcp"
|
|
35
|
+
Provides-Extra: batch
|
|
36
|
+
Requires-Dist: anthropic>=0.35; extra == "batch"
|
|
37
|
+
Provides-Extra: all
|
|
38
|
+
Requires-Dist: claude-code-generator[batch,mcp,repomap]; extra == "all"
|
|
30
39
|
Dynamic: license-file
|
|
31
40
|
|
|
32
41
|
# code-generator
|
|
@@ -72,7 +81,7 @@ $EDITOR .code-generator/requirements.md
|
|
|
72
81
|
|
|
73
82
|
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
83
|
|
|
75
|
-
Runs a single Opus 4.
|
|
84
|
+
Runs a single Opus 4.7 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
85
|
|
|
77
86
|
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
87
|
|
|
@@ -88,13 +97,13 @@ Read `.code-generator/requirements.md` and orchestrate Claude Code through the 0
|
|
|
88
97
|
|
|
89
98
|
| Phase | Action | Model |
|
|
90
99
|
|---|---|---|
|
|
91
|
-
| 0 | Complexity analysis (single vs multi-cycle) | Opus 4.
|
|
92
|
-
| 1 | Planning — creates GitHub issues + milestone | Opus 4.
|
|
93
|
-
| 2 | Per-issue review | Opus 4.
|
|
100
|
+
| 0 | Complexity analysis (single vs multi-cycle) | Opus 4.7 |
|
|
101
|
+
| 1 | Planning — creates GitHub issues + milestone | Opus 4.7 |
|
|
102
|
+
| 2 | Per-issue review | Opus 4.7 |
|
|
94
103
|
| 3-4 | Implementation, fresh SDK session per issue (TDD) | Sonnet 4.6 |
|
|
95
|
-
| 5 | Closure + cross-module review | Opus 4.
|
|
104
|
+
| 5 | Closure + cross-module review | Opus 4.7 |
|
|
96
105
|
| 6 | Test suite, max 3 retries on failure | Sonnet 4.6 |
|
|
97
|
-
| 7 | Commit message + git add/commit/push | Opus 4.
|
|
106
|
+
| 7 | Commit message + git add/commit/push | Opus 4.7 |
|
|
98
107
|
|
|
99
108
|
Every phase logs a completion summary with token counts (`in`, `cache_read`, `cache_write`, `out`) and persists them to `state.json`.
|
|
100
109
|
|
|
@@ -107,6 +116,11 @@ Flags:
|
|
|
107
116
|
| `--continue` | Resume from the last completed phase (reads `state.json`) | false |
|
|
108
117
|
| `--mode auto\|single\|multi-cycle` | Force a mode (default `auto` runs Phase 0 first) | auto |
|
|
109
118
|
| `--cycle N` | Resume from cycle N (multi-cycle only) | — |
|
|
119
|
+
| `--max-turns N` | Opt-in per-session turn cap for debugging or strict cost control (positive integer); omit for no cap | — |
|
|
120
|
+
|
|
121
|
+
#### Turn budgets
|
|
122
|
+
|
|
123
|
+
No per-session turn budget is set by default. Sessions terminate via `end_turn` on the model side; the real safety nets are rate-limit handling, overage abort (non-negotiable #4), and task budgets — **not** a guessed integer. `--max-turns N` exists on `generate`, `optimize`, and `review` as an opt-in for debugging or strict cost control; it is not for production.
|
|
110
124
|
|
|
111
125
|
In multi-cycle mode each cycle is a GitHub Milestone and produces a committable, working increment. Each cycle starts a fresh SDK session and re-reads the committed codebase, so the model never relies on stale conversational context.
|
|
112
126
|
|
|
@@ -114,7 +128,7 @@ If the Max subscription hits a rate limit, the tool **pauses** — it persists t
|
|
|
114
128
|
|
|
115
129
|
### `code-generator review [--create-issues] [--severity LEVEL]`
|
|
116
130
|
|
|
117
|
-
Run a standalone Opus 4.
|
|
131
|
+
Run a standalone Opus 4.7 review of the current codebase against the design principles in `requirements.md` §4 (SOLID, Clean Code, TDD, YAGNI/KISS/DRY). With `--create-issues`, every finding becomes a GitHub Issue.
|
|
118
132
|
|
|
119
133
|
### `code-generator status`
|
|
120
134
|
|
|
@@ -122,7 +136,7 @@ Print a Rich table with the current mode, current cycle, current phase, open/clo
|
|
|
122
136
|
|
|
123
137
|
## Safety constraints
|
|
124
138
|
|
|
125
|
-
The tool enforces
|
|
139
|
+
The tool enforces nine non-negotiables (see `CLAUDE.md` for the full list):
|
|
126
140
|
|
|
127
141
|
1. **Max subscription only, zero API credits.** Before any SDK or subprocess call, the tool strips `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, `ANTHROPIC_BEDROCK_API_KEY`, `ANTHROPIC_VERTEX_PROJECT_ID`, `CLAUDE_CODE_USE_BEDROCK`, `CLAUDE_CODE_USE_VERTEX` from the environment. A startup check refuses to run if any are present.
|
|
128
142
|
2. **Never `--bare`.** The CLI flag `--bare` skips OAuth and forces API credits — it is **never** passed by this tool. If Anthropic ever makes `--bare` the default for `claude -p`, pin the CLI version or pass the opposite flag explicitly.
|
|
@@ -131,7 +145,7 @@ The tool enforces eight non-negotiables (see `CLAUDE.md` for the full list):
|
|
|
131
145
|
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.
|
|
132
146
|
6. **Fresh SDK session per issue.** The implementation phase never reuses conversational context across issues — each issue is a `/clear`-equivalent fresh session.
|
|
133
147
|
7. **Atomic state writes.** `.code-generator/state.json` is updated via `tmp → os.replace(tmp, STATE)` so a crash mid-write cannot corrupt it.
|
|
134
|
-
8. **Fixed model per phase.** Opus 4.
|
|
148
|
+
8. **Fixed model per phase.** Opus 4.7 for phases 0/1/2/5/7; Sonnet 4.6 for phases 3/4/6.
|
|
135
149
|
|
|
136
150
|
## Troubleshooting
|
|
137
151
|
|
|
@@ -183,6 +197,12 @@ pytest -q
|
|
|
183
197
|
ruff check src tests
|
|
184
198
|
```
|
|
185
199
|
|
|
200
|
+
## Benchmarking
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
code-generator bench --fake --cycles 3 --output bench.json
|
|
204
|
+
```
|
|
205
|
+
|
|
186
206
|
## Reference
|
|
187
207
|
|
|
188
208
|
The full specification lives in [`requirements.md`](requirements.md). Each prompt file (`prompt-phase-*.md`, `prompt-review.md`) is loaded verbatim by the orchestrator with `{NAME}` placeholders substituted at runtime — edit the prompts there, not inline in Python.
|
|
@@ -14,12 +14,23 @@ src/code_generator/effort.py
|
|
|
14
14
|
src/code_generator/env.py
|
|
15
15
|
src/code_generator/git_ops.py
|
|
16
16
|
src/code_generator/logging_setup.py
|
|
17
|
+
src/code_generator/memory.py
|
|
18
|
+
src/code_generator/preflight.py
|
|
19
|
+
src/code_generator/repo_info.py
|
|
20
|
+
src/code_generator/repomap.py
|
|
17
21
|
src/code_generator/requirements_structure.py
|
|
18
22
|
src/code_generator/state.py
|
|
23
|
+
src/code_generator/state_retention.py
|
|
19
24
|
src/code_generator/commands/__init__.py
|
|
25
|
+
src/code_generator/commands/_bench_io.py
|
|
26
|
+
src/code_generator/commands/_crash_recovery.py
|
|
20
27
|
src/code_generator/commands/_detect.py
|
|
21
28
|
src/code_generator/commands/_dispatch.py
|
|
22
29
|
src/code_generator/commands/_resume.py
|
|
30
|
+
src/code_generator/commands/_validators.py
|
|
31
|
+
src/code_generator/commands/bench.py
|
|
32
|
+
src/code_generator/commands/bench_compare.py
|
|
33
|
+
src/code_generator/commands/bench_export.py
|
|
23
34
|
src/code_generator/commands/generate.py
|
|
24
35
|
src/code_generator/commands/init.py
|
|
25
36
|
src/code_generator/commands/optimize.py
|
|
@@ -31,7 +42,10 @@ src/code_generator/gh/issues.py
|
|
|
31
42
|
src/code_generator/gh/labels.py
|
|
32
43
|
src/code_generator/gh/milestones.py
|
|
33
44
|
src/code_generator/orchestrator/__init__.py
|
|
45
|
+
src/code_generator/orchestrator/_client_lifecycle.py
|
|
34
46
|
src/code_generator/orchestrator/_comments.py
|
|
47
|
+
src/code_generator/orchestrator/_memory_writers.py
|
|
48
|
+
src/code_generator/orchestrator/_phase5_precommit.py
|
|
35
49
|
src/code_generator/orchestrator/cycle_loop.py
|
|
36
50
|
src/code_generator/orchestrator/phase0_complexity.py
|
|
37
51
|
src/code_generator/orchestrator/phase1_plan.py
|
|
@@ -41,6 +55,7 @@ src/code_generator/orchestrator/phase5_closure.py
|
|
|
41
55
|
src/code_generator/orchestrator/phase6_test.py
|
|
42
56
|
src/code_generator/orchestrator/phase7_commit.py
|
|
43
57
|
src/code_generator/prompts/__init__.py
|
|
58
|
+
src/code_generator/prompts/hashes.py
|
|
44
59
|
src/code_generator/prompts/prompt-optimize-requirements.md
|
|
45
60
|
src/code_generator/prompts/prompt-phase-0-complexity.md
|
|
46
61
|
src/code_generator/prompts/prompt-phase-1-planning.md
|
|
@@ -51,12 +66,18 @@ src/code_generator/prompts/prompt-phase-6-test.md
|
|
|
51
66
|
src/code_generator/prompts/prompt-phase-7-commit.md
|
|
52
67
|
src/code_generator/prompts/prompt-review.md
|
|
53
68
|
src/code_generator/runner/__init__.py
|
|
69
|
+
src/code_generator/runner/_telemetry.py
|
|
70
|
+
src/code_generator/runner/batch.py
|
|
71
|
+
src/code_generator/runner/fake_runner.py
|
|
72
|
+
src/code_generator/runner/mcp.py
|
|
54
73
|
src/code_generator/runner/message_parsing.py
|
|
55
74
|
src/code_generator/runner/options.py
|
|
56
75
|
src/code_generator/runner/protocol.py
|
|
57
76
|
src/code_generator/runner/rate_limit.py
|
|
58
77
|
src/code_generator/runner/retry.py
|
|
59
78
|
src/code_generator/runner/sdk_runner.py
|
|
79
|
+
src/code_generator/runner/soft_reset.py
|
|
80
|
+
src/code_generator/runner/state_guard.py
|
|
60
81
|
src/code_generator/runner/subprocess_runner.py
|
|
61
82
|
src/code_generator/runner/types.py
|
|
62
83
|
src/code_generator/runner/utils.py
|
|
@@ -69,12 +90,23 @@ src/code_generator/templates/fullstack.md
|
|
|
69
90
|
src/code_generator/templates/nestjs.md
|
|
70
91
|
src/code_generator/templates/python-cli.md
|
|
71
92
|
tests/test_agents.py
|
|
93
|
+
tests/test_bench.py
|
|
94
|
+
tests/test_bench_compare.py
|
|
95
|
+
tests/test_bench_export.py
|
|
96
|
+
tests/test_bench_fixture.py
|
|
97
|
+
tests/test_bench_regression.py
|
|
98
|
+
tests/test_changelog.py
|
|
99
|
+
tests/test_claude_md.py
|
|
100
|
+
tests/test_client_lifecycle.py
|
|
72
101
|
tests/test_comments.py
|
|
73
102
|
tests/test_commit_message.py
|
|
103
|
+
tests/test_crash_recovery.py
|
|
74
104
|
tests/test_cycle_loop.py
|
|
75
105
|
tests/test_cycle_loop_multicycle.py
|
|
76
106
|
tests/test_delta_planning.py
|
|
107
|
+
tests/test_dependencies.py
|
|
77
108
|
tests/test_detect.py
|
|
109
|
+
tests/test_docs_no_default_max_turns.py
|
|
78
110
|
tests/test_effort.py
|
|
79
111
|
tests/test_env.py
|
|
80
112
|
tests/test_generate.py
|
|
@@ -82,23 +114,40 @@ tests/test_generate_resume.py
|
|
|
82
114
|
tests/test_gh.py
|
|
83
115
|
tests/test_gh_labels.py
|
|
84
116
|
tests/test_gh_milestones.py
|
|
117
|
+
tests/test_gh_repo_threading.py
|
|
85
118
|
tests/test_gh_submodules.py
|
|
86
119
|
tests/test_git_ops.py
|
|
87
120
|
tests/test_init.py
|
|
88
121
|
tests/test_logging_setup.py
|
|
122
|
+
tests/test_max_turns_cli_flag.py
|
|
123
|
+
tests/test_mcp.py
|
|
124
|
+
tests/test_memory.py
|
|
125
|
+
tests/test_memory_writers.py
|
|
89
126
|
tests/test_message_parsing.py
|
|
127
|
+
tests/test_no_max_turns_in_call_sites.py
|
|
128
|
+
tests/test_no_max_turns_literal.py
|
|
129
|
+
tests/test_non_goals_grep_guard.py
|
|
90
130
|
tests/test_optimize.py
|
|
91
131
|
tests/test_options.py
|
|
92
132
|
tests/test_phase0.py
|
|
93
133
|
tests/test_phase1.py
|
|
94
134
|
tests/test_phase2.py
|
|
135
|
+
tests/test_phase2_batch.py
|
|
95
136
|
tests/test_phase3_4.py
|
|
96
137
|
tests/test_phase5.py
|
|
138
|
+
tests/test_phase5_precommit.py
|
|
97
139
|
tests/test_phase6.py
|
|
98
140
|
tests/test_phase7.py
|
|
141
|
+
tests/test_phase_mcp_regression.py
|
|
99
142
|
tests/test_phase_token_logging.py
|
|
143
|
+
tests/test_preflight.py
|
|
144
|
+
tests/test_prompt_drift.py
|
|
145
|
+
tests/test_prompt_prefix_snapshots.py
|
|
146
|
+
tests/test_prompt_prefix_stability.py
|
|
100
147
|
tests/test_prompts.py
|
|
101
148
|
tests/test_rate_limit.py
|
|
149
|
+
tests/test_repo_info.py
|
|
150
|
+
tests/test_repomap.py
|
|
102
151
|
tests/test_requirements_structure.py
|
|
103
152
|
tests/test_retry.py
|
|
104
153
|
tests/test_review.py
|
|
@@ -107,7 +156,12 @@ tests/test_runner_protocol_annotations.py
|
|
|
107
156
|
tests/test_runner_types.py
|
|
108
157
|
tests/test_runner_utils.py
|
|
109
158
|
tests/test_sdk_runner.py
|
|
159
|
+
tests/test_sdk_runner_shared.py
|
|
160
|
+
tests/test_session_mode.py
|
|
110
161
|
tests/test_state.py
|
|
162
|
+
tests/test_state_guard.py
|
|
163
|
+
tests/test_state_retention.py
|
|
111
164
|
tests/test_status.py
|
|
112
165
|
tests/test_subprocess_runner.py
|
|
166
|
+
tests/test_telemetry.py
|
|
113
167
|
tests/test_version.py
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
claude-agent-sdk<0.2.0,>=0.1.61
|
|
2
|
+
typer
|
|
3
|
+
rich
|
|
4
|
+
|
|
5
|
+
[all]
|
|
6
|
+
claude-code-generator[batch,mcp,repomap]
|
|
7
|
+
|
|
8
|
+
[batch]
|
|
9
|
+
anthropic>=0.35
|
|
10
|
+
|
|
11
|
+
[dev]
|
|
12
|
+
pytest
|
|
13
|
+
pytest-asyncio
|
|
14
|
+
ruff
|
|
15
|
+
|
|
16
|
+
[mcp]
|
|
17
|
+
mcp<2.0,>=1.0
|
|
18
|
+
|
|
19
|
+
[repomap]
|
|
20
|
+
tree-sitter<0.22,>=0.21
|
|
21
|
+
tree-sitter-languages>=1.10
|
|
@@ -9,6 +9,7 @@ from typing import Annotated
|
|
|
9
9
|
import typer
|
|
10
10
|
|
|
11
11
|
import code_generator
|
|
12
|
+
from code_generator.commands.bench import bench_app
|
|
12
13
|
from code_generator.commands.generate import generate_command
|
|
13
14
|
from code_generator.commands.init import init_command
|
|
14
15
|
from code_generator.commands.optimize import optimize_command
|
|
@@ -44,6 +45,7 @@ def root(
|
|
|
44
45
|
"""code-generator CLI root."""
|
|
45
46
|
|
|
46
47
|
|
|
48
|
+
app.add_typer(bench_app, name="bench")
|
|
47
49
|
app.command(name="init")(init_command)
|
|
48
50
|
app.command(name="status")(status_command)
|
|
49
51
|
app.command(name="generate")(generate_command)
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""Shared I/O helpers for bench and bench export subcommands.
|
|
2
|
+
|
|
3
|
+
Extracted to break the circular-import between bench.py (which registers
|
|
4
|
+
subcommands) and bench_export.py (which needs the schema version and writer).
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import json
|
|
10
|
+
import os
|
|
11
|
+
from typing import TYPE_CHECKING, Any
|
|
12
|
+
|
|
13
|
+
import typer
|
|
14
|
+
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
|
|
18
|
+
# Bump this + add a migration note for any breaking schema change.
|
|
19
|
+
# v2 (issue #212): per-phase dicts + totals now include ``num_turns``.
|
|
20
|
+
SCHEMA_VERSION: int = 2
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def write_output(path: Path | None, payload: dict[str, Any]) -> None:
|
|
24
|
+
"""Write *payload* as pretty-printed JSON atomically to *path*, or stdout.
|
|
25
|
+
|
|
26
|
+
Uses tmp → os.replace() so a crash mid-write cannot corrupt the file.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
path: Destination file path, or None to print to stdout.
|
|
30
|
+
payload: JSON-serialisable dict to write.
|
|
31
|
+
"""
|
|
32
|
+
serialised = json.dumps(payload, indent=2)
|
|
33
|
+
if path is None:
|
|
34
|
+
typer.echo(serialised)
|
|
35
|
+
return
|
|
36
|
+
|
|
37
|
+
tmp_path = path.with_suffix(".tmp")
|
|
38
|
+
tmp_path.write_text(serialised, encoding="utf-8")
|
|
39
|
+
os.replace(tmp_path, path)
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"""Crash-recovery helpers for the --continue entry point.
|
|
2
|
+
|
|
3
|
+
On --continue, if the previous client was alive within the TTL window
|
|
4
|
+
(default 60 minutes), the client was likely orphaned by a process crash.
|
|
5
|
+
The orchestrator always opens a fresh client on resume; this module
|
|
6
|
+
provides the diagnostic check and log message.
|
|
7
|
+
|
|
8
|
+
The log message is exact — downstream bench/observability tooling greps for it.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
import logging
|
|
14
|
+
from typing import TYPE_CHECKING
|
|
15
|
+
|
|
16
|
+
from code_generator import state as _state
|
|
17
|
+
|
|
18
|
+
if TYPE_CHECKING:
|
|
19
|
+
from code_generator.state import State
|
|
20
|
+
|
|
21
|
+
# Exact log string — do NOT change without updating downstream consumers.
|
|
22
|
+
CRASH_RECOVERY_LOG_MSG = (
|
|
23
|
+
"previous client vanished; reopening with fresh KV cache (expected on crash recovery)"
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
_logger = logging.getLogger(__name__)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def check_and_log_crash_recovery(
|
|
30
|
+
state: State,
|
|
31
|
+
*,
|
|
32
|
+
ttl_minutes: int = 60,
|
|
33
|
+
logger: logging.Logger | None = None,
|
|
34
|
+
) -> None:
|
|
35
|
+
"""Log a crash-recovery diagnostic when client_alive_at is within the TTL window.
|
|
36
|
+
|
|
37
|
+
Called on --continue before the cycle loop opens a new shared client.
|
|
38
|
+
When client_alive_at is set and within ttl_minutes, the client was likely
|
|
39
|
+
orphaned by a crash. The caller will open a fresh client regardless; this
|
|
40
|
+
function only emits the INFO diagnostic.
|
|
41
|
+
|
|
42
|
+
When client_alive_at is None or older than ttl_minutes, no log is emitted
|
|
43
|
+
(normal resume after a rate-limit pause or a completed run).
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
state: Root state to inspect (read-only).
|
|
47
|
+
ttl_minutes: Age threshold in minutes (exclusive upper bound). Default 60.
|
|
48
|
+
logger: Logger for the INFO message. Defaults to the module logger.
|
|
49
|
+
"""
|
|
50
|
+
log = logger or _logger
|
|
51
|
+
if _state.is_client_presumed_alive(state, ttl_minutes=ttl_minutes):
|
|
52
|
+
log.info(CRASH_RECOVERY_LOG_MSG)
|