claude-code-generator 0.4.13__tar.gz → 0.4.14__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 (182) hide show
  1. {claude_code_generator-0.4.13/src/claude_code_generator.egg-info → claude_code_generator-0.4.14}/PKG-INFO +1 -1
  2. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/pyproject.toml +1 -1
  3. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14/src/claude_code_generator.egg-info}/PKG-INFO +1 -1
  4. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/env.py +30 -10
  5. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/orchestrator/_client_lifecycle.py +15 -4
  6. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/orchestrator/cycle_loop.py +6 -2
  7. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/runner/subprocess_runner.py +11 -1
  8. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/LICENSE +0 -0
  9. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/README.md +0 -0
  10. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/setup.cfg +0 -0
  11. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/claude_code_generator.egg-info/SOURCES.txt +0 -0
  12. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/claude_code_generator.egg-info/dependency_links.txt +0 -0
  13. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/claude_code_generator.egg-info/entry_points.txt +0 -0
  14. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/claude_code_generator.egg-info/requires.txt +0 -0
  15. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/claude_code_generator.egg-info/top_level.txt +0 -0
  16. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/__init__.py +0 -0
  17. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/agents.py +0 -0
  18. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/cli.py +0 -0
  19. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/commands/__init__.py +0 -0
  20. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/commands/_bench_io.py +0 -0
  21. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/commands/_crash_recovery.py +0 -0
  22. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/commands/_detect.py +0 -0
  23. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/commands/_dispatch.py +0 -0
  24. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/commands/_resume.py +0 -0
  25. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/commands/_validators.py +0 -0
  26. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/commands/bench.py +0 -0
  27. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/commands/bench_compare.py +0 -0
  28. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/commands/bench_export.py +0 -0
  29. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/commands/generate.py +0 -0
  30. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/commands/init.py +0 -0
  31. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/commands/optimize.py +0 -0
  32. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/commands/review.py +0 -0
  33. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/commands/status.py +0 -0
  34. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/effort.py +0 -0
  35. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/gh/__init__.py +0 -0
  36. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/gh/core.py +0 -0
  37. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/gh/issues.py +0 -0
  38. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/gh/labels.py +0 -0
  39. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/gh/milestones.py +0 -0
  40. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/git_ops.py +0 -0
  41. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/logging_setup.py +0 -0
  42. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/memory.py +0 -0
  43. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/orchestrator/__init__.py +0 -0
  44. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/orchestrator/_comments.py +0 -0
  45. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/orchestrator/_memory_writers.py +0 -0
  46. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/orchestrator/_phase5_precommit.py +0 -0
  47. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/orchestrator/cycle_prompts.py +0 -0
  48. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/orchestrator/ollama_budget.py +0 -0
  49. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/orchestrator/phase0_complexity.py +0 -0
  50. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/orchestrator/phase1_plan.py +0 -0
  51. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/orchestrator/phase2_review.py +0 -0
  52. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/orchestrator/phase3_4_implement.py +0 -0
  53. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/orchestrator/phase5_closure.py +0 -0
  54. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/orchestrator/phase6_test.py +0 -0
  55. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/orchestrator/phase7_commit.py +0 -0
  56. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/preflight.py +0 -0
  57. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/prompts/__init__.py +0 -0
  58. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/prompts/hashes.py +0 -0
  59. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/prompts/prompt-cycle-specializer.md +0 -0
  60. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/prompts/prompt-optimize-requirements.md +0 -0
  61. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/prompts/prompt-phase-0-complexity.md +0 -0
  62. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/prompts/prompt-phase-1-planning.md +0 -0
  63. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/prompts/prompt-phase-2-batch-review.md +0 -0
  64. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/prompts/prompt-phase-2-issue-review.md +0 -0
  65. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/prompts/prompt-phase-3-implementation.md +0 -0
  66. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/prompts/prompt-phase-5-final-review.md +0 -0
  67. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/prompts/prompt-phase-6-test.md +0 -0
  68. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/prompts/prompt-phase-7-commit.md +0 -0
  69. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/prompts/prompt-review.md +0 -0
  70. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/repo_info.py +0 -0
  71. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/repomap.py +0 -0
  72. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/requirements_structure.py +0 -0
  73. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/runner/__init__.py +0 -0
  74. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/runner/_telemetry.py +0 -0
  75. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/runner/batch.py +0 -0
  76. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/runner/fake_runner.py +0 -0
  77. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/runner/mcp.py +0 -0
  78. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/runner/message_parsing.py +0 -0
  79. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/runner/options.py +0 -0
  80. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/runner/protocol.py +0 -0
  81. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/runner/rate_limit.py +0 -0
  82. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/runner/retry.py +0 -0
  83. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/runner/sdk_runner.py +0 -0
  84. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/runner/soft_reset.py +0 -0
  85. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/runner/state_guard.py +0 -0
  86. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/runner/types.py +0 -0
  87. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/runner/utils.py +0 -0
  88. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/state.py +0 -0
  89. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/state_retention.py +0 -0
  90. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/templates/__init__.py +0 -0
  91. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/templates/angular.md +0 -0
  92. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/templates/base.md +0 -0
  93. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/templates/fastapi.md +0 -0
  94. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/templates/finance.md +0 -0
  95. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/templates/fullstack.md +0 -0
  96. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/templates/nestjs.md +0 -0
  97. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/src/code_generator/templates/python-cli.md +0 -0
  98. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_agents.py +0 -0
  99. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_bench.py +0 -0
  100. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_bench_compare.py +0 -0
  101. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_bench_export.py +0 -0
  102. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_bench_fixture.py +0 -0
  103. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_bench_regression.py +0 -0
  104. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_changelog.py +0 -0
  105. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_claude_md.py +0 -0
  106. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_client_lifecycle.py +0 -0
  107. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_comments.py +0 -0
  108. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_commit_message.py +0 -0
  109. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_crash_recovery.py +0 -0
  110. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_cycle_loop.py +0 -0
  111. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_cycle_loop_multicycle.py +0 -0
  112. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_cycle_ollama_model.py +0 -0
  113. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_cycle_prompts.py +0 -0
  114. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_delta_planning.py +0 -0
  115. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_dependencies.py +0 -0
  116. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_detect.py +0 -0
  117. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_docs_no_default_max_turns.py +0 -0
  118. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_docs_ollama_model_guide.py +0 -0
  119. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_docs_ollama_pro.py +0 -0
  120. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_effective_model_routing.py +0 -0
  121. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_effort.py +0 -0
  122. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_env.py +0 -0
  123. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_generate.py +0 -0
  124. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_generate_ollama.py +0 -0
  125. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_generate_resume.py +0 -0
  126. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_gh.py +0 -0
  127. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_gh_labels.py +0 -0
  128. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_gh_milestones.py +0 -0
  129. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_gh_repo_threading.py +0 -0
  130. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_gh_submodules.py +0 -0
  131. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_git_ops.py +0 -0
  132. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_init.py +0 -0
  133. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_logging_setup.py +0 -0
  134. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_max_turns_cli_flag.py +0 -0
  135. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_mcp.py +0 -0
  136. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_memory.py +0 -0
  137. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_memory_writers.py +0 -0
  138. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_message_parsing.py +0 -0
  139. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_no_max_turns_in_call_sites.py +0 -0
  140. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_no_max_turns_literal.py +0 -0
  141. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_non_goals_grep_guard.py +0 -0
  142. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_ollama_budget.py +0 -0
  143. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_ollama_rate_limit.py +0 -0
  144. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_optimize.py +0 -0
  145. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_options.py +0 -0
  146. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_phase0.py +0 -0
  147. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_phase1.py +0 -0
  148. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_phase2.py +0 -0
  149. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_phase2_batch.py +0 -0
  150. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_phase3_4.py +0 -0
  151. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_phase5.py +0 -0
  152. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_phase5_precommit.py +0 -0
  153. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_phase6.py +0 -0
  154. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_phase7.py +0 -0
  155. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_phase_mcp_regression.py +0 -0
  156. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_phase_token_logging.py +0 -0
  157. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_preflight.py +0 -0
  158. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_preflight_ollama.py +0 -0
  159. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_prompt_drift.py +0 -0
  160. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_prompt_prefix_snapshots.py +0 -0
  161. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_prompt_prefix_stability.py +0 -0
  162. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_prompts.py +0 -0
  163. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_rate_limit.py +0 -0
  164. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_repo_info.py +0 -0
  165. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_repomap.py +0 -0
  166. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_requirements_structure.py +0 -0
  167. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_retry.py +0 -0
  168. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_review.py +0 -0
  169. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_runner_protocol.py +0 -0
  170. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_runner_protocol_annotations.py +0 -0
  171. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_runner_types.py +0 -0
  172. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_runner_utils.py +0 -0
  173. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_sdk_runner.py +0 -0
  174. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_sdk_runner_shared.py +0 -0
  175. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_session_mode.py +0 -0
  176. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_state.py +0 -0
  177. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_state_guard.py +0 -0
  178. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_state_retention.py +0 -0
  179. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_status.py +0 -0
  180. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_subprocess_runner.py +0 -0
  181. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/tests/test_telemetry.py +0 -0
  182. {claude_code_generator-0.4.13 → claude_code_generator-0.4.14}/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.4.13
