claude-code-generator 0.5.0__tar.gz → 0.5.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.
Files changed (179) hide show
  1. {claude_code_generator-0.5.0/src/claude_code_generator.egg-info → claude_code_generator-0.5.1}/PKG-INFO +1 -1
  2. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/pyproject.toml +1 -1
  3. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1/src/claude_code_generator.egg-info}/PKG-INFO +1 -1
  4. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/__init__.py +1 -1
  5. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/commands/_dispatch.py +59 -11
  6. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_dispatch_graph_report.py +59 -16
  7. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/LICENSE +0 -0
  8. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/README.md +0 -0
  9. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/setup.cfg +0 -0
  10. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/claude_code_generator.egg-info/SOURCES.txt +0 -0
  11. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/claude_code_generator.egg-info/dependency_links.txt +0 -0
  12. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/claude_code_generator.egg-info/entry_points.txt +0 -0
  13. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/claude_code_generator.egg-info/requires.txt +0 -0
  14. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/claude_code_generator.egg-info/top_level.txt +0 -0
  15. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/agents.py +0 -0
  16. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/cli.py +0 -0
  17. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/commands/__init__.py +0 -0
  18. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/commands/_bench_io.py +0 -0
  19. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/commands/_crash_recovery.py +0 -0
  20. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/commands/_detect.py +0 -0
  21. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/commands/_resume.py +0 -0
  22. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/commands/_validators.py +0 -0
  23. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/commands/bench.py +0 -0
  24. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/commands/bench_compare.py +0 -0
  25. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/commands/bench_export.py +0 -0
  26. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/commands/generate.py +0 -0
  27. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/commands/init.py +0 -0
  28. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/commands/optimize.py +0 -0
  29. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/commands/review.py +0 -0
  30. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/commands/status.py +0 -0
  31. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/effort.py +0 -0
  32. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/env.py +0 -0
  33. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/gh/__init__.py +0 -0
  34. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/gh/core.py +0 -0
  35. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/gh/issues.py +0 -0
  36. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/gh/labels.py +0 -0
  37. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/gh/milestones.py +0 -0
  38. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/git_ops.py +0 -0
  39. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/logging_setup.py +0 -0
  40. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/memory.py +0 -0
  41. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/orchestrator/__init__.py +0 -0
  42. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/orchestrator/_client_lifecycle.py +0 -0
  43. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/orchestrator/_comments.py +0 -0
  44. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/orchestrator/_memory_writers.py +0 -0
  45. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/orchestrator/_phase5_precommit.py +0 -0
  46. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/orchestrator/cycle_loop.py +0 -0
  47. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/orchestrator/cycle_prompts.py +0 -0
  48. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/orchestrator/ollama_budget.py +0 -0
  49. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/orchestrator/phase0_complexity.py +0 -0
  50. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/orchestrator/phase1_plan.py +0 -0
  51. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/orchestrator/phase2_review.py +0 -0
  52. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/orchestrator/phase3_4_implement.py +0 -0
  53. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/orchestrator/phase5_closure.py +0 -0
  54. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/orchestrator/phase6_test.py +0 -0
  55. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/orchestrator/phase7_commit.py +0 -0
  56. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/preflight.py +0 -0
  57. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/prompts/__init__.py +0 -0
  58. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/prompts/hashes.py +0 -0
  59. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/prompts/prompt-cycle-specializer.md +0 -0
  60. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/prompts/prompt-optimize-requirements.md +0 -0
  61. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/prompts/prompt-phase-0-complexity.md +0 -0
  62. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/prompts/prompt-phase-1-planning.md +0 -0
  63. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/prompts/prompt-phase-2-batch-review.md +0 -0
  64. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/prompts/prompt-phase-3-implementation.md +0 -0
  65. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/prompts/prompt-phase-5-final-review.md +0 -0
  66. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/prompts/prompt-phase-6-test.md +0 -0
  67. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/prompts/prompt-phase-7-commit.md +0 -0
  68. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/prompts/prompt-review.md +0 -0
  69. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/repo_info.py +0 -0
  70. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/requirements_structure.py +0 -0
  71. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/runner/__init__.py +0 -0
  72. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/runner/_telemetry.py +0 -0
  73. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/runner/batch.py +0 -0
  74. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/runner/fake_runner.py +0 -0
  75. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/runner/mcp.py +0 -0
  76. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/runner/message_parsing.py +0 -0
  77. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/runner/options.py +0 -0
  78. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/runner/protocol.py +0 -0
  79. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/runner/rate_limit.py +0 -0
  80. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/runner/retry.py +0 -0
  81. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/runner/sdk_runner.py +0 -0
  82. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/runner/soft_reset.py +0 -0
  83. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/runner/state_guard.py +0 -0
  84. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/runner/subprocess_runner.py +0 -0
  85. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/runner/types.py +0 -0
  86. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/runner/utils.py +0 -0
  87. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/state.py +0 -0
  88. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/state_retention.py +0 -0
  89. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/templates/__init__.py +0 -0
  90. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/templates/angular.md +0 -0
  91. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/templates/base.md +0 -0
  92. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/templates/fastapi.md +0 -0
  93. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/templates/finance.md +0 -0
  94. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/templates/fullstack.md +0 -0
  95. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/templates/nestjs.md +0 -0
  96. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/src/code_generator/templates/python-cli.md +0 -0
  97. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_agents.py +0 -0
  98. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_bench.py +0 -0
  99. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_bench_compare.py +0 -0
  100. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_bench_export.py +0 -0
  101. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_bench_fixture.py +0 -0
  102. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_bench_regression.py +0 -0
  103. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_changelog.py +0 -0
  104. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_claude_md.py +0 -0
  105. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_client_lifecycle.py +0 -0
  106. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_comments.py +0 -0
  107. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_commit_message.py +0 -0
  108. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_crash_recovery.py +0 -0
  109. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_cycle_loop.py +0 -0
  110. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_cycle_loop_multicycle.py +0 -0
  111. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_cycle_ollama_model.py +0 -0
  112. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_cycle_prompts.py +0 -0
  113. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_delta_planning.py +0 -0
  114. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_dependencies.py +0 -0
  115. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_detect.py +0 -0
  116. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_docs_no_default_max_turns.py +0 -0
  117. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_docs_ollama_model_guide.py +0 -0
  118. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_docs_ollama_pro.py +0 -0
  119. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_effective_model_routing.py +0 -0
  120. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_effort.py +0 -0
  121. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_env.py +0 -0
  122. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_generate.py +0 -0
  123. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_generate_ollama.py +0 -0
  124. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_generate_resume.py +0 -0
  125. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_gh.py +0 -0
  126. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_gh_labels.py +0 -0
  127. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_gh_milestones.py +0 -0
  128. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_gh_repo_threading.py +0 -0
  129. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_gh_submodules.py +0 -0
  130. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_git_ops.py +0 -0
  131. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_init.py +0 -0
  132. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_logging_setup.py +0 -0
  133. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_max_turns_cli_flag.py +0 -0
  134. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_mcp.py +0 -0
  135. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_memory.py +0 -0
  136. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_memory_writers.py +0 -0
  137. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_message_parsing.py +0 -0
  138. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_no_max_turns_in_call_sites.py +0 -0
  139. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_no_max_turns_literal.py +0 -0
  140. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_non_goals_grep_guard.py +0 -0
  141. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_ollama_budget.py +0 -0
  142. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_ollama_rate_limit.py +0 -0
  143. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_optimize.py +0 -0
  144. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_options.py +0 -0
  145. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_phase0.py +0 -0
  146. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_phase1.py +0 -0
  147. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_phase2.py +0 -0
  148. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_phase3_4.py +0 -0
  149. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_phase5.py +0 -0
  150. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_phase5_precommit.py +0 -0
  151. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_phase6.py +0 -0
  152. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_phase7.py +0 -0
  153. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_phase_mcp_regression.py +0 -0
  154. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_phase_token_logging.py +0 -0
  155. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_preflight.py +0 -0
  156. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_preflight_ollama.py +0 -0
  157. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_prompt_drift.py +0 -0
  158. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_prompt_prefix_snapshots.py +0 -0
  159. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_prompt_prefix_stability.py +0 -0
  160. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_prompts.py +0 -0
  161. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_rate_limit.py +0 -0
  162. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_repo_info.py +0 -0
  163. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_requirements_structure.py +0 -0
  164. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_retry.py +0 -0
  165. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_review.py +0 -0
  166. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_runner_protocol.py +0 -0
  167. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_runner_protocol_annotations.py +0 -0
  168. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_runner_types.py +0 -0
  169. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_runner_utils.py +0 -0
  170. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_sdk_runner.py +0 -0
  171. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_sdk_runner_shared.py +0 -0
  172. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_session_mode.py +0 -0
  173. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_state.py +0 -0
  174. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_state_guard.py +0 -0
  175. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_state_retention.py +0 -0
  176. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_status.py +0 -0
  177. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_subprocess_runner.py +0 -0
  178. {claude_code_generator-0.5.0 → claude_code_generator-0.5.1}/tests/test_telemetry.py +0 -0
  179. {claude_code_generator-0.5.0 → claude_code_generator-0.5.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.5.0
3
+ Version: 0.5.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
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "claude-code-generator"
7
- version = "0.5.0"
7
+ version = "0.5.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" }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: claude-code-generator
3
- Version: 0.5.0
3
+ Version: 0.5.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
@@ -1,3 +1,3 @@
1
1
  """code-generator: orchestrator CLI for end-to-end project generation."""
