A flag is not a setting
I was reviewing a change to rust-tool-base’s scaffolder when a word stopped me dead. rtb generate config-field. I couldn’t have told you why in that first second… I looked at it and just knew it was wrong. The verb there …

I was reviewing a change to rust-tool-base’s scaffolder when a word stopped me dead. rtb generate config-field. I couldn’t have told you why in that first second… I looked at it and just knew it was wrong. The verb there …

It came out of an audit. I’d recently pointed a small army of review agents at the whole go-tool-base codebase, back before that became a political problem, and one of the findings was that a subcommand could quietly …

You’ve got a Python script that already does the job. It’s sat in a tools/ directory somewhere, it works, and every few weeks someone copies it onto a laptop that doesn’t have the right version of pandas and it falls …

You ship version one. A week later someone finds a bug, you fix it, you cut version two. Now for the awkward part: how does the person who installed version one ever get version two? Email them? Hope they wander back to …

I run a Dungeons & Dragons game on the odd weekend, so when I sat down to put an AI feature inside a CLI, my first instinct wasn’t a chatbot. It was: could the tool run a little adventure, with an AI as the dungeon …

“Make it work with AI” is the request that lands on your desk with a thud and no further detail. The first time it landed on mine I braced for a treadmill of integration work: an adapter for this assistant, a wrapper for …

In part 1 you scaffolded a tool and gave it a hello command. It says the same thing every time, which is fine for a first command and useless for a real one. The moment a tool does anything worth doing it needs settings: …

Every time I start a new Go CLI, the first hour goes the same way, and none of it is the actual tool. Config loading. A logger. An update command. An error path that prints something a human can act on. A help system. I …

--output json worked everywhere. On the top-level command, on every ordinary subcommand, wherever the user fancied putting it. Then it stopped working in exactly one place, and of course it was the subcommand I’d been …

I ended the last post promising to show how a Rust command registers itself when the language flatly refuses to run any of your code before main(). This is that post, and it’s a lovely example of reaching the same …