3
+ Version: 0.4.14
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
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "claude-code-generator"
7
- version = "0.4.13"
7
+ version = "0.4.14"
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" }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: claude-code-generator
3
- Version: 0.4.13
3
+ Version: 0.4.14
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
@@ -48,7 +48,17 @@ def strip_dangerous_env() -> None:
48
48
  (``sdk_runner.run``, ``run_with_shared_client``).
49
49
  """
50
50
  ollama_mode = _is_localhost_base_url(os.environ.get("ANTHROPIC_BASE_URL"))
51
- protected = {"ANTHROPIC_AUTH_TOKEN"} if ollama_mode else set()
51
+ # On the Ollama codepath, ANTHROPIC_AUTH_TOKEN carries the daemon token
52
+ # and must survive stripping. ANTHROPIC_API_KEY is also protected when it
53
+ # has been set to "" by assert_safe_environment_ollama() — the empty-string
54
+ # sentinel tells the SDK to accept non-Claude model tags. A non-empty
55
+ # ANTHROPIC_API_KEY (e.g. "sk-evil") is still stripped because it would
56
+ # route traffic to Anthropic's real API, defeating the localhost redirect.
57
+ protected: set[str] = set()
58
+ if ollama_mode:
59
+ protected.add("ANTHROPIC_AUTH_TOKEN")
60
+ if os.environ.get("ANTHROPIC_API_KEY") == "":
61
+ protected.add("ANTHROPIC_API_KEY")
52
62
  for var in DANGEROUS_VARS:
53
63
  if var in protected:
54
64
  continue
@@ -116,7 +126,7 @@ def _require_ollama_preconditions() -> str:
116
126
 
117
127
  Refuses the bypass when:
118
128
  * ``OLLAMA_API_KEY`` is unset or empty.
119
- * ``ANTHROPIC_BASE_URL`` is pre-set to anything other than the pinned URL.
129
+ * ``ANTHROPIC_BASE_URL`` is pre-set to a non-localhost value.
120
130
 
121
131
  A non-empty ``ANTHROPIC_API_KEY`` in the parent env is **not** a refusal:
122
132
  ``_build_ollama_env`` strips every ``ANTHROPIC_*`` var from the returned
@@ -132,10 +142,10 @@ def _require_ollama_preconditions() -> str:
132
142
  "before running with provider='ollama'."
133
143
  )
134
144
  preset_base = os.environ.get("ANTHROPIC_BASE_URL")
135
- if preset_base and preset_base != OLLAMA_BASE_URL:
145
+ if preset_base and not _is_localhost_base_url(preset_base):
136
146
  raise RuntimeError(
137
- f"ANTHROPIC_BASE_URL={preset_base!r} does not match the pinned "
138
- f"{OLLAMA_BASE_URL!r}. Unset it or point it at the local daemon."
147
+ f"ANTHROPIC_BASE_URL={preset_base!r} does not point at a local "
148
+ f"daemon. Unset it or point it at localhost/127.0.0.1."
139
149
  )
140
150
  return token
141
151
 
@@ -222,14 +232,24 @@ def assert_single_workspace(
222
232
  )
223
233
 
224
234
 
235
+ _LOCALHOST_PREFIXES: tuple[str, ...] = (
236
+ "http://localhost:",
237
+ "http://127.0.0.1:",
238
+ "http://[::1]:",
239
+ )
240
+
241
+
225
242
  def _is_localhost_base_url(base_url: str | None) -> bool:
226
243
  """Return True when the ANTHROPIC_BASE_URL points at any localhost port.