2
2
 
3
- __version__ = "0.5.0"
3
+ __version__ = "0.5.1"
@@ -37,23 +37,59 @@ __all__ = ["dispatch_async", "dispatch_orchestrator"]
37
37
  _GRAPHIFY_TIMEOUT = int(os.environ.get("CODE_GENERATOR_GRAPHIFY_TIMEOUT", "600"))
38
38
 
39
39
 
40
+ def _graphify_command(project_dir: Path) -> list[str]:
41
+ """Return the right graphify CLI invocation based on whether a prior graph exists.
42
+
43
+ Graphify's ``--update`` flag *requires* an existing ``graph.json`` to
44
+ merge into ("re-extract only changed files, merge into existing graph").
45
+ On a virgin project tree it fails with exit 1. We detect that case by
46
+ looking for ``graphify-out/graph.json`` and skipping ``--update`` on the
47
+ first run.
48
+
49
+ Args:
50
+ project_dir: Project root directory.
51
+
52
+ Returns:
53
+ The argv list to pass to ``subprocess.run``.
54
+ """
55
+ graph_json = project_dir / "graphify-out" / "graph.json"
56
+ base = ["graphify", str(project_dir), "--no-viz"]
57
+ if graph_json.exists():
58
+ base.append("--update")
59
+ return base
60
+
61
+
62
+ def _decode_stderr(stderr: bytes | str | None) -> str:
63
+ """Decode subprocess stderr to a short single-line string for logging."""
64
+ if stderr is None:
65
+ return ""
66
+ text = stderr.decode("utf-8", errors="replace") if isinstance(stderr, bytes) else stderr
67
+ text = text.strip().replace("\n", " | ")
68
+ return text[:500]
69
+
70
+
40
71
  def _compute_and_persist_graph_report(project_dir: Path, log: logging.Logger) -> None:
