CookSprite is a general, open-source tool for producing 2D sprites with AI.
CLAUDE.md is a compatibility symlink to this file; keep one agent contract.
Lowest usage burden wins. Design for three audiences, in this priority:
- Agents call it β fast, scriptable, one obvious way to do a thing.
- Humans use the web toolbox β pick a task, run, preview, light-edit. Never author node graphs.
- Contributors extend it β add a model adapter or a workflow without touching the other layers.
Fully general. Zero downstream-game assumptions. CookSprite must never hard-code a specific game's camera angle, canvas size, direction naming, actor pixel height, or content identity. Direction counts, canvas dimensions, frame rates, and naming are user-supplied config, never baked constants.
Simply First. One default route per capability. One owner per concern across the four layers. Delete an unselected route rather than keep it "just in case." Missing data or a failed inference surfaces an explicit error β never a silent fallback or a second hidden implementation.
- CookSprite produces sprites: directional clips, sprite sheets, and β the signature unit β sprite pairs (a diffuse frame plus a same-size normal map for dynamic lighting).
- It is an AI-generation tool, not a hand-drawing pixel editor. The web frontend previews, selects frames, does pixel-perfect cleanup, and can regenerate a single frame. Detailed hand-pixeling stays in dedicated editors (Aseprite) via standard PNG sprite-sheet round-trips.
- Reference frontends for the human editor: spritecook.ai and pixellab.ai.
- The frontend includes a three.js interactive preview: load a sprite + its normal map, drag a dynamic light source, watch normal-mapped shading in real time.
Model + Inference ββ[ /infer HTTP API ]βββΊ atomic capability, local OR remote (docker)
Workflow ββ[ typed tool graph ]βββΊ one minimal self-contained task
Frontend ββ[ triggers workflows ]βββΊ Web GUI (humans) + CLI/skill (agents)
Each layer talks to the next only through a stable contract (its ABI). You can swap a model, add a workflow, or replace the web UI without the other layers knowing. ComfyUI is not a dependency β see the ComfyUI section.
Two composition layers, same DAG shape. A task is a DAG of workflow-nodes; a workflow is a DAG of tool-nodes. Neither nests into itself.
Task β a user-facing goal, e.g. "reference image β a full sprite animation
β pack". A DAG of workflow-nodes; the unit a frontend triggers. A simple
β goal (textβimage) mounts ONE workflow; a big one mounts MANY.
βββ node β one slot in the task. Runs exactly one Workflow, chosen from
β `candidates` ([0] is the default; callers may pick another).
β Nodes wire one workflow's output into another's declared input.
βββ Workflow β one minimal end-to-end route; a FLAT graph of tools
β (never contains another workflow). May declare external
β `inputs` a task feeds via `$in.<name>`. Reusable across
β tasks and across nodes.
βββ Tool β the smallest unit that satisfies one minimal function,
with a typed input/output port (ComfyUI-like). Every tool
has a `kind`:
βββ kind="inference" β calls /infer (text2img, img2img,
β img2vid, upscale β¦). Names a model op that MANY
β model_ids can serve behind /infer.
βββ kind="deterministic" β a local, model-free step
(pixelize, crop, center-align, normal-estimate β¦).
Key decoupling: a task is independent of which model or which route fulfills each step. A workflow is task-independent and reusable; the model choice is a param on each inference tool.
Candidate selection: each task node lists one or more workflow candidates;
candidates[0] is the default. Humans and agents may pick another candidate by
node. No hidden auto-ranking.
Typed I/O: tools declare typed inputs/outputs (Image, ImageBatch, SpriteSheet, FrameSeq, Mask, NormalMap, Palette, β¦) so they compose safely.
backend/ Python β FastAPI /infer server, model adapters, model-op routing
workflow/ Python β workflow schema, tool library, runner, ComfyUI export
cli/ Python β agent-facing CLI + skill
web/ TypeScript β human toolbox, sprite preview, three.js light preview
docs/ open-source-facing documentation (public)
.agent-os/ dev-state docs (NEVER in git; ignored)
.agent-os/is branch/local development state, never in git, never in the public release tree.docs/is the open-source-facing documentation and IS committed.AGENTS.mdis the one contract;CLAUDE.mdis a symlink to it.- No model weights, secrets,
.env, generated outputs, or scratch in git.
ComfyUI is the most mature open-source generation ecosystem, so many users live
there. CookSprite does not depend on it and does not build on its
custom_nodes. Instead:
- The backend is a self-owned lightweight inference API (
/infer). - A translator exports a CookSprite workflow β ComfyUI API-format JSON
(
{node_id: {class_type, inputs}}, links as["node_id", output_index]). - This lets ComfyUI users run our workflows in their environment without us carrying ComfyUI's weight.
Rationale: ComfyUI's own architecture confirms inference-as-HTTP-API is right; its API-format workflow is nearly 1:1 with our "workflow = minimal function" concept, so a translator is cheap and keeps us light.
Minimal REST, async job model (generation β especially video β is long):
POST /infer { "op", "model_id", "inputs", "params" } β { "job_id" }
GET /jobs/{job_id} β status + progress
GET /jobs/{job_id}/result β { "outputs", "meta" }
- Engine: vLLM-Omni (covers FLUX.2 / WAN2.2 / LTX-2 / Qwen-Image / β¦ in one engine). Orchestration: Ray Serve (model pool + VRAM multiplexing + future scale-out).
- One unified API regardless of machine; dev deployment on H20 GPU.
- Each
opis atomic; oneopβ manymodel_ids (caller/workflow picks). - Adapters implement
(op, model_id) β resulton vLLM-Omni. - Sprite multi-inputs (control / normal / mask / reference) are first-class
inputs, not bolted on.
One prompt β single sprite β pixelize + normal-estimate β preview / light-edit, touching every layer (Op + Tool + workflow + frontend + CLI). The frontend adds a three.js interactive preview: load the sprite + normal map, drag a dynamic light source, watch normal-mapped shading update live.
- Recovery order: read this file β
.agent-os/project-index.mdβ activetodo.mdβ newestrun-log.mdβ the smallest owning schema/module/test. - Make the smallest final-form change and verify it. No dead code or routes.
- First-party Markdown stays below 500 lines.
- No commit, push, or history rewrite without explicit user instruction.