gaido.

A lab notebook for
visual coding agents.

Type a brief. A coder agent builds it — a website, a Three.js scene, a canvas animation — a renderer films the result, a critic reviews it, and every attempt is a node on a graph you can fork. Run the same brief through Opus and GPT-5.5 and compare what they actually render. Local-first: your filesystem, your git, your keys.

fig. 01 — mireille three takes down one branch · then the third one's index.html, opened

Coding something visual is usually one-dimensional: watch the current result, push one direction, overwrite the past. gaido adds a second axis.

  • Down a branch — time. Every run is kept; step back to any render.
  • Across — breadth. Fork into siblings; rival directions side by side.

A fork is a git branch: cheap, nothing overwritten, dead ends left on the canvas. And the axes meet — attach any earlier run as a reference. Branch A from three steps ago, crossed with branch C.

fig. 02 — site studies three passes in one branch · a dark A/B sibling · a second client

One instruction in, one rendered variation out.

  • The coder works in its own git worktree.
  • The renderer films headless Chromium on a fixed clock — same scene, same video, twice.
  • When the run finishes, a critique slot opens under it.
fig. 03 — seed instruction → code → render → critique slot

A critic agent — or you; reviewing every render yourself is a first-class mode — judges each run against its brief: a rating, concrete weaknesses, proposed rules.

Feedback that should outlive one branch gets promoted to LESSONS.md — plain markdown at the project root that every fresh session starts from.

fig. 04 — critique the verdict lands — and it does not flatter you either

Coders are adapters. gaido ships four, all plugging in the same way:

  • Claude Code
  • Codex
  • opencode
  • Cursor CLI

Fork one brief into siblings — Opus left, GPT-5.5 right — and read the renders against each other, not the prose. Or switch coders mid-critique: the new one continues from the committed code, resuming the session where it can, resetting where it can't.

fig. 05 — switch claude-code → codex · session reset · code carried

The same loop runs canvas work — Pixi scenes, flow fields, kinetic type. The faked clock keeps every take deterministic: a five-second loop renders the same way twice, so the critic reviews real frames, not luck.

fig. 06 — drift studies two roots · six variations · one dead end
mkdir site-studies && cd site-studies
npx gaido init
npx playwright install chromium
npx gaido

Opens the graph at 127.0.0.1:4288, pointed at the current directory. The init template runs end-to-end on stub adapters; wire real ones in gaido.config.ts:

import {
  defineConfig,
  claudeCodeCoder,
  codexCoder,
  opencodeCoder,
  cursorCoder,
  geminiCritic,
  playwrightRenderer,
} from 'gaido';

export default defineConfig({
  coders: {
    'cc-opus': claudeCodeCoder({ model: 'opus' }),
    codex: codexCoder({ effort: 'medium' }),
    opencode: opencodeCoder(),
    cursor: cursorCoder(),
  },
  critic: geminiCritic(), // or humanCritic() — your eye, no API
  renderer: playwrightRenderer(),
  render: { width: 1024, height: 1024, fps: 30, duration: 5 },
});

Node 20+ and ffmpeg. The bundled coder adapters shell out to the claude, codex, opencode, and cursor-agent CLIs — your existing subscriptions and logins, no extra keys.

graph
The graph is the workflow. No workflow engine — SQLite, a state machine, an events table. Nodes alternate coder → critique.
versioning
Each coder node owns a git worktree and branch backed by one bare repo. Fork = git worktree add. Retry stacks a commit. Diffs come free.
renders
Headless Chromium on a faked clock steps frame by frame; ffmpeg encodes. Same code, same video. Websites get a scroll-through capture that slows down for tall pages.
adapters
Coder, critic, renderer — three interfaces in @vadimlobanov/gaido-core, the only pluggable surface. Everything else is deliberately hardcoded.
skeletons
Named starting points per root node, so sibling roots can A/B different starting contexts. Init ships default (Pixi), css, and website — each can overlay its own render params, checks, even adapters.
references
Attach images or other runs to a node; materialized into the worktree, excluded from the art's diff.