41
72
  """Build the codebase graph via graphify and persist it to memories.
42
73
 
43
- Invokes ``graphify <project_dir> --update --no-viz`` to (re)build
44
- ``graphify-out/GRAPH_REPORT.md`` and copies the resulting markdown into
74
+ Invokes the ``graphify`` CLI to (re)build ``graphify-out/GRAPH_REPORT.md``
75
+ and copies the resulting markdown into
45
76
  ``.code-generator/memories/cycle-repo-map.md`` so Phases 0, 1, 2 can read
46
77
  it via :func:`code_generator.memory.read_cycle_repomap`.
47
78
 
48
- Incremental builds rely on graphify's own SHA256-keyed cache in
49
- ``graphify-out/cache/`` — the ``--update`` flag short-circuits unchanged
50
- files, so repeated invocations on a clean tree are nearly free. We
51
- deliberately do *not* call ``graphify check-update`` because it is an
52
- undocumented subcommand (see graphify issue #277) and not part of the
53
- stable CLI surface.
79
+ Two modes:
80
+
81
+ - **First run** (no ``graphify-out/graph.json``): full build via
82
+ ``graphify <path> --no-viz``. ``--update`` is *not* added because it
83
+ requires a prior graph to merge into passing it on a virgin tree
84
+ makes graphify exit 1.
85
+ - **Incremental** (graph.json exists): ``graphify <path> --update
86
+ --no-viz``. Graphify's SHA256-keyed cache in ``graphify-out/cache/``
87
+ keeps subsequent runs cheap.
54
88
 
55
89
  Falls back to :data:`code_generator.memory.REPOMAP_FALLBACK` on any
56
90
  failure (binary missing, timeout, non-zero exit, missing report file).
91
+ Stderr from graphify is captured and logged at WARN level on failure so
92
+ the user can diagnose without re-running by hand.
57
93
 
58
94
  Auth: graphify inherits the parent process env (Claude Code OAuth
59
95
  subscription). Do **not** strip ``ANTHROPIC_*`` here — graphify is a
@@ -79,7 +115,7 @@ def _compute_and_persist_graph_report(project_dir: Path, log: logging.Logger) ->
79
115
  _memory.write_memory_file(memories_dir, "cycle-repo-map.md", _memory.REPOMAP_FALLBACK)
80
116
  return
81
117
 
82
- cmd = ["graphify", str(project_dir), "--update", "--no-viz"]
118
+ cmd = _graphify_command(project_dir)
83
119
  try:
84
120
  log.info("graph-report: building (cmd=%s)", " ".join(cmd))
85
121
  subprocess.run( # noqa: S603
@@ -89,8 +125,20 @@ def _compute_and_persist_graph_report(project_dir: Path, log: logging.Logger) ->
89
125
  capture_output=True,
90
126
  check=True,
91
127
  )
92
- except (subprocess.CalledProcessError, subprocess.TimeoutExpired) as exc:
93
- log.warning("graph-report: graphify subprocess failed (%s); using fallback", exc)
128
+ except subprocess.CalledProcessError as exc:
129
+ stderr = _decode_stderr(exc.stderr)
130
+ log.warning(
131
+ "graph-report: graphify exited %d; using fallback. stderr: %s",
132
+ exc.returncode,
133
+ stderr or "<empty>",
134
+ )
135
+ _memory.write_memory_file(memories_dir, "cycle-repo-map.md", _memory.REPOMAP_FALLBACK)
136
+ return
137
+ except subprocess.TimeoutExpired as exc:
138
+ log.warning(
139
+ "graph-report: graphify timed out after %ss; using fallback",
140
+ exc.timeout,
141
+ )
94
142
  _memory.write_memory_file(memories_dir, "cycle-repo-map.md", _memory.REPOMAP_FALLBACK)
95
143
  return
96
144
  except (FileNotFoundError, OSError) as exc:
@@ -4,18 +4,12 @@ The helper shells out to the ``graphify`` CLI to (re)build
4
4
  ``graphify-out/GRAPH_REPORT.md`` and copies the result into
5
5
  ``.code-generator/memories/cycle-repo-map.md``.
6
6
 
7
- Graphify's own SHA256-keyed cache makes repeated invocations cheap on
8
- unchanged source, so we always invoke ``graphify <path> --update --no-viz``
9
- and rely on the tool's internal incrementalism (no ``check-update`` call —
10
- that subcommand is undocumented; see graphify issue #277).
11
-
12
- These tests cover each branch:
13
- - happy path (writes the report into memories)
14
- - binary missing (writes fallback)
15
- - timeout (writes fallback)
16
- - non-zero exit (writes fallback)
17
- - missing report after a successful exit (writes fallback)
18
- - inherited-env: no env stripping (graphify uses parent OAuth)
7
+ Two invocation modes:
8
+ - **First run** (no ``graphify-out/graph.json``): ``graphify <path> --no-viz``
9
+ - **Incremental** (graph.json exists): ``graphify <path> --update --no-viz``
10
+
11
+ The ``--update`` flag merges into an existing graph and fails on a virgin
12
+ tree, so we detect first-run via ``graph.json`` existence.
19
13
  """