227
244
 
228
- Deliberately lenient — any ``http://localhost:*`` prefix matches — because
229
- the workspace invariant is \"local endpoint\", not the strict :11434 the
230
- Ollama preflight refusal gate enforces.
245
+ Deliberately lenient — ``http://localhost:*``, ``http://127.0.0.1:*``,
246
+ and ``http://[::1]:*`` all match because the workspace invariant is
247
+ \"local endpoint\", not the strict :11434 the Ollama preflight refusal
248
+ gate enforces.
231
249
  """
232
- return base_url is not None and base_url.startswith("http://localhost:")
250
+ if base_url is None:
251
+ return False
252
+ return any(base_url.startswith(prefix) for prefix in _LOCALHOST_PREFIXES)
233
253
 
234
254
 
235
255
  def _log_localhost_short_circuit_once(state: dict[str, object]) -> None:
@@ -302,7 +322,7 @@ def assert_safe_environment_ollama() -> None:
302
322
  preset_base = os.environ.get("ANTHROPIC_BASE_URL")
303
323
  if not token:
304
324
  return
305
- if preset_base and preset_base != OLLAMA_BASE_URL:
325
+ if preset_base and not _is_localhost_base_url(preset_base):
306
326
  return
307
327
 
308
328
  os.environ["ANTHROPIC_AUTH_TOKEN"] = token
@@ -92,12 +92,15 @@ def _open_cycle_client(options_template: Any) -> Any:
92
92
  return ClaudeSDKClient(options=options_template)
93
93
 
94
94
 
95
- def _build_cycle_options(project_dir: Path) -> Any:
95
+ def _build_cycle_options(project_dir: Path, effective_model: str | None = None) -> Any:
96
96
  """Return cycle-scoped options for the shared ``ClaudeSDKClient``.
