First step of the model-agnostic image-generation framework. Lands the
plumbing other components (skill, ComfyUI/Replicate adapters, agents)
will plug into:
- internal/backend: Backend interface (Request/Result), thread-safe
Registry with init-time Register, plus a Mock reference adapter that
emits a deterministic gradient PNG for smoke tests.
- internal/config: YAML loader for ~/.config/imagen.yaml. Framework owns
default_backend + output settings + a per-backend block; each adapter
owns the schema below its own block via BackendSpec.Raw.
- internal/output: filename templating ({date}/{time}/{slug}/{seed}/
{backend}/{ext}), JSON metadata sidecar, --output override path.
- internal/prompt: embedded styles.yaml, style-preset suffix application.
- internal/server: 501 stub — HTTP surface lands in a follow-up issue.
- cmd/imagen: generate / backends / config (init|validate|path) / serve
/ version subcommands. Stdlib-only flag parsing with a small helper to
honour positional prompt args ahead of flags (matches the issue spec).
- Tests for output (slug, naming template, sidecar), backend (mock PNG
validity + determinism, registry build + duplicate panic), config
(round-trip + validation), prompt (style apply + unknown-style error).
- CLAUDE.md, README.md, docs/architecture.md, docs/usage.md, Makefile.
Acceptance criteria from #211:
1. go build ./... — clean
2. imagen backends — lists registered backends, exits 0
3. imagen generate "test prompt" --backend mock --output /tmp/x.png —
writes a 1024x1024 PNG plus an x.png.json sidecar
4. imagen config init | imagen config validate — round-trips cleanly
5. CLAUDE.md "Adding a new adapter" — six-step recipe
3.1 KiB
3.1 KiB
Using imagen
Subcommands
imagen generate <prompt> [flags] generate one image
imagen backends list configured + registered backends
imagen config init print a sample imagen.yaml on stdout
imagen config validate parse + validate the active config
imagen config path print the resolved config path
imagen serve [--addr :8080] (stub) start the HTTP server
imagen version print version
generate flags
| Flag | Default | Notes |
|---|---|---|
--backend |
default_backend from config |
Instance name from imagen.yaml |
--size |
1024x1024 |
WxH |
--seed |
0 (= backend default) |
|
--steps |
0 (= backend default) |
|
--style |
empty | One of imagen config init's style names |
--negative |
empty | Negative prompt (ignored by some adapters) |
--output |
empty (= use naming template) | Explicit path |
--no-sidecar |
false |
Skip the JSON sidecar even if config enables it |
--config |
~/.config/imagen.yaml |
Override config path |
Examples
# Quick smoke test — mock backend ships in-tree
imagen generate "test" --backend mock --output /tmp/x.png
# Real generation, FLUX-schnell on mRock via ComfyUI
imagen generate "a wide editorial blog header about RAG systems" \
--backend flux-schnell-local \
--style blog-header \
--size 1536x768
# Explicit seed for reproducibility
imagen generate "a cat in a fishbowl" --backend mock --seed 42 --output /tmp/cat.png
Config
A complete sample is in imagen config init. Adapters get only their own
sub-block — see ../CLAUDE.md for the contract.
Naming template
output.naming placeholders:
| Placeholder | Replaced with |
|---|---|
{date} |
2026-05-08 |
{time} |
143015 (no separators) |
{slug} |
lowercased ASCII prompt, ≤ 40 chars |
{seed} |
seed actually used |
{backend} |
backend instance name |
{ext} |
file extension matching Result.MimeType |
Unknown placeholders are left literal.
Credentials
API-backed adapters read tokens from env vars referenced by the config
(api_token_env, api_key_env). Never put a token in imagen.yaml.
export REPLICATE_API_TOKEN=...
imagen generate "a cat" --backend flux-dev-replicate