Use the right provider. Stay in one place.

Agent skills for Claude Code and Codex CLI. delegate reaches other providers from the session you are already in, matches each task to the cheapest capable model, and uses plan allowances you already pay for — no moving work between IDEs or chat apps. gif and svg build on it, turning one free call into a small looping icon — pixels or vectors.

skill

A prepared demo, not a screen recording of production work: a throwaway repo with one deliberately unvalidated function, so the flow fits on a page. The commands, the models and every line of output are real — only the file paths and the wording of one prompt are shortened to fit the width.

fixing a bug in a shopping cart, start to finish 6 commands · 4 providers · $0

delegate.sh providers

Who is available, and which model each tier is wired to.

antigravity available (plan) hard=claude-opus-4-6-thinking code=claude-sonnet-4-6 read=gemini-3.7-flash-high cheap=gemini-3.7-flash-low codex available (plan: chatgpt) openrouter key present (not verified; use: providers --check) ai-studio key present (images blocked on free tier)

delegate.sh read "List every exported function in src/cart.js"

Reading is cheap work, so it goes to Gemini Flash. free · plan

- subtotal (src/cart.js:1-3): Calculates the total sum of items in the cart by multiplying each item's price by its quantity. - applyDiscount (src/cart.js:5-7): Computes the discounted total by applying a given percentage reduction to an amount.

delegate.sh code "applyDiscount: throw a RangeError when percent is outside [0, 100]." --write

A bounded change you could hand a competent stranger, so Claude Sonnet writes it. free · plan

Done. applyDiscount now throws a RangeError before any calculation when percent is outside [0, 100]. Everything else in the file is unchanged.

git diff

Read the diff yourself — a delegate reporting success is a claim, not evidence. delegate also checks the files really changed.