97
97
 
98
98
  ``ClaudeSDKClient`` locks options at open-time — per-query changes do not
99
99
  apply. The shared client therefore opens with:
100
100
 
101
+ - ``model``: the effective Ollama model tag (when on the Ollama codepath),
102
+ or ``None`` to let the SDK default (Anthropic Max path). Must be set at
103
+ open-time because per-query overrides are silently ignored.
101
104
  - ``system_prompt``: canonical ``claude_code`` preset with
102
105
  ``exclude_dynamic_sections=True`` (§2 cache-safe prefix).
103
106
  - ``extra_headers``: default betas (extended-cache-ttl + token-efficient-tools).
@@ -114,6 +117,9 @@ def _build_cycle_options(project_dir: Path) -> Any:
114
117
 
115
118
  Args:
116
119
  project_dir: Project root; used to resolve MCP servers.
120
+ effective_model: Ollama model tag to lock into the shared client
121
+ (threaded from cycle_loop). When ``None``, the SDK default
122
+ (Anthropic Max path) is used.
117
123
 
118
124
  Returns:
119
125
  A ``ClaudeAgentOptions`` instance (or duck-typed fallback) suitable
@@ -121,15 +127,18 @@ def _build_cycle_options(project_dir: Path) -> Any:
121
127
  """
122
128
  mcp_servers = build_mcp_servers(project_dir)
123
129
  allowed_tools: list[str] = list(_SHARED_CLIENT_ALLOWED_TOOLS) + mcp_tool_wildcards(mcp_servers)
124
- return make_agent_options(
130
+ kwargs: dict[str, Any] = dict(
125
131
  allowed_tools=allowed_tools,
126
132
  permission_mode="bypassPermissions",
127
133
  mcp_servers=mcp_servers,
128
134
  )
135
+ if effective_model is not None:
136
+ kwargs["model"] = effective_model
137
+ return make_agent_options(**kwargs)
129
138
 
130
139
 
131
140
  @contextlib.asynccontextmanager
132
- async def managed_shared_client(state: State, state_path: Path): # type: ignore[return]
141
+ async def managed_shared_client(state: State, state_path: Path, effective_model: str | None = None): # type: ignore[return]
133
142
  """Async context manager owning the full shared-client lifecycle.
