Metadata-Version: 2.4
Name: claude-code-generator
Version: 0.5.6
Summary: Orchestrator CLI that drives Claude Code end-to-end to generate whole projects from a requirements.md file.
Author: Silvio Baratto
License: MIT
Project-URL: Homepage, https://github.com/SilvioBaratto/code-generator
Project-URL: Repository, https://github.com/SilvioBaratto/code-generator
Project-URL: Issues, https://github.com/SilvioBaratto/code-generator/issues
Keywords: claude,claude-code,code-generation,llm,cli,orchestrator
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Code Generators
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: claude-agent-sdk<0.2.0,>=0.1.61
Requires-Dist: typer
Requires-Dist: rich
Provides-Extra: dev
Requires-Dist: pytest; extra == "dev"
Requires-Dist: pytest-asyncio; extra == "dev"
Requires-Dist: ruff; extra == "dev"
Provides-Extra: mcp
Requires-Dist: mcp<2.0,>=1.0; extra == "mcp"
Requires-Dist: serena-agent<2.0,>=1.1; extra == "mcp"
Provides-Extra: batch
Requires-Dist: anthropic>=0.35; extra == "batch"
Provides-Extra: all
Requires-Dist: claude-code-generator[batch,mcp]; extra == "all"
Dynamic: license-file

# code-generator

A Python CLI that orchestrates Claude Code end-to-end to generate a whole project from a `requirements.md` file. Five commands — `init`, `optimize`, `generate`, `review`, `status`. Works for any project type: Python CLI, FastAPI, Angular, NestJS, full-stack, finance, BAML/LLM.

