Pulling the library out of the binary
In 0.10 the domain layer moved out of the binary and into a crate of its own. The CLI now depends on it like any other consumer would, and so does the TUI.
In 0.10 the domain layer moved out of the binary and into a crate of its own. The CLI now depends on it like any other consumer would, and so does the TUI.
Why it was worth a release
A CLI that owns its own logic can only be tested by running it. You spawn a process, you hand it arguments, you read stdout, and you assert on text that exists to be read by a person. Those tests are slow, they break when you improve a message, and they cannot reach the interesting half of the code at all.
The test count went from 97 to 282 in the same release. That is not diligence arriving suddenly; it is what happens when the operations become functions you can call. Per-platform parser fixtures, httpmock-backed client tests that assert on auth headers and status mapping, TUI state tests, CLI dispatch tests — none of those were reachable before the split, and none of them needed a subprocess after it.
What else came out of it
The three largest files were broken up in the same pass. cli.rs was 6,600 lines and became a clap surface plus twenty-four domain modules. The TUI's app.rs and events.rs became per-view modules. The platform code was reorganised by platform rather than by feature, which is why the seven client directories exist in the shape they do.
And roughly 415 catch-all error sites got precise variants: Network, PlatformApi carrying the real HTTP status, Auth, MalformedResponse, Subprocess, Fs, RepoState, Workspace, Unsupported, Usage. Before that, a great many failures arrived as InvalidConfig, which is a lie with a plausible face: you go and check your configuration, and your configuration is fine.
The bug that only a library boundary would surface
torii log | headThat used to panic with failed printing to stdout: Broken pipe. head closes the pipe once it has its ten lines, the write fails, and Rust's default SIGPIPE disposition turns that into a panic rather than the quiet exit every other command-line tool performs. The fix is one line at startup — restore SIGPIPE to its default — and it is the kind of thing you find when you start asking what the process does rather than only what the functions return.
Two more from the same release, both mundane and both the sort of thing that makes a tool feel unfinished: torii rename moved a directory on disk and then failed to index it, because Index::add_path only takes files; and torii save hung forever with no TTY when the secret scanner found something, waiting on a [y/N] that nobody could answer. It now fails fast and names --yes.
What it sets up
One library, several front ends. The CLI and the TUI are two of them today. The graphical application on the roadmap is the third, and the reason it is a plausible piece of work rather than a rewrite is that it inherits the snapshots, the scanner and the platform clients instead of reimplementing them.