claude-code-generator 0.2.4__tar.gz → 0.4.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 (178) hide show
  1. {claude_code_generator-0.2.4/src/claude_code_generator.egg-info → claude_code_generator-0.4.0}/PKG-INFO +31 -11
  2. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/README.md +20 -9
  3. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/pyproject.toml +23 -2
  4. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0/src/claude_code_generator.egg-info}/PKG-INFO +31 -11
  5. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/claude_code_generator.egg-info/SOURCES.txt +54 -0
  6. claude_code_generator-0.4.0/src/claude_code_generator.egg-info/requires.txt +21 -0
  7. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/__init__.py +1 -1
  8. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/cli.py +2 -0
  9. claude_code_generator-0.4.0/src/code_generator/commands/_bench_io.py +39 -0
  10. claude_code_generator-0.4.0/src/code_generator/commands/_crash_recovery.py +52 -0
  11. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/commands/_dispatch.py +102 -1
  12. claude_code_generator-0.4.0/src/code_generator/commands/_validators.py +27 -0
  13. claude_code_generator-0.4.0/src/code_generator/commands/bench.py +271 -0
  14. claude_code_generator-0.4.0/src/code_generator/commands/bench_compare.py +249 -0
  15. claude_code_generator-0.4.0/src/code_generator/commands/bench_export.py +207 -0
  16. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/commands/generate.py +113 -1
  17. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/commands/optimize.py +22 -6
  18. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/commands/review.py +26 -7
  19. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/commands/status.py +111 -41
  20. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/effort.py +2 -2
  21. claude_code_generator-0.4.0/src/code_generator/env.py +148 -0
  22. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/gh/__init__.py +1 -3
  23. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/gh/core.py +36 -23
  24. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/gh/issues.py +40 -7
  25. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/gh/labels.py +55 -19
  26. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/gh/milestones.py +20 -10
  27. claude_code_generator-0.4.0/src/code_generator/memory.py +175 -0
  28. claude_code_generator-0.4.0/src/code_generator/orchestrator/_client_lifecycle.py +163 -0
  29. claude_code_generator-0.4.0/src/code_generator/orchestrator/_comments.py +120 -0
  30. claude_code_generator-0.4.0/src/code_generator/orchestrator/_memory_writers.py +126 -0
  31. claude_code_generator-0.4.0/src/code_generator/orchestrator/_phase5_precommit.py +165 -0
  32. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/orchestrator/cycle_loop.py +176 -23
  33. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/orchestrator/phase0_complexity.py +19 -9
  34. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/orchestrator/phase1_plan.py +43 -16
  35. claude_code_generator-0.4.0/src/code_generator/orchestrator/phase2_review.py +657 -0
  36. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/orchestrator/phase3_4_implement.py +112 -23
  37. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/orchestrator/phase5_closure.py +176 -23
  38. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/orchestrator/phase6_test.py +8 -2
  39. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/orchestrator/phase7_commit.py +22 -23
  40. claude_code_generator-0.4.0/src/code_generator/preflight.py +259 -0
  41. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/prompts/__init__.py +45 -5
  42. claude_code_generator-0.4.0/src/code_generator/prompts/hashes.py +34 -0
  43. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/prompts/prompt-optimize-requirements.md +1 -1
  44. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/prompts/prompt-phase-0-complexity.md +9 -1
  45. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/prompts/prompt-phase-1-planning.md +29 -20
  46. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/prompts/prompt-phase-2-issue-review.md +40 -18
  47. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/prompts/prompt-phase-3-implementation.md +36 -18
  48. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/prompts/prompt-phase-5-final-review.md +51 -36
  49. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/prompts/prompt-phase-6-test.md +8 -4
  50. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/prompts/prompt-phase-7-commit.md +25 -27
  51. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/prompts/prompt-review.md +10 -6
  52. claude_code_generator-0.4.0/src/code_generator/repo_info.py +161 -0
  53. claude_code_generator-0.4.0/src/code_generator/repomap.py +233 -0
  54. claude_code_generator-0.4.0/src/code_generator/runner/_telemetry.py +47 -0
  55. claude_code_generator-0.4.0/src/code_generator/runner/batch.py +201 -0
  56. claude_code_generator-0.4.0/src/code_generator/runner/fake_runner.py +66 -0
  57. claude_code_generator-0.4.0/src/code_generator/runner/mcp.py +125 -0
  58. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/runner/message_parsing.py +32 -3
  59. claude_code_generator-0.4.0/src/code_generator/runner/options.py +603 -0
  60. claude_code_generator-0.4.0/src/code_generator/runner/sdk_runner.py +322 -0
  61. claude_code_generator-0.4.0/src/code_generator/runner/soft_reset.py +103 -0
  62. claude_code_generator-0.4.0/src/code_generator/runner/state_guard.py +80 -0
  63. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/runner/subprocess_runner.py +21 -4
  64. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/runner/types.py +17 -4
  65. claude_code_generator-0.4.0/src/code_generator/state.py +777 -0
  66. claude_code_generator-0.4.0/src/code_generator/state_retention.py +102 -0
  67. claude_code_generator-0.4.0/tests/test_bench.py +331 -0
  68. claude_code_generator-0.4.0/tests/test_bench_compare.py +312 -0
  69. claude_code_generator-0.4.0/tests/test_bench_export.py +388 -0
  70. claude_code_generator-0.4.0/tests/test_bench_fixture.py +144 -0
  71. claude_code_generator-0.4.0/tests/test_bench_regression.py +114 -0
  72. claude_code_generator-0.4.0/tests/test_changelog.py +114 -0
  73. claude_code_generator-0.4.0/tests/test_claude_md.py +33 -0
  74. claude_code_generator-0.4.0/tests/test_client_lifecycle.py +581 -0
  75. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_comments.py +17 -9
  76. claude_code_generator-0.4.0/tests/test_crash_recovery.py +490 -0
  77. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_cycle_loop.py +131 -9
  78. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_cycle_loop_multicycle.py +12 -12
  79. claude_code_generator-0.4.0/tests/test_dependencies.py +23 -0
  80. claude_code_generator-0.4.0/tests/test_docs_no_default_max_turns.py +139 -0
  81. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_effort.py +4 -4
  82. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_env.py +65 -0
  83. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_generate.py +157 -11
  84. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_generate_resume.py +23 -1
  85. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_gh.py +23 -45
  86. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_gh_labels.py +14 -11
  87. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_gh_milestones.py +51 -63
  88. claude_code_generator-0.4.0/tests/test_gh_repo_threading.py +385 -0
  89. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_gh_submodules.py +21 -8
  90. claude_code_generator-0.4.0/tests/test_max_turns_cli_flag.py +420 -0
  91. claude_code_generator-0.4.0/tests/test_mcp.py +235 -0
  92. claude_code_generator-0.4.0/tests/test_memory.py +238 -0
  93. claude_code_generator-0.4.0/tests/test_memory_writers.py +334 -0
  94. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_message_parsing.py +53 -0
  95. claude_code_generator-0.4.0/tests/test_no_max_turns_in_call_sites.py +103 -0
  96. claude_code_generator-0.4.0/tests/test_no_max_turns_literal.py +87 -0
  97. claude_code_generator-0.4.0/tests/test_non_goals_grep_guard.py +302 -0
  98. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_optimize.py +21 -8
  99. claude_code_generator-0.4.0/tests/test_options.py +1174 -0
  100. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_phase0.py +1 -1
  101. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_phase1.py +23 -3
  102. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_phase2.py +401 -6
  103. claude_code_generator-0.4.0/tests/test_phase2_batch.py +602 -0
  104. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_phase3_4.py +742 -17
  105. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_phase5.py +421 -14
  106. claude_code_generator-0.4.0/tests/test_phase5_precommit.py +409 -0
  107. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_phase7.py +95 -11
  108. claude_code_generator-0.4.0/tests/test_phase_mcp_regression.py +193 -0
  109. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_phase_token_logging.py +26 -1
  110. claude_code_generator-0.4.0/tests/test_preflight.py +443 -0
  111. claude_code_generator-0.4.0/tests/test_prompt_drift.py +254 -0
  112. claude_code_generator-0.4.0/tests/test_prompt_prefix_snapshots.py +144 -0
  113. claude_code_generator-0.4.0/tests/test_prompt_prefix_stability.py +239 -0
  114. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_prompts.py +234 -7
  115. claude_code_generator-0.4.0/tests/test_repo_info.py +249 -0
  116. claude_code_generator-0.4.0/tests/test_repomap.py +110 -0
  117. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_runner_types.py +51 -0
  118. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_sdk_runner.py +78 -2
  119. claude_code_generator-0.4.0/tests/test_sdk_runner_shared.py +398 -0
  120. claude_code_generator-0.4.0/tests/test_session_mode.py +294 -0
  121. claude_code_generator-0.4.0/tests/test_state.py +2610 -0
  122. claude_code_generator-0.4.0/tests/test_state_guard.py +100 -0
  123. claude_code_generator-0.4.0/tests/test_state_retention.py +297 -0
  124. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_status.py +276 -1
  125. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_subprocess_runner.py +240 -2
  126. claude_code_generator-0.4.0/tests/test_telemetry.py +193 -0
  127. claude_code_generator-0.2.4/src/claude_code_generator.egg-info/requires.txt +0 -8
  128. claude_code_generator-0.2.4/src/code_generator/env.py +0 -55
  129. claude_code_generator-0.2.4/src/code_generator/orchestrator/_comments.py +0 -72
  130. claude_code_generator-0.2.4/src/code_generator/orchestrator/phase2_review.py +0 -158
  131. claude_code_generator-0.2.4/src/code_generator/runner/options.py +0 -41
  132. claude_code_generator-0.2.4/src/code_generator/runner/sdk_runner.py +0 -211
  133. claude_code_generator-0.2.4/src/code_generator/state.py +0 -366
  134. claude_code_generator-0.2.4/tests/test_options.py +0 -95
  135. claude_code_generator-0.2.4/tests/test_state.py +0 -1154
  136. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/LICENSE +0 -0
  137. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/setup.cfg +0 -0
  138. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/claude_code_generator.egg-info/dependency_links.txt +0 -0
  139. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/claude_code_generator.egg-info/entry_points.txt +0 -0
  140. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/claude_code_generator.egg-info/top_level.txt +0 -0
  141. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/agents.py +0 -0
  142. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/commands/__init__.py +0 -0
  143. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/commands/_detect.py +0 -0
  144. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/commands/_resume.py +0 -0
  145. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/commands/init.py +0 -0
  146. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/git_ops.py +0 -0
  147. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/logging_setup.py +0 -0
  148. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/orchestrator/__init__.py +0 -0
  149. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/requirements_structure.py +0 -0
  150. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/runner/__init__.py +0 -0
  151. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/runner/protocol.py +0 -0
  152. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/runner/rate_limit.py +0 -0
  153. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/runner/retry.py +0 -0
  154. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/runner/utils.py +0 -0
  155. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/templates/__init__.py +0 -0
  156. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/templates/angular.md +0 -0
  157. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/templates/base.md +0 -0
  158. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/templates/fastapi.md +0 -0
  159. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/templates/finance.md +0 -0
  160. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/templates/fullstack.md +0 -0
  161. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/templates/nestjs.md +0 -0
  162. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/src/code_generator/templates/python-cli.md +0 -0
  163. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_agents.py +0 -0
  164. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_commit_message.py +0 -0
  165. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_delta_planning.py +0 -0
  166. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_detect.py +0 -0
  167. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_git_ops.py +0 -0
  168. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_init.py +0 -0
  169. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_logging_setup.py +0 -0
  170. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_phase6.py +0 -0
  171. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_rate_limit.py +0 -0
  172. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_requirements_structure.py +0 -0
  173. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_retry.py +0 -0
  174. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_review.py +0 -0
  175. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_runner_protocol.py +0 -0
  176. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_runner_protocol_annotations.py +0 -0
  177. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/tests/test_runner_utils.py +0 -0
  178. {claude_code_generator-0.2.4 → claude_code_generator-0.4.0}/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.2.4
