cd /news/artificial-intelligence/fable-5-opened-a-1800-line-pr-on-tab… Β· home β€Ί topics β€Ί artificial-intelligence β€Ί article
[ARTICLE Β· art-39661] src=tabularis.dev β†— pub= topic=artificial-intelligence verified=true sentiment=↑ positive

Fable 5 Opened a 1,800-Line PR on Tabularis in 30 Minutes

Anthropic's Fable 5 AI model autonomously generated a 1,810-line pull request for the Tabularis codebase in 30 minutes, adding a full command-line interface to the Tauri app. The AI refactored existing code into a shared module, wrote 37 unit tests, and fixed two pre-existing bugs without being asked. The result demonstrates AI's ability to handle complex, multi-file software engineering tasks with minimal human input.

read7 min views1 publishedJun 10, 2026
Fable 5 Opened a 1,800-Line PR on Tabularis in 30 Minutes
Image: Tabularis (auto-discovered)

Daily Dev Experimentβ€” a short series where we hand a real task to an AI on the Tabularis codebase and report exactly what happened. No staged demos. Today's run got a little out of hand.

We asked Fable 5 (Anthropic's new model) to add a command-line interface to the app. That's less trivial than it sounds: this is a Tauri app β€” Rust backend, React frontend β€” so "a CLI" means reaching every saved connection (keychain passwords, SSH/K8s tunnels, plugin drivers) without booting the GUI or starting the Tauri runtime at all.

One prompt. A coffee break. A draft PR waiting at the end of it.

Here's what was in it.

The numbers #

| Lines added | 1,810 | | Lines removed | 319 | | Files touched | 16 | | New unit tests | 37 (full suite: 692 passing) | | Pre-existing bugs fixed | 2 β€” we didn't ask for either | | Wall-clock time | ~30 minutes |

We've spent longer naming a variable.

Video unavailable

What we expected #

A coherent set of clap

subcommands, addressed by connection id or name:

Command What it does
tabularis connections (ls )
List saved connections β€” table or --json
tabularis databases <conn>
List databases on the server
tabularis schemas <conn>
List schemas
tabularis tables <conn>
List tables (-d , --schema , --json )
tabularis describe <conn> <table>
Columns, indexes, foreign keys
tabularis query <conn> [SQL] (q )
One-shot query, stdin pipe, or interactive shell
tabularis install-cli
Symlink the binary into a PATH directory

The detail we like most: query

picks its mode from the invocation. SQL argument β†’ one-shot. Piped stdin β†’ executes the piped statement. Interactive TTY with no SQL β†’ drops into a proper SQL shell.

tabularis query my-db "select id, name from customers" --format csv > out.csv

echo "select count(*) from orders" | tabularis q my-db

tabularis query my-db

The interactive shell is backed by rustyline

: line editing, persistent history (cli_history.txt

in the app config dir), multi-line statements that fire on a terminating ;

, Ctrl-C

drops the current buffer, Ctrl-D

exits. Plus psql-style meta commands:

\l    list databases        \f table|json|csv   output format
\dn   list schemas          \limit N            row limit (0 = unlimited)
\dt   list tables           \schema NAME        set schema
\d T  describe table        \use DB             switch database
\q    quit                  \?                  help

Result data goes to stdout, logs go to stderr β€” so piping stays clean, and you get a non-zero exit code on failure. Exactly the kind of detail a human means to remember and usually forgets.

It even kept the GUI-launch fallback intact: macOS still passes junk like -psn_*

to the binary on launch, and that must keep booting the GUI β€” while a misspelled subcommand should surface clap's error instead of silently opening a window. It threaded that needle, and wrote tests asserting the exact clap

error kinds that fall through to the GUI versus the ones that don't.

What we did NOT expect #

1. It found the refactor before writing a single feature.

The app already ships an MCP server, and that server already knew how to resolve a saved connection β€” decrypt the keychain password, open the SSH/K8s tunnel, register the right plugin driver. Instead of duplicating all of that for the CLI, Fable 5 dug through the codebase, realized the logic was buried inside mcp/mod.rs

, and pulled it out into a shared headless.rs module that both the MCP server and the new CLI consume. The MCP server now just wraps the shared helpers with its JSON-RPC error type β€” zero behavior change on that side.

That's 242 lines deleted from mcp/mod.rs

and a 214-line module born. It's the refactor we would have done β€” unprompted, because it understood why duplicating connection resolution was the wrong move.

It also didn't dump everything into one file. The old 52-line cli.rs

became a real module:

src-tauri/src/cli/
β”œβ”€β”€ mod.rs       clap definitions, GUI-fallback logic     (182 lines)
β”œβ”€β”€ run.rs       command dispatch + execution             (338 lines)
β”œβ”€β”€ repl.rs      the interactive shell                    (282 lines)
β”œβ”€β”€ output.rs    table / JSON / CSV rendering             (138 lines)
β”œβ”€β”€ install.rs   install-cli symlink logic                 (97 lines)
└── *_tests.rs   args, output, run, install               (442 lines)

2. It fixed two real bugs that were already there.

keychain_utils

was logging withprintln!

, dumping straight tostdout. Harmless in a GUI β€” silently corrupting any piped CSV/JSON the moment a CLI exists. And it was bypassing the in-app log buffer too. It rerouted everything through thelog

crate.- Headless processes never called sqlx::any::install_default_drivers()

, so the default connection-test pathpanicked. It installed the drivers in the sharedheadless::register_drivers()

β€” which also quietly fixed the existing--mcp

mode.

Neither was in the prompt. It found them because it actually traced the execution path from "user pipes a query" to "bytes hit the terminal" and noticed what would break along the way.

3. It handled multi-database connections properly.

Multi-db connections used to resolve to their first database, which made the others unreachable outside the GUI. Every db-scoped command now takes -d/--database

, and the shell's \use <db>

doesn't just flip a variable β€” it validates the switch with a connection test before applying it, and the prompt shows where you are (Demo Β· MySQL:blog_demo>

). Under the hood it reuses the GUI's per-call database-override semantics (DatabaseSelection::Single

) instead of inventing a parallel mechanism.

