Agents · From Tools to Agents
Tools built for agents — the Hyperframes pattern
Eight lessons asked: how do you build a tool a model can use? This one flips it. What does a tool look like when an agent authors with it, not just calls it?
Run init and read what shows up
npx hyperframes init
# → Created hyperframes.json
# → Created package.json
# → Created index.html
# → Created meta.json
# → Created AGENTS.md
# → Created CLAUDE.md
Six files. Two of them — AGENTS.md and CLAUDE.md — exist for one reason: so the agent never has to leave the repo to learn how to use the tool.
The cognitive surface
Hand someone a power saw without the safety label and you've handed them a different tool. The blade is the same. What changed: whether the warning sits next to the cut. The agent has the same constraint — it sees what's in the working directory. A docs site lives somewhere it doesn't.
CLAUDE.md lists thirteen slash-skills the project owns: /hyperframes, /gsap, /lottie, /three, /website-to-hyperframes. The docs aren't a site you read. They're a tool you invoke — same packaging as Anthropic's superpowers.
The edit surface
One file. index.html. Each .clip div carries data-start, data-duration, data-track-index. Animations live in GSAP timelines registered on window.__timelines["main"], created paused.
<!-- index.html -->
<div class="clip" data-start="0" data-duration="2" data-track-index="0">
<h1 class="title">Hello</h1>
</div>
<script>
const tl = gsap.timeline({ paused: true });
tl.from(".title", { y: 100, opacity: 0, duration: 0.8 });
window.__timelines["main"] = tl; // load-bearing line
</script>
That last line is the whole lesson on this mechanic. The renderer is a headless browser that must seek to timestamps to capture frames. A running timeline doesn't expose seek; only a paused timeline registered on window.__timelines does. Forget the registration and the browser preview still plays — but the render freezes on frame 0. Same shape as the os.path.realpath boundary in l6: the failure is invisible until something outside the local environment exercises it.
The lint pass
npm run check
# → composition validated
# → 0 console errors
# → WCAG-AA: pass
Same discipline as the pytest suite in l8: fail loudly before shipping, with concrete checks, not vibes. The browser hid the console error; the headless run surfaces it.
The catalog
npx hyperframes add data-chart
# → compositions/data-chart.html (458 lines)
# → snippet copied to clipboard
shadcn-style. The file is in your repo. You own it, you edit it, no runtime import to a black-box component.
The four-signal test
When evaluating any tool that claims agent support:
- Does it ship an
AGENTS.mdorCLAUDE.mdat init? - Does it provide slash-skills or equivalent invocable docs?
- Is the edit surface one file, not a component tree?
- Does a lint pass catch headless-render failures before they ship?
Three of four missing means the tool was built for humans and retrofitted with an MCP server. The retrofitted version still works — but the agent spends tokens reading a website to learn what AGENTS.md could have told it for free.
Hyperframes vs. Remotion
Code-first agents → Hyperframes. The agent writes HTML it can read back; the renderer is local.
React-first humans → Remotion. Type-safe composition trees, prop-based reuse, JSX a person edits.
Same shape, different authors. Pick by who is writing.
If you get stuck
Composition animates in the browser preview but freezes on frame 0 in the render: the GSAP timeline is not registered on window.__timelines["<id>"]. Add the assignment line and confirm the timeline was created with paused: true.
Render passes locally but npm run check reports a console error you didn't see: the browser swallowed it. Open the page in devtools, reproduce, and fix the underlying error — the lint pass is reading the same buffer.
Agent imports a block from npm instead of running add: it pulled in a registry your project does not own. Delete the import, run npx hyperframes add <name>, edit the file that lands in compositions/.
Cross-reference
l7 and l8 built the consumer posture — your code calls tools the model authors. l9 is the author posture — you evaluate tools built for the model to author with. Same vocabulary, opposite end of the contract.
Deliverable
A 6-second composition rendered locally with npx hyperframes to a 200-300KB h264 file in out/. Plus notes/tool-evaluation.md applying the four-signal test to one other tool you use that claims agent support — name which signals are present, which are missing, and what the next agent author must read a website to learn.
Further reading
- "What Agents Actually Need From Your API" — same boundary problem one layer down. The response shape that worked for human developers degrades reasoning when the caller is a model. Tooling has the same gradient.
Try these prompts
- Run npx hyperframes init in a scratch directory, then describe what each of the six scaffold files is for and which two exist solely so an agent can read them before writing any code.
- Apply the four-signal agent-first test (AGENTS.md ships at init, slash-skills as docs, single-file edit surface, lint pass catches headless-render failures) to one tool you currently use that claims agent support; name which signals are present and which are missing.
- Explain in two sentences why a GSAP timeline that animates correctly in the browser preview can freeze on frame 0 in the headless render, and what one line of code prevents it.
Sign in to keep your place and tick off lessons. Reading stays open either way.