Cost-based routing, approval before spending, a ledger, and the prompt saved next to each file.

A skill is a folder of Markdown files that works as an operating manual: the agent rereads it each time, so rules written once apply every time. This one covers images and video—and, most importantly, what tends to go wrong around them.
Chooses the cheapest route that can handle the task and says which one it used. Pricing lives in a dated file, not in the agent's guess.
Quotes the cost in dollars and waits for the “go-ahead.” One approval covers one run. The monthly cap is cumulative, because a per-run gate lets thirty small expenses through.
A flat library, with a JSON file next to each file containing the prompt, model, parameters, and cost. Three months later, you can still tell what made that image.
The workflow is the same in both versions. What changes is where step 1 points.
Choose the model and provider, and read that model’s recipe before calling it — endpoint, authentication, request body format, and where the file appears in the response.
Logo, face, and style come from files in refs/. Describing a logo in words gets you the wrong logo every time — if the file doesn't exist, the skill stops and asks.
The video model returns a job ID; the skill checks its status and downloads the result right away because the result URL expires within hours. The ID is saved so you can resume without paying again.
No subfolders. It looks messy, but it’s the opposite: any gallery, script, or search can read the entire library without configuration.
JSON file with the same basename next to the file, plus one line in the ledger. The charge happens when the provider accepts the job — not when the file arrives.
A new model is a ten-minute Markdown recipe. Nothing else changes — that’s what lets the system survive monthly model changes.
On a machine running a model locally, the cheapest route is free and the cost gate almost never triggers. Without that, every generation costs money — and the gate becomes the heart of the skill.
| generate-local | generate-api | |
|---|---|---|
| For | machine running a model on it | any machine, everything via API |
| Cheapest route | local, $0 (flux2-klein on the GPU) | paid cheap model, ~$0,02 |
| Billing model | hardware already paid for, zero marginal cost | pay-as-you-go per call |
| Paid route | exception—only two reasons | is the only way |
| Image with legible text | paid route (local model gets letters wrong) | top model, paid |
| Default video | local 2.5D render, $0 | generative, $0,20–0,35/s |
| Cost gate | exists, almost never triggers | triggers on every run |
| Draft cheaply / finalize at higher cost | doesn’t make sense—it’s the same model | saves the most |
| Depends on | local image server up | FAL_KEY + KIE_API_KEY in a .env |
Choose one of the two versions per workspace — both declare name: generate.
The scripts use only the standard library. No dependencies to install.
# check python3 --version
The skill checks availability before generating and, if it's down, fails with instructions on how to start it — instead of silently switching to a paid route.
# should return status ok curl localhost:8000/health
Aggregators offer dozens of models with one key and one bill. Add .env to the .gitignore on the first day.
# .env FAL_KEY=sua_chave KIE_API_KEY=sua_chave
Real commands. The local version generates for free; the API version never calls the API without explicit approval in the command.
The two versions live in separate folders, each with its own README.
git clone https://github.com/inematds/generator-skill cd generator-skill
One per workspace. If you install both with the same name, they collide.
# machine running a local model cp -r generate-local ~/.claude/skills/generate # machine without a local model — everything through a paid API cp -r generate-api <workspace>/.claude/skills/generate
Choose the library folder and monthly alert cap. Limit tip: load a small amount of credit with your first payment — the provider can't spend what it doesn't have.
# _config.json, created on the first run { "pasta": "~/generations", "teto_mensal_usd": 50 }
Zero cost, just a few seconds. With no marginal cost, drafts and finals use the same model: vary the seed as much as you like.
python3 scripts/gerar-local.py \ --prompt "capa de curso, formas geométricas, fundo escuro" \ --projeto capa-curso --desc hero -n 3 # OK ...capa-curso_hero_1785563764.png (6.2s, $0)
--estimar prints the quote and exits without spending. This is what you show the person before asking for the “go-ahead.”
python3 scripts/gerar.py --rota fal --model <id> \ --prompt "..." --projeto capa --desc hero \ --custo 0.04 --estimar # QUOTE cost $0.04 · month $0.00 of $50 -> would be $0.04 # Nothing was spent.
No --confirmar the script refuses to call the API. Authorization is in the command, not in the operator’s memory.
python3 scripts/gerar.py ... --confirmar # async video: submits, polls, downloads, and saves the task id python3 scripts/gerar.py ... --custo 1.75 --async --confirmar
The charge happens when the provider accepts the job. If generation fails afterward, the money is already gone — and it’s marked as pending instead of disappearing.
python3 scripts/registrar.py --saldo # 2 run(s) charged without a saved file: # ...1f5462ee incomplete $0.40 # ...fb8bb889 failed $2.00 task T3 # when the bill arrives, correct the amount python3 scripts/registrar.py --corrigir <run_id> --cost 1.9
Copy the recipe template, fill it in using the provider's documentation, and add the entry to the price table with the date. Ten minutes, and nothing else changes.
cp models/_template.md models/meu-modelo.md # fill in: model id, method (sync/async), endpoint, auth, # request body and where the file appears in the response
The complete workflow and the route decision behind the split into two versions.


What was verified with a real run is marked as verified; everything else is marked as unverified in the recipes themselves.