4. It tested its own work against a live database.

The 37 unit tests aren't padding: clap parsing (including the GUI-fallback error kinds), table/CSV/JSON rendering (column alignment, control-character escaping, CSV quoting), limit and database-override semantics, and the install-cli

symlink logic β€” idempotency, refusal to clobber a foreign file, --force

.

Then it went further: it ran the new shell against a real MySQL connection, switched across the three demo databases with \use

, eyeballed the table/CSV/JSON output, and fixed the formatting it didn't like β€” before handing over the PR.

Finding Tabularis useful? Star it on GitHub β€” it takes a second and helps more developers discover the project. Star on GitHub## So... do we trust it?

No. It's a draft PR and we're reviewing every line before anything ships. There are real limitations β€” which, to its credit, it flagged itself in the PR description:

  • On Windows release builds the binary has no attached console ( windows_subsystem = "windows"

), so CLI output is invisible there. Same constraint the--mcp

mode always had. - Each shell statement runs on its own pooled connection, so session state β€” SET

, transactions, temp tables β€” doesn't persist between statements. It even documents that caveat inside\?

.

But here's the part that stuck with us: the review is genuinely worth doing. This isn't autocomplete spitting out a function body. It's an agent that read the architecture, found the seam we'd have found, refactored toward it, and cleaned up two messes on the way out β€” then wrote 37 tests and a PR description more thorough than most humans bother with.

Two years ago this was Tab-complete. Today it's a coworker whose work we have to code-review.

πŸ‘‰ Read the full PR β€” every line, the real description: #313

Where this is going #

This experiment isn't a side quest β€” it's the direction. We're building a database client that's native to this new workflow: a built-in MCP server so agents like the one in this post can work against your databases, with approval gates, a read-only mode, and a full audit log so they do it on your terms. An AI assistant that also runs on open-source models β€” locally via Ollama, with zero schema data leaving your machine. And now a CLI, born from that same headless core.

An agent wrote today's feature. The point is that tomorrow, your agents get a first-class, safe way to use it.

── more in #artificial-intelligence 4 stories Β· sorted by recency
── more on @anthropic 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain β€” perfect for shipping the agent you just read about.

$git push zahid main
β†’ Live at https://your-agent.zahid.host βœ“
Get free account β†’ Pricing
from €0/mo Β· no card required
LIVE [news/fable-5-opened-a-180…] indexed:0 read:7min 2026-06-10 Β· β€”