> **Max subscription only.** This tool uses **exclusively** the Claude Max subscription. It strips every environment variable that could route a call through the API and aborts on startup if any are still present. There is no path to API credit billing — see [Safety constraints](#safety-constraints) below.

## Install

```bash
pipx install code-generator        # recommended
# or
pip install code-generator          # user-site
# or, from source
git clone git@github.com:SilvioBaratto/code-generator.git
cd code-generator && pip install -e ".[dev]"
```

### Optional: codebase graph (graphify)

Phases 0, 1, and 2 inject a knowledge-graph report from [graphify](https://github.com/safishamsi/graphify) for richer code orientation. When the graph is missing, the orchestrator falls back to a sentinel string and continues — nothing breaks.

**Install the CLI** (required to use graphify at all):

```bash
pipx install graphifyy   # CLI binary is `graphify`
```

**Seed the graph (one-time, per project)**: graphify's full LLM-driven build runs through the `/graphify` slash-command inside an AI assistant — *not* through the shell binary. From inside Claude Code (or any other graphify-supported assistant) run:

```
/graphify .
```

This produces `graphify-out/graph.json` and `graphify-out/GRAPH_REPORT.md`.

**Subsequent code-generator runs** will automatically refresh the graph with `graphify update .` (AST-only, no LLM cost). Doc / paper / image changes still need a manual `/graphify .` re-run inside your assistant.

Add to your project's `.gitignore`:

```
graphify-out/
```

## Authentication

```bash
# Claude Code (Max subscription)
claude auth login

# GitHub (SSH protocol)
gh auth login -h github.com -p ssh
gh config set git_protocol ssh
```

## Commands

### `code-generator init [--template TYPE] [--force]`

Scaffold `.code-generator/` in the current directory with a ready-to-fill `requirements.md`. Templates: `fastapi`, `angular`, `nestjs`, `fullstack`, `python-cli`, `finance`. Refuses to clobber an existing `.code-generator/` without `--force`.

```bash
code-generator init --template fastapi
$EDITOR .code-generator/requirements.md
```

### `code-generator optimize [--dry-run] [--force]`

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`.

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`.

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.

```bash
code-generator optimize --dry-run    # preview
code-generator optimize              # commit the rewrite
code-generator generate              # then run the pipeline
```

### `code-generator generate [flags]`

Read `.code-generator/requirements.md` and orchestrate Claude Code through the 0→7 phase pipeline:

| Phase | Action | Model |
|---|---|---|
| 0 | Complexity analysis (single vs multi-cycle) | Opus 4.7 |
| 1 | Planning — creates GitHub issues + milestone | Opus 4.7 |
| 2 | Per-issue review | Opus 4.7 |
| 3-4 | Implementation, fresh SDK session per issue (TDD) | Sonnet 4.6 |
| 5 | Closure + cross-module review | Opus 4.7 |
| 6 | Test suite, max 3 retries on failure | Sonnet 4.6 |
| 7 | Commit message + git add/commit/push | Opus 4.7 |

Every phase logs a completion summary with token counts (`in`, `cache_read`, `cache_write`, `out`) and persists them to `state.json`.

Flags:

| Flag | Description | Default |
|---|---|---|
| `--dry-run` | Run only Phase 0 + Phase 1 (planning) | false |
| `--phase N` | Resume from phase N | — |
| `--continue` | Resume from the last completed phase (reads `state.json`) | false |
| `--mode auto\|single\|multi-cycle` | Force a mode (default `auto` runs Phase 0 first) | auto |
| `--cycle N` | Resume from cycle N (multi-cycle only) | — |
| `--max-turns N` | Opt-in per-session turn cap for debugging or strict cost control (positive integer); omit for no cap | — |

#### Turn budgets

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.

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.

If the Max subscription hits a rate limit, the tool **pauses** — it persists the session id and `paused_until` timestamp atomically to `.code-generator/state.json`, sleeps until the window resets, and resumes with `--resume <session_id>`. A killed process will resume on its own when re-run.

### `code-generator review [--create-issues] [--severity LEVEL]`

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.

### `code-generator status`

Print a Rich table with the current mode, current cycle, current phase, open/closed issue counts, the rate-limit pause state (with minutes remaining if paused), per-cycle token consumption columns (`in | cache_read | cache_write | out`), wall-clock elapsed time, and any `last_error` highlighted in red.

## Running against Ollama Pro

An opt-in subcommand, `code-generator generate ollama`, runs the full 0→7 pipeline against **one** Ollama-hosted model instead of the Anthropic Max subscription. This is the only supported way to bypass the Max-subscription invariant and is gated by `provider == "ollama"` inside `env.py`.

### One-time setup

1. Install the Ollama daemon (≥ 0.14.0) and start it on the default endpoint `http://localhost:11434`.
2. Sign the daemon into your Ollama Pro account — required for any `:cloud` model:

   ```bash
   ollama signin
   ```

3. Export your existing `OLLAMA_API_KEY` (the same secret you already use elsewhere — no new secret is introduced):

   ```bash
   export OLLAMA_API_KEY=...   # typically set once in ~/.zshrc
   ```

Preflight refuses to run if the daemon is unreachable, not signed in, or `OLLAMA_API_KEY` is empty — fix the message it prints and re-run.

### Worked examples

```bash
# Plan + implement a whole repo on a cloud-hosted 480B coding model
code-generator generate ollama --model "qwen3-coder:480b:cloud"

# Same pipeline on a different cloud model
code-generator generate ollama --model "gpt-oss:120b-cloud"
```

The `--model` tag you pass drives **every** phase (0 through 7). There is no per-phase override on this codepath: single-model is the whole point. The tag is persisted to `state.json` as `CycleState.ollama_model` so `code-generator generate ollama --continue` resumes with the same model without re-typing it.

### What is overridden vs. preserved

- **Overridden under `provider == "ollama"`:** non-negotiable #1 (Max-only env strip is narrowed to `ANTHROPIC_AUTH_TOKEN` / `ANTHROPIC_BASE_URL` passthrough), #4 (no Anthropic overage telemetry — replaced by turn-count + wall-clock budgets), #8 (fixed-model-per-phase — replaced by single-model routing).
- **Preserved on every path:** #2 (never `--bare`), #3 (YOLO permissions), #5 (wait-and-resume on 429), #6 (fresh context per issue), #7 (atomic state writes), #9 (no default `max_turns`).

## Safety constraints

The tool enforces nine non-negotiables (see `CLAUDE.md` for the full list):

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.
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.
3. **YOLO mode always.** Every SDK call uses `permission_mode="bypassPermissions"`; the subprocess fallback uses `--dangerously-skip-permissions`.
4. **Overage protection.** On every `RateLimitEvent`, the tool checks `info.overage_status` and aborts immediately if it is anything other than `None` or `"disabled"`. Reference incident: [anthropics/claude-code#37686](https://github.com/anthropics/claude-code/issues/37686) — a user burned $1,800 in two days because billing overage was silently enabled.
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.
6. **Fresh SDK session per issue.** The implementation phase never reuses conversational context across issues — each issue is a `/clear`-equivalent fresh session.
7. **Atomic state writes.** `.code-generator/state.json` is updated via `tmp → os.replace(tmp, STATE)` so a crash mid-write cannot corrupt it.
8. **Fixed model per phase.** Opus 4.7 for phases 0/1/2/5/7; Sonnet 4.6 for phases 3/4/6.

## Troubleshooting

**Startup fails with "dangerous environment variables present".** A previous shell session exported `ANTHROPIC_API_KEY` (or another billing-routing variable). `unset` it and try again — the tool is intentionally strict so a stray export never costs you money.

**Rate limit reached.** Run `code-generator status` to see how many minutes remain on the current pause. The next `code-generator generate --continue` will wait out the rest of the window and resume the same session automatically.

**`gh issue create` fails.** Confirm `gh auth status` reports an authenticated SSH session for `github.com`, and that the current directory is inside a repo with a default remote configured.

**Tests don't pass after Phase 6.** The orchestrator skips Phase 7 (commit) when the test runner reports persistent failures. Fix the failing tests manually, then run `code-generator generate --continue` to re-enter from where it stopped.

## Project layout

```
src/code_generator/
├── cli.py                # Typer entry point: init, generate, review, status
├── env.py                # DANGEROUS_VARS, build_agent_env, assert_safe_environment
├── state.py              # State dataclasses + atomic load/save
├── prompts/              # Packaged prompt-phase-*.md files + load_prompt
├── templates/            # Project templates for `init`
├── logging_setup.py      # Per-phase log files under .code-generator/logs/
├── gh.py                 # Subprocess wrapper for issues, milestones, labels
├── agents.py             # Tech-stack detector + agent selection matrix
├── runner/
│   ├── sdk_runner.py     # claude-agent-sdk wrapper, RateLimitEvent handling
│   ├── subprocess_runner.py  # CLI fallback, stream-json parser
│   ├── rate_limit.py     # Wait-and-resume main loop
│   └── retry.py          # Backoff + circuit breaker
├── orchestrator/
│   ├── phase0_complexity.py  # single vs multi-cycle decision
│   ├── phase1_plan.py        # milestone + issues
│   ├── phase2_review.py      # per-issue review
│   ├── phase3_4_implement.py # TDD loop, fresh session per issue
│   ├── phase5_closure.py     # closure + fix-issue feedback loop
│   ├── phase6_test.py        # test runner, max 3 retries
│   ├── phase7_commit.py      # Opus commit message + push with rebase retry
│   └── cycle_loop.py         # multi-cycle driver
└── commands/             # init, optimize, status, generate, review (Typer commands)
```

## Development

```bash
git clone git@github.com:SilvioBaratto/code-generator.git
cd code-generator
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest -q
ruff check src tests
```

## Benchmarking

```bash
code-generator bench --fake --cycles 3 --output bench.json
```

## Reference

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.

## License

MIT.
