Building For The Robots

I for one, embrace our robotic overlords.

I, for one, welcome embrace our robotic overlords.

Nine months ago I sat down with ChatGPT to upgrade the command routing and keybinding system for Terminal.Gui. I expected magic. What I got was C# that would have compiled cleanly in 2007. Static singletons. Obsolete event handlers. APIs we’d deprecated two years ago. The agent was confident, fast, and clinically insane.

I had a choice. Get mad at the agent, or get to work.

This is the choice every library maintainer faces in the new AI world. Models are trained on whatever code is in the world, which means they know your v1 better than they know your v2. They are not going to politely wait for your docs to catch up. They are going to ship code, with or without you.

So either you build for them, or they build against you.

In the past month, in an effort to take advantage of Copilot’s insane pricing model that is going away next week, I took on several ambitious Terminal.Gui projects. This time the experience approached magic (with a lingering whiff of Mad Hatter).

What “agent-friendly” actually means

Agent-friendly software treats AI agents as first-class consumers of every artifact the project produces: APIs, docs, CLIs, demos, and tests.

Most people, when they say “I made my codebase AI-friendly,” mean “I added a CLAUDE.md.” That is the bare minimum, and it does almost nothing on its own.

The actual work is five things.

  1. Typed contracts at every edge. JSON in, JSON out, with a schemaVersion. POSIX exit codes. Timeouts. Errors that say what’s wrong in a shape the agent can parse.
  2. Documentation organized by reader. Humans get tutorials. Agents get schemas, runbooks, and machine-readable summaries. Same source of truth, different surface area.
  3. Anti-pattern files, not just pattern files. The model already knows your v1 API. The fight is teaching it you have a v2.
  4. Reproducibility. If a human can run your demo and watch it work, an agent should run the same demo and verify it worked, headlessly, in CI.
  5. Agent-readable specs. Hand the agent a phased plan with decision records and scope boundaries, not “go figure it out.” The library being agent-friendly is necessary. The task being agent-friendly is the other half.

None of this is new. It is the boring discipline of writing a good API, applied to a population of consumers that didn’t exist three years ago.

Here is what came out of taking that seriously across the Terminal.Gui ecosystem.

Terminal.Gui v2

v2.0 Released in April. The architectural headline was real: we killed the static singleton, moved to instance-based IApplication, built a pure-ANSI driver, and rebuilt mouse and keyboard from the parser up.

TG Hero

The headline for agents is different. The API is now boring enough that an LLM can use it correctly. Singletons make models hallucinate state. Instance-based APIs do not. Type-safe dialogs make models invent fewer fields. Pure ANSI means one driver to reason about across platforms, not three.

We also did the unglamorous work. Rewrote AGENTS.md as a real payload instead of a pointer. Shipped a v1-to-v2 corrections file so agents stop generating obsolete API calls. Added llms.txt to the docs site. Wrote a CLAUDE.md tuned for Claude Code specifically. The migration guide is now the kind of document you can point an agent at and say “port my v1 app,” and it works. I’ve done it.

Last week Copilot (using GPT 5.5) did something to Terminal.Gui that would have been a month of typing in 2024. PR #5411 refactors ConfigurationManager to be based on Microsoft.Extensions.Configuration. 86 files, 14 commits, six phases, 17,110 tests still passing. I didn’t write any of it.

It wasn’t a one-shot. The first pass invented APIs that didn’t exist (Driver.ForceMaxColors, fake theme names, properties that were renamed two versions ago). I caught it, made Copilot verify every API reference against the actual codebase, and from there it was clean.

The real magic wasn’t the agent. It was the spec. Six phases, decision records (D-01, D-02) for the contested design choices, scope-in and scope-out called out explicitly, a stacked follow-up PR planned before this one shipped. I used Opus 4.7 to help write the spec. Copilot and GPT 5.5 executed it. That is the division of labor that works.

If an agent can’t use your library well, your library has bad ergonomics. Agents do not read between the lines.

Editor

Terminal.Gui.Editor is what happens when you take AvaloniaEdit’s document layer, port the pure-data bits to a TG View, and ship it as a NuGet package. It is a library. It is not a competitor to vim.

