Metadata-Version: 2.4
Name: cgh-codegen
Version: 0.1.2
Summary: Pattern-matched code generation for cgh: a cheap model writes boilerplate that mirrors a reference file cgh picks from the graph
Author-email: Joy Ndjama <joy.ndjama@altikva.com>
License-Expression: MIT
Requires-Python: >=3.11
Description-Content-Type: text/markdown

# cgh-codegen

A cgh plugin that delegates predictable, pattern-following code (tests,
stubs, config, boilerplate) to a cheap model so the primary model spends
no tokens producing it. Its distinguishing move: cgh picks the reference
file to mirror straight from the code graph, so you do not have to name it.

Installs through cgh's plugin entry point. Inert without cgh.

## Surfaces

### `cgh codegen pick`

Report the existing file a generator should mirror for a target, and why.

```
cgh codegen pick --target tests/test_user_service.py
# reference: tests/test_order_service.py
# defines a matching symbol, sibling in the same directory
```

The pick combines two signals: the graph (a file defining a symbol
related to the target's name) and the filesystem (a sibling of the same
kind in the target's directory). It degrades to a filesystem-only pick
when the graph is not readable (no index yet, or an owner holds the write
lock). Pass `--reference` to validate a specific file instead.

### `cgh codegen gen`

Generate a file from a spec, mirroring the reference, and write it.

```
cgh codegen gen --spec "pytest tests for UserService: create, update, delete" \
                  --target tests/test_user_service.py
```

Two checks run before anything reaches a model:

- **Secret check, always.** The reference, the file being extended and the
  spec are scanned with built-in regex patterns for known secret formats:
  private key blocks, AWS access key ids, GCP service-account key files,
  GitHub, Slack and Stripe live tokens, bearer tokens, and `password` /
  `secret` / `api_key` / `token` assignments to a real-looking literal
  (empty values, `changeme`, `xxx`, `${...}` templates and env lookups are
  ignored). A hit refuses the run with the file and line, never the value,
  for every backend, local included, and whatever the egress setting. An
  auto-picked reference that fails falls back to the next candidate. It
  needs no other plugin. The check is best effort, not a guarantee: a
  secret in a format it has no pattern for (another provider's token, a
  key split across lines, an encoded value) goes through.
- **Egress gate, cloud backends only.** A reference carrying a
  `confidential`, block-severity or PII finding is refused (findings come
  from cgh-pii or cgh-classify when they scan at index). `egress = "strict"`
  under `[plugin.codegen]` only sends files labeled non-confidential.
  Absent or `"open"` is the default; any other value is treated as
  `"strict"`, so a typo fails closed.

An existing target is never overwritten without `--force`; `--stdout`
prints instead of writing.

`--extend` grows a file that already exists instead of writing a new one:

```
cgh codegen gen --extend --target tests/test_user_service.py \
                  --spec "add a test for the soft-delete path" \
                  --verify "pytest tests/test_user_service.py -q"
```

The file itself goes to the model as the thing to add to, and the model
returns only the block to append, so nothing already in the file passes
through the model's output and nothing can be dropped from it. The block
lands before a trailing `if __name__ == "__main__":` guard rather than after
it. With `--verify`, a check that never passes restores the original: a
damaged existing file is worse than no change, which is the opposite of the
tradeoff for a new file, where the failed draft is left for you to read.
Anything the addition needs must already be imported in the file.

Configure the backend in `.codegraph/config.toml`:

```toml
[plugin.codegen]
command = "claude -p"   # any agent CLI, invoked with the prompt on stdin
```

The generated code is a proposal. Verify it by running the type-checker,
linter, or tests, never by trusting that it is correct because a later check
was green. This matters most for generated tests: a green run of tests you
did not read proves nothing.

### `codegen_pick` and `codegen_write` (MCP tools)

`codegen_pick(target, reference?)` returns the selection as JSON.
`codegen_write(spec, target, reference?, force?)` generates and writes the
file, returning what it wrote, the reference used, the egress decision, and
the cost. Both run inside the owner, so the graph read reuses its
connection.

## License

MIT. Plugins that interact with cgh only through the documented plugin
interfaces are not derivative works of cgh.