3
+ Version: 0.4.0
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.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`.
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.6 |
92
- | 1 | Planning — creates GitHub issues + milestone | Opus 4.6 |
93
- | 2 | Per-issue review | Opus 4.6 |
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.6 |
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.6 |
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.6 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.
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 eight non-negotiables (see `CLAUDE.md` for the full list):
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.6 for phases 0/1/2/5/7; Sonnet 4.6 for phases 3/4/6.
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.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`.
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.6 |
61
- | 1 | Planning — creates GitHub issues + milestone | Opus 4.6 |
62
- | 2 | Per-issue review | Opus 4.6 |
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.6 |
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.6 |
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.6 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.
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 eight non-negotiables (see `CLAUDE.md` for the full list):
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.6 for phases 0/1/2/5/7; Sonnet 4.6 for phases 3/4/6.
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.2.4"
7
+ version = "0.4.0"
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.2.4
3
+ Version: 0.4.0
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.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`.
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.6 |
92
- | 1 | Planning — creates GitHub issues + milestone | Opus 4.6 |
93
- | 2 | Per-issue review | Opus 4.6 |
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.6 |
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.6 |
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.6 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.
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 eight non-negotiables (see `CLAUDE.md` for the full list):
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.6 for phases 0/1/2/5/7; Sonnet 4.6 for phases 3/4/6.
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
@@ -1,3 +1,3 @@
1
1
  """code-generator: orchestrator CLI for end-to-end project generation."""
2
2
 
3
- __version__ = "0.2.4"
3
+ __version__ = "0.4.0"
@@ -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)