src/cart.js | 3 +++   function applyDiscount(total, percent) { + if (percent < 0 || percent > 100) { + throw new RangeError('percent must be between 0 and 100'); + } return total - (total * percent / 100);

delegate.sh review --uncommitted

Claude wrote it, so Codex reviews it. A model reviewing its own work mostly agrees with itself. free · plan

- [P2] Reject nonnumeric discount percentages — src/cart.js:6 When percent is NaN, undefined, or a nonnumeric string, both comparisons evaluate to false, so the new guard is bypassed and the function returns NaN instead of rejecting an invalid percentage. Validate that percent is a finite number before applying the range check.

delegate.sh image "a flat-design shopping cart icon" cart-icon.png

Image generation has its own small quota, separate from the model quota — and it was spent. Two free paths run before anything paid, so the second picked it up.

[delegate] antigravity produced no image, trying codex imagegen wrote cart-icon.png (codex imagegen, free)

a flat-design shopping cart icon Shown on this page, not in the terminal.The command prints the path and nothing more; open the file to see it. This is what that prompt actually returns, at 96×96 of the 1024×1024 the model draws.

Spend for that session: nothing. Every step ran on a subscription that was already being paid for — and the review caught a real hole in the guard that had just been written.

A skill built on top of another skill: gif spends one delegate image call on a sprite sheet, then does every pixel of the assembly locally. An illustrative run — the commands, the flags and the shape of the output are real, the subject is not a specific recorded session.

a 32px transparent looping icon, and what is really in the file 2 commands · 1 image call · $0

gif.sh make "a coin spinning end over end" coin.gif --show

Defaults are the ones you nearly always want: 32×32, transparent, one second, loops forever. --show draws the finished file in the terminal, and the path it prints is a link you can click. free · plan

[gif] generating a sprite sheet of 8 frames wrote /tmp/…/sheet.png (antigravity, free) gifpack: sheet is 1376x768, reading it as 4 x 2 wrote coin.gif (32x32, 8 frames, 1.00s, loop=forever, transparent) file coin.gif format GIF size 32x32 frames 8 duration 1.00s (delays ms: [130, 130, 130, 130, 120, 120, 120, 120]) loop forever transparent yes (index 63) bytes 4707

a gold coin spinning end over end, 32x32 the same coin at 3x, showing the pixels Shown on this page, not in the terminal by default.--show draws the GIF inline only where iTerm2's imgcat, chafa or viu is installed; everywhere else you click the underlined path. This is coin.gif itself, 32×32 as written and at 3×.

gif.sh sheet sheet.png coin-64.gif --cols 4 --rows 2 --size 64

Every write ends with that report, read back off the finished file — gif.sh probe runs it on any GIF, including ones you did not make here. Re-cutting the sheet you kept spends no quota at all.

gifpack: sheet is 1376x768, reading it as 4 x 2 wrote coin-64.gif (64x64, 8 frames, 1.00s, loop=forever, transparent) file coin-64.gif format GIF size 64x64 frames 8 duration 1.00s (delays ms: [130, 130, 130, 130, 120, 120, 120, 120]) loop forever transparent yes (index 63) bytes 10775

The image model cannot draw transparency, so the prompt asks for a flat magenta backdrop and the key removes it — which only works if the frames are cut where the model actually drew them, so the layout is read off the sheet rather than assumed. Sizes stop at 16/32/64/128 and duration at three seconds: the format's own limits, refused loudly rather than rounded.

The same shape as gif, but an SVG is code — so it comes from a delegate text tier, not an image model, and everything a model cannot be trusted with is enforced locally. An illustrative run: the commands, the flags and the shape of the output are real.

a CSS-animated icon, a frame sequence, and a look inside the file 2 commands · text tier · $0

svg.sh make "a ringing notification bell" bell.svg

CSS by default: restyleable from the page that embeds it, and it can honour prefers-reduced-motion — which SMIL cannot express at all. free · plan

[svg] asking delegate (code) for the source wrote bell.svg (32x32, animated (CSS), transparent, 2812 bytes) file bell.svg size 32 x 32 viewBox 0 0 100 100 elements 11 animation CSS, cycle 1.000s loop infinite reduced honours prefers-reduced-motion background transparent bytes 2812 unsafe none

Shown on this page, not in the terminal.No terminal draws SVG — the underlined path opens it in a browser, which is where it animates. bell.svg itself, 32×32 and at 3×: the CSS travels with the file, so it rocks here and holds still if your system asks for reduced motion.

svg.sh make "a walking robot" walk.svg --frames 6

For motion no tween can express. The model draws six moments and nothing else; the step-end keyframes and the negative per-frame delays are written here, because that is arithmetic a model gets wrong and drawing is not.

[svg] asking delegate (code) for the source wrote walk.svg (32x32, 6-frame sequence, transparent, 11862 bytes) file walk.svg size 32 x 32 viewBox 0 0 100 100 elements 128 animation 6-frame sequence, cycle 1.000s loop infinite reduced honours prefers-reduced-motion background transparent bytes 11862 unsafe none

Shown on this page, not in the terminal.walk.svg opened the same way — six drawn moments, no tween. Step-end keyframes hold each one for a sixth of the second.

One loop lasts exactly the duration you asked for: times are scaled by the ratio, so a dot delayed a sixth of the way through stays a sixth of the way through. Scripts, event handlers, external references and DOCTYPEs never reach the file at all — and svg.sh probe reports the same for an SVG you did not generate here, exiting nonzero on anything unsafe.

install

Three ways in. Each links the skill into Claude Code, and into Codex too when it is installed. Then start a new agent session — skills load at startup.

Ask your agent

Paste this into Claude Code or Codex. It reads the repo and does the rest.

Install the skills from https://github.com/krzysztofradomski/skills — clone it, then symlink the skills into my agent skill directory and any bundled scripts onto my PATH. Show me what you linked.

One command

Clones to ~/.local/share/agent-skills, links the skills, puts scripts on your PATH. Re-run it to update. It skips anything that is already a real directory rather than overwriting it.

curl -fsSL https://raw.githubusercontent.com/krzysztofradomski/skills/main/install.sh | bash

Piping a stranger's script into your shell is a habit worth resisting — download it and read it first if you would rather. It is about sixty lines.

By hand

Symlinks, not copies, so git pull updates everything with nothing to reinstall.

git clone https://github.com/krzysztofradomski/skills.git ~/code/skills
cd ~/code/skills
ln -s "$PWD/delegate" ~/.claude/skills/delegate
ln -s "$PWD/delegate" ~/.codex/skills/delegate
ln -s "$PWD/gif" ~/.claude/skills/gif
ln -s "$PWD/svg" ~/.claude/skills/svg
ln -s "$PWD/delegate/scripts/delegate.sh" ~/.local/bin/
ln -s "$PWD/gif/scripts/gif.sh" ~/.local/bin/
ln -s "$PWD/svg/scripts/svg.sh" ~/.local/bin/

npx skills

Resolves this site's discovery index and verifies the skill's digest before installing anything.

npx skills add https://ai-skills.radomski.dev --skill delegate -a claude-code -g   # one skill
npx skills add https://ai-skills.radomski.dev --skill '*' -a claude-code -g        # all of them

api keys

None are required. Antigravity and Codex sign in through their own CLIs, and that covers every default path. Keys only add the two optional providers below.

OpenRouter — free frontier models, and the paid image fallback

Get one at openrouter.ai/keys. Read from a file, so it never lands in your shell history or in ps output.

mkdir -p ~/.config/openrouter
printf 'OpenRouter key: '; read -rs k; echo
printf '%s' "$k" > ~/.config/openrouter/key; chmod 600 ~/.config/openrouter/key; unset k

Google AI Studio — tried first for images

Get one at aistudio.google.com/apikey.

mkdir -p ~/.config/google-ai
printf 'AI Studio key: '; read -rs k; echo
printf '%s' "$k" > ~/.config/google-ai/key; chmod 600 ~/.config/google-ai/key; unset k

Worth knowing before you bother: AI Studio's free tier grants zero image quota — every image model returns RESOURCE_EXHAUSTED with limit: 0 until billing is enabled on the Google project. Without billing this key changes nothing for images, and the chain falls through to the free paths anyway.

Check what actually works

A key file existing proves nothing. This validates the OpenRouter key against the API and exits nonzero if it is rejected.

delegate.sh providers --check

$OPENROUTER_API_KEY and $GEMINI_API_KEY work too if you prefer environment variables.

where the work goes

Antigravity and Codex bill against a subscription rather than per token, so the default path costs nothing on top of what you already pay. Anything that spends money is opt-in behind a flag.

providerauthused for
antigravityplanthe default — reading, coding, and image generation
codexplanreview, and anything that has to actually run your tests
openrouterfree tierone-shot text when no repo context is needed
paid fallback--paidimages only, only when both free paths fail, only if you ask

what it actually does for you