That said, the ted example app is a great TUI text and code editor!

Editor Hero

The README lists the use cases: a script box, a config pane, a notes view, a chat composer. And one more, named explicitly because it matters: the input area of an LLM agent’s terminal front-end.

Building a TUI for an agent? You need a multi-caret, undo-aware, syntax-highlighted edit surface. That is now a dotnet add package away.

clet

clet is the cleanest example of the thesis.

A clet is a CLI-let: a single subcommand that delivers a typed, schema-versioned interactive prompt to either a human or an agent, with the contract negotiated by a single --json flag.

One binary, eighteen subcommands, every one a typed prompt. edit, select, pick-file, confirm, date, color, multi-select. For a human, a rich TUI. For an agent:

clet select --json "prod" "staging" "dev"
# → {"schemaVersion":1,"status":"ok","value":"staging"}

JSON envelope. Schema version. POSIX exit codes (0 ok, 2 usage, 130 cancelled). --timeout 30s so an agent script doesn’t hang on a missing human. Same binary serves the shell user picking a deploy target and the agent escalating a decision before continuing.

That is what agent-friendly looks like at the contract level. A typed result with a parseable error path. Not a markdown file.

The competition is gum, fzf, dialog, and whiptail. Each is good at one thing. clet is the unification, with a real UI toolkit underneath and a JSON contract on top so the agent never has to scrape stdout.

cli

gui-cs/cli generalizes the clet idea. It is a Terminal.Gui library that lets your app expose its Views as scriptable CLI commands with typed JSON output, POSIX exit codes, and AI-agent discoverability.

Build an interactive TUI for humans. Get a scriptable agent surface for free. Same View, two front ends.

Still early. The shape is right.

tuirec

tuirec records a terminal app driven by a keystroke script and produces an animated GIF. Cross-platform, Go, agg-backed.

What I am proud of is the README’s For AI Agents section. Three layers, each doing a different job.

  • OpenCLI handles discovery. tuirec opencli returns a machine-readable command schema. The agent learns what commands and flags exist.
  • Agent guide handles semantics. tuirec agent-guide explains keystroke syntax, timing budgets, and platform gotchas. The agent learns how to use the commands correctly.
  • Recipe files handle runbooks. Markdown the agent follows verbatim for a specific recording.

Discovery, then semantics, then runbook. Three different decisions the agent has to make, three different documents serving each one. Ship only the first and the agent guesses. Ship all three and the agent succeeds on the first try.

“Record UICatalog opening the About dialog, hovering over each tab, and quitting” should be an agent call, not a human afternoon.

As of today, Terminal.Gui’s API docs for each View shows a GIF illustrating what the View looks like in action.

GraphView API docs

Spectre.Console interop

Last week I filed an issue against Spectre.Console titled Complementary by Design.

Spectre excels at beautiful output: tables, charts, trees, panels, figlet, rich markup. Terminal.Gui excels at interactive TUI apps: forms, focus, layout, lifecycle. These are complementary, not competitors. We have built a first pass at the bridge, a read-only TG View that renders any Spectre IRenderable inline alongside interactive TG controls.

The argument I led with in the issue is the one I want to repeat here:

Increasingly, it’s AI agents (not just developers) generating TUI code. They shouldn’t have to choose between the two libraries when both are in their training data.

That is a new design constraint, and a permanent one. Your library’s documentation in 2026 is partly shaped by which other libraries the model has also memorized. Some of your consumers have weights.

So who is the overlord here?

Not them. Still us.

But the people who treat agents as adversaries to defend against are going to ship software that fights its own tooling. The people who treat agents as users to design for are going to ship software that gets better every time the models do.

Every contract typed. Every doc dual-audience. Every demo agent-reproducible. Five projects that work for humans, work for agents, and work better because I stopped pretending those were different requirements.

And just wait until you see what I am going to do next with WinPrint 2.x. Humans have stopped printing stuff. Maybe agents will want to instead.

Comments below. Or grab time on office hours.

Debate this topic with me:

This site uses Akismet to reduce spam. Learn how your comment data is processed.