20
14
 
21
15
  from __future__ import annotations
@@ -44,10 +38,10 @@ def _read_persisted(project_dir: Path) -> str:
44
38
  class TestGraphReportBuild:
45
39
  """Behaviour of _compute_and_persist_graph_report under each branch."""
46
40
 
47
- def test_happy_path_builds_and_persists_report(
41
+ def test_first_run_uses_full_build_without_update_flag(
48
42
  self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
49
43
  ) -> None:
50
- """Successful graphify run copies GRAPH_REPORT.md into memories/."""
44
+ """First run (no graph.json) invokes `graphify <path> --no-viz` (no --update)."""
51
45
  monkeypatch.setattr(_dispatch.shutil, "which", lambda _name: "/usr/bin/graphify")
52
46
 
53
47
  commands_seen: list[list[str]] = []
@@ -63,13 +57,41 @@ class TestGraphReportBuild:
63
57
 
64
58
  _dispatch._compute_and_persist_graph_report(tmp_path, _logger())
65
59
 
66
- # Single invocation: no check-update, just the build.
67
60
  assert len(commands_seen) == 1
68
61
  assert commands_seen[0][0] == "graphify"
69
- assert "--update" in commands_seen[0]
70
62
  assert "--no-viz" in commands_seen[0]
63
+ assert "--update" not in commands_seen[0], (
64
+ "first run must not pass --update — graphify exits 1 without an existing graph"
65
+ )
71
66
  assert _read_persisted(tmp_path) == "# fresh report\n"
72
67
 
68
+ def test_incremental_run_uses_update_flag(
69
+ self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
70
+ ) -> None:
71
+ """When graph.json already exists, the run uses `--update --no-viz`."""
72
+ report_dir = tmp_path / "graphify-out"
73
+ report_dir.mkdir(parents=True)
74
+ (report_dir / "graph.json").write_text("{}", encoding="utf-8")
75
+ (report_dir / "GRAPH_REPORT.md").write_text("# old report\n", encoding="utf-8")
76
+
77
+ monkeypatch.setattr(_dispatch.shutil, "which", lambda _name: "/usr/bin/graphify")
78
+
79
+ commands_seen: list[list[str]] = []
80
+
81
+ def _fake_run(cmd: list[str], **_kwargs: object) -> subprocess.CompletedProcess[bytes]:
82
+ commands_seen.append(cmd)
83
+ (report_dir / "GRAPH_REPORT.md").write_text("# updated report\n", encoding="utf-8")
84
+ return subprocess.CompletedProcess(args=cmd, returncode=0, stdout=b"", stderr=b"")
85
+
86
+ monkeypatch.setattr(_dispatch.subprocess, "run", _fake_run)
87
+
88
+ _dispatch._compute_and_persist_graph_report(tmp_path, _logger())
89
+
90
+ assert len(commands_seen) == 1
91
+ assert "--update" in commands_seen[0]
92
+ assert "--no-viz" in commands_seen[0]
93
+ assert _read_persisted(tmp_path) == "# updated report\n"
94
+
73
95
  def test_binary_missing_writes_fallback(
74
96
  self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
75
97
  ) -> None:
@@ -119,6 +141,27 @@ class TestGraphReportBuild:
119
141
 
120
142
  assert _read_persisted(tmp_path) == REPOMAP_FALLBACK
121
143
 
144
+ def test_failure_logs_graphify_stderr(
145
+ self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch, caplog: pytest.LogCaptureFixture
146
+ ) -> None:
147
+ """On non-zero exit, graphify's stderr must appear in the log warning."""
148
+ monkeypatch.setattr(_dispatch.shutil, "which", lambda _name: "/usr/bin/graphify")
149
+
150
+ stderr_msg = b"Error: graph.json not found, cannot --update"
151
+
152
+ def _fake_run(cmd: list[str], **_kwargs: object) -> subprocess.CompletedProcess[bytes]:
153
+ raise subprocess.CalledProcessError(returncode=1, cmd=cmd, stderr=stderr_msg)
154
+
155
+ monkeypatch.setattr(_dispatch.subprocess, "run", _fake_run)
156
+
157
+ with caplog.at_level("WARNING"):
158
+ _dispatch._compute_and_persist_graph_report(tmp_path, _logger())
159
+
160
+ warnings = [r.getMessage() for r in caplog.records if r.levelname == "WARNING"]
161
+ assert any("graph.json not found" in w for w in warnings), (
162
+ f"stderr from graphify must be in the log warning. Got: {warnings}"
163
+ )
164
+
122
165
  def test_missing_report_after_success_writes_fallback(
123
166
  self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
124
167
  ) -> None: