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.
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.
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)
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.
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.
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
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 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.
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.
svg.sh probe
reports the same for an SVG you did not generate here, exiting nonzero on anything unsafe.
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.
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.
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.
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/
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
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.
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
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.
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.
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.
| provider | auth | used for |
|---|---|---|
| antigravity | plan | the default — reading, coding, and image generation |
| codex | plan | review, and anything that has to actually run your tests |
| openrouter | free tier | one-shot text when no repo context is needed |
| paid fallback | --paid | images only, only when both free paths fail, only if you ask |