Standard: version
How every binary in the shll toolkit reports its own version. <tool> --version is the one probe shll runs to answer three questions at once: what version is installed, is the tool healthy, and — because the probe doubles as an install check — is the tool installed at all. shll parses it under a tight timeout with a first-line-only token scan, so the output shape is a contract, not a courtesy.
This page is the producer-facing standard: what your --version must emit. The consumer side — shll version’s aligned table, shll doctor’s health check, and the shared install probe — is shll’s job and lives in its own memory. A tool author’s entire obligation is keeping --version conformant to this page.
Scope is all seven binaries — the six roster tools (wt, idea, tu, run-kit, hop, fab-kit) and shll itself. Unlike update and shell-init, shll is a producer here too: shll version prints its own row — read from the version string linked into the binary at build time (via -ldflags) and run through the exact same first-line parse this page requires of everyone else — so shll holds itself to the shape it enforces on the tools it probes.
This standard implements principle №4 of the toolkit CLI principles (fail fast with actionable errors — an unparseable or slow --version makes a healthy tool read as broken or absent), and its stdout discipline serves principle №2 (stdout is data).
Invocation contract
<tool> --version is uniform across all seven binaries:
- MUST support
--versionand exit0. - Writes the version to stdout (it is data — principle №2).
Respond within 2 seconds
shll version, shll doctor, and the shared install probe run <tool> --version under a 2-second timeout (versionTimeout), and the worst case for shll version is len(roster) × versionTimeout — so a slow tool taxes the whole table.
- MUST respond within 2 seconds. This is a hard consumer bound: exceed it and shll’s probe kills the call. In
shll versionand the shared install probe that collapses to not installed — the same row as a missing binary.shll doctorkeeps the two apart: a timeout is an unreportable tool (installed but--versionfailed), distinct from a genuinely missing binary — see the failure mode below. - This implies no network I/O on the version path. A
--versionthat phones home (checks for updates, resolves a remote manifest) will intermittently blow the 2-second budget on a slow network and flap between “installed” and “not installed” across runs. The version path MUST be purely local.
The version is on the first non-empty line
shll parses the version by scanning the first non-empty line only and never looks past it:
- The version token MUST appear on the first non-empty line of output, as either:
- a bare token matching
v?\d+(\.\d+)*([.-][\w.+-]+)?(an optional leadingv, at least one numeric component, optional dotted components, optional[.-]<suffix>for pre-release / build metadata) — shll’sversionTokenRE; or - a line of the shape
<word> version <rest>(versioncase-insensitive), from which shll takes<rest>— shll’sversionPrefixRE.
- a bare token matching
- A banner-first layout is non-conformant. The parser does not scan past line 1, so an ASCII-art banner, a copyright line, or a “checking for updates…” notice printed above the version breaks the parse — shll reads that first line as the version. If it holds no version token and isn’t a
<word> version <rest>line, shll falls back to the trimmed first line verbatim, soshll versionprints the banner text where the version belongs. - RECOMMENDED canonical shape:
<tool> version vX.Y.Z— cobra’s stable default form, which satisfies both the prefix and token rules and is exactly what fab-kit’s self-update post-check parses (last whitespace field, strip a leadingv).
Failure mode. A version buried below a banner, or emitted with decorative framing, makes shll version print the wrong first line in the tool’s row. And if the version path errors, times out, or emits nothing on the first line at all, shll doctor flags an otherwise-healthy tool as unreportable (“installed but --version failed”).
The binary name on PATH equals the tool name
The version probe is also shll’s install-mechanism-agnostic install probe: shll runs <tool> --version by the tool’s name, and a proc.ErrNotFound (binary not on PATH under that name) is how shll concludes “not installed” — without querying brew, a package DB, or anything install-mechanism-specific.
- The binary name on
PATHMUST equal the tool name shll knows the tool by (the same one-string identity the update standard requires across repo / formula / binary). A differently-named binary reads as not installed everywhere —shll version,shll doctor, and every install check — even when it is present and healthy.
The one sanctioned exception is a rename in flight: when a tool declares a legacy name (the rk → run-kit precedent), shll retries the probe under the old binary name if the new one is absent from PATH, so a pre-rename install still reads as installed. This is transitional migration-guard machinery, not a licence for a lasting name mismatch — see the update standard’s formula_renames.json rule.
Verifying conformance
Before shipping a change that touches --version:
<tool> --versionexits0and writes the version to stdout.- It returns in well under 2 seconds with the network unplugged (no network I/O on the version path).
- The version token is on the first non-empty line — no banner, copyright, or update-check line above it — and matches the token regex or the
<word> version <rest>prefix shape (the RECOMMENDED<tool> version vX.Y.Zsatisfies both). - The binary’s name on
PATHis exactly the tool name (== repo == formula leaf). - Keep (or add) a minimal test pinning the above — exit 0, version on line 1, matches the shape — so the contract stays protected.