Driving yoink from an AI agent
CLI and YAML-driven, deterministic exit codes, and patterns for driving yoink from Claude Code, Cursor, Aider, and GitHub Copilot Workspace.
Yoink is unusually well-suited to being driven by AI coding agents (Claude Code, Cursor, Aider, OpenAI Codex, GitHub Copilot Workspace, Devin, …) because its entire control surface is a CLI binary plus YAML files in your repo: no web dashboard, no REST API to learn, no interactive prompts to navigate. Anything an agent can do at a terminal, it can do with yoink.
Why it works
| Property | Why an agent benefits |
|---|---|
| Single binary, on-demand | Agent runs yoink up like any other shell command. No long-running service to bootstrap, no auth flow to script. |
| YAML-only config | Agent can read, edit, and grep yoink.yaml like any other source file. Diffs show up cleanly in PRs. |
--dry-run --format=markdown | Agent can ask "what would change?" before committing. Output is machine-readable enough to feed back into the conversation. |
| Deterministic exit codes | Success / failure is unambiguous. No "click the button and see what happens." |
| Idempotent | Re-running yoink up after a partial failure picks up where it left off. Safe to retry. |
| Drift detection in labels | Agent can docker inspect (or yoink status) to see whether the live state matches the declared spec, without trusting its own memory. |
| Same workflow local & CI | The agent's local commands work identically in a GitHub Actions runner. Nothing special to wire up. |
The agent-friendly loop
The pattern that works:
- Describe the change in YAML. Edit
yoink.yamlto add a service, change an image tag, bump a replica count, etc. - Preview the diff.
yoink up --dry-run --format=markdown: output is a markdown table the agent can paste into the chat or a PR comment. - Apply.
yoink up(or scoped:yoink up --service api). - Verify.
yoink status(one-shot table) andcurlthe public endpoint. The exit code on a failed healthcheck-gated swap is non-zero, so the agent knows immediately if rollout failed. - Roll back if needed.
yoink rollback api: atomic, no human in the loop required.
Every step in this loop is a single shell command with predictable output. No screen-scraping, no waiting for a UI to render.
Useful subcommands for agents
yoink validate # Schema + Caddy-config sanity check, fast
yoink up --dry-run --format=markdown # "What would happen?" — paste into PR comment
yoink up --service api # Reconcile one service in isolation
yoink status # One-shot table; parses cleanly
yoink history api # Who deployed what, when (last 10)
yoink rollback api # Roll service back to its previous version
yoink logs api -f # Stream logs (terminate when done)
yoink prune --dry-run # See what stale containers would be removed
yoink proxy-render # Print the rendered Caddy config (debugging)
yoink pf api --json & # Tunnel to a (possibly non-published) service;
# stdout is a JSON line {local_port, mode, url, …}
# the agent can read to drive a follow-up curlThe full surface is in the CLI reference: all flags, all subcommands, no hidden state.
A tip for prompt design
When asking an agent to make a deploy change, anchor it on the YAML diff rather than on the deploy outcome. A good prompt looks like:
Add a new
workerservice toyoink.yaml: imageghcr.io/me/worker:v1, depends onredis, runs on theapiandredisnetworks, healthcheck on/health. Then runyoink up --dry-runand show me the diff before applying.
The agent edits the file, runs the dry-run, you skim the diff, the agent applies. This is the same loop a human would follow; yoink doesn't ask the agent to do anything fundamentally different.
CI runs the same loop
The GitHub Actions workflows yoink documents (see Pre-merge dry-run on every PR) are the same shape: an automated runner edits / reads yoink.yaml, calls yoink up --dry-run, posts the diff back to the PR, and on merge calls yoink up for real. Anything an AI agent does locally, you can graduate to CI by copying the same commands into a workflow file.
What doesn't work yet
A couple of honest limitations:
- The TUI is keyboard-driven.
yoink tuiis for humans. Agents should stick toyoink status,yoink history,yoink logsfor inspection. - Interactive prompts. A few subcommands (
yoink secrets edit) drop into$EDITOR. Agents should useyoink secrets set KEY=valuestyle flags or pre-write the secrets file directly. - No streaming structured output.
yoink upemits human-readable progress lines. The exit code tells you success/failure; for richer machine-readable output, use--dry-run --format=markdownor parseyoink status.
These are tractable; if you hit a friction point that an agent can't work around, open an issue.
See also
- Pre-merge dry-run on every PR: agent-readable plan output via
yoink up --dry-run --format=markdown. - CLI reference: every subcommand surface an agent might drive.