134
143
 
135
144
  On entry: strips dangerous env vars (non-negotiable #1), opens one
@@ -151,6 +160,8 @@ async def managed_shared_client(state: State, state_path: Path): # type: ignore
151
160
  Args:
152
161
  state: Root state (mutated by mark/clear helpers).
153
162
  state_path: Path to ``state.json`` for atomic persistence.
163
+ effective_model: Ollama model tag to lock into the shared client.
164
+ When ``None``, the SDK default (Anthropic Max path) is used.
154
165
 
155
166
  Yields:
156
167
  The open ``ClaudeSDKClient`` instance.
@@ -158,7 +169,7 @@ async def managed_shared_client(state: State, state_path: Path): # type: ignore
158
169
  _env.strip_dangerous_env()
159
170
  # state.json lives at {project_dir}/.code-generator/state.json.
160
171
  project_dir = state_path.parent.parent
161
- options = _build_cycle_options(project_dir)
172
+ options = _build_cycle_options(project_dir, effective_model=effective_model)
162
173
  async with _open_cycle_client(options) as client:
163
174
  _state.mark_client_alive(state, state_path)
164
175
  try:
@@ -435,7 +435,9 @@ async def run_single_mode(
435
435
  state_path = project_dir / ".code-generator" / "state.json"
436
436
 
437
437
  if state.session_mode in ("shared", "batch"):
438
- async with managed_shared_client(state, state_path) as client:
438
+ async with managed_shared_client(
439
+ state, state_path, effective_model=effective_model
440
+ ) as client:
439
441
  await _run_phases(
440
442
  state,
441
443
  None,
@@ -665,7 +667,9 @@ async def _run_cycle_phases(
665
667
  log_prefix = f"cycle{cycle.id}_"
666
668
 
667
669
  if state.session_mode in ("shared", "batch"):
668
- async with managed_shared_client(state, state_path) as client:
670
+ async with managed_shared_client(
671
+ state, state_path, effective_model=effective_model
672
+ ) as client:
669
673
  await _run_phases(
670
674
  state,
671
675
  cycle,
@@ -13,6 +13,7 @@ from __future__ import annotations
13
13
  import asyncio
14
14
  import contextlib
15
15
  import json
16
+ import os
16
17
  import subprocess
17
18
  import time
18
19
  from typing import TYPE_CHECKING, Any
@@ -313,7 +314,16 @@ async def run(
313
314
  "CLI session starting (model=%s effort=%s max_turns=%s).", model, effort_display, max_turns
314
315
  )
315
316
 
316
- safe_env = _env.build_agent_env()
317
+ # Detect Ollama mode so build_agent_env() preserves the scoped localhost
318
+ # routing (ANTHROPIC_API_KEY="" + pinned BASE_URL). Without provider="ollama"
319
+ # the default "anthropic-max" path omits ANTHROPIC_API_KEY, which causes
320
+ # the CLI to reject non-Claude model tags or fall back to real credentials.
321
+ _provider: _env.Provider = (
322
+ "ollama"
323
+ if _env._is_localhost_base_url(os.environ.get("ANTHROPIC_BASE_URL"))
324
+ else "anthropic-max"
325
+ )
326
+ safe_env = _env.build_agent_env(provider=_provider)
317
327
 
318
328
  text_parts: list[str] = []
319
329
  result_holder: dict[str, Any] = {