Back to the network

Tooling

tool-kit

A personal toolbox behind one command: safe publishing of private repos, script vetting, checksummed backups, machine diagnosis and AI helpers.

The problem

I work across several machines, and the same jobs keep coming back. I publish a repository without my personal data in it. I read a script before I run it, back a folder up, find out why the network is down, and sit down at another PC expecting my terminal to look the same there. tool-kit is where those jobs live: seventeen tool sets in one repository, each with its own docs and its own tests.

One rule runs through all of them. What decides is deterministic and checkable, and nothing is destroyed before what replaces it is proven. An AI may advise. It never owns an exit code. Safety rails shows that rule at work.

One front door: run

Every tool is reached the same way, run <name>, from any folder. Behind the name there is no registry. A command is a config file, and its id= line is the only thing that makes it a command. The config lists the steps, and cmd-bot, the engine underneath, runs them in order:

The catalog's own search, through the front door
$ run csearch --match scrub
Run: csearch  (config: command-search.conf, steps: 1)
Memory: /tmp/cmd-bot.a4sgace1/memory

==> [1/1] search.py
scrub            a publishable snapshot of a repo with your personal data replaced (one commit, no history)
Run 'csearch' completed successfully.

An id is frozen, and a name is what you type. So a rename is one edited line, and no file moves. The table of commands in the README is generated from the configs and never edited by hand, and its check exits 1 the moment the table drifts. On 2026-08-28 the catalog held twelve commands. It holds 34 now.

Rules that came from failures

Most of the rules in the repository are there because something went wrong once. Three of them:

Built on 0-libraries

The packages tool-kit shares with my other repositories come from 0-libraries: the AI engine, the git command set, and pinned runtimes for Python, zellij and age. They are copied into 0-lib/ and committed, so every sync is a diff in this history, and nothing syncs on its own. A wrapper reports where each copy stands. Each copy's starting hash is committed too, so a fresh clone can tell a copy that is only behind the library from one that someone edited by hand:

Eleven vendored packages and the wrapper, checked against the library
$ python3 0-lib/wrapper check
ok          age
stale       ai
ok          ai-transcripts
ok          git
ok          pywebview
ok          pywebview-ui
ok          shellcheck
ok          sshcmd
ok          sshconf
ok          uvpython
ok          wrapper
ok          zellij
$ echo $?
1

The stale line is real: the library's ai package has moved since the last sync. The rule is that the next change touching that package's callers syncs it first, and every landing runs this check beside the test suites.

Scale, and how I built it

1,656 commits between 2026-07-07 and 2026-10-26. Claude Code co-authored 1,189 of them, counted on 2026-10-27. The last full test run, on 2026-10-26, passed 4,986 of 4,986 assertions across 72 files of tool-kit's own suites.

The work runs the way the rest of this site's work does. A change starts as a written spec and a plan, is built in a lane of its own and reviewed, and lands when its checks pass. The rules above are written into the repository, so each session starts from them.

Read on

Stack

  • Python
  • Shell

Connected to