Skip to content

Refine: one name for the API key, one window for usage, and the fixes a real box turned up - #1

Merged
lroolle merged 6 commits into
mainfrom
refine/env-naming-and-output
Aug 14, 2026
Merged

Refine: one name for the API key, one window for usage, and the fixes a real box turned up#1
lroolle merged 6 commits into
mainfrom
refine/env-naming-and-output

Conversation

@lroolle

@lroolle lroolle commented Aug 14, 2026

Copy link
Copy Markdown
Owner

Six commits from running bwg against a live box that had just come
back from a bandwidth suspension. Every change here is something that
box exposed.

What changed

BWG_API_KEY is the name. v0.1.0 accepted two spellings and the
code and the docs each picked a different one, so the pair people
copied was BWG_VEID + BWG_KIWIVM_API_KEY. The old name keeps
working, warns once per run on stderr, and goes at v1.0.

bwg info printed a bare rDNS heading with nothing under it
KiwiVM returns an entry per address whether or not a PTR is set.
output.Section prints a heading only when something survives under
it.

A box suspended for bandwidth was told see: bwg abuse, which
answers "nothing outstanding". It now names the likely cause and when
the quota resets, and still routes to bwg abuse when there is
actually an abuse case.

bwg usage dumped 608 rows and --days 7 trimmed the table but
not the totals, while --raw ignored the window entirely. One trim
now feeds table, --raw, totals and JSON; default 30 days; the render
says what it withheld.

bwg update was broken wherever $TMPDIR is a different filesystem
from the binary
(tmpfs /tmp): the install rename fails EXDEV.
Falls back to a copy.

Plus 1 keys1 key and friends.

Verification

make check          # gofmt, vet, -race, build — green
go test ./... -cover

Coverage 79.0% → 84.5%. mcp 56.6→86.4 (every tool actually runs now),
updater 50.0→79.2 (Download, the zip branch and the EXDEV fallback had
no tests at all), output 75.5→83.8, cli 77.8→81.8.

Design rulings behind the two judgement calls are in TASTE.md.

🤖 Generated with Claude Code

lroolle and others added 6 commits August 13, 2026 21:45
v0.1.0 accepted the key as either BWG_API_KEY or BWG_KIWIVM_API_KEY.
The code called the short one canonical; every README, skill file,
installer line and error message taught the long one. So the pair a
new user copied read

    export BWG_VEID=1347645
    export BWG_KIWIVM_API_KEY=private_xxx

— two halves of one credential in two styles, one of them namespaced
twice, with nothing in the tool saying which was real.

BWG_VEID and BWG_API_KEY now read as the pair they are. The old
spelling still authenticates, is documented in one README line, and
warns once per run on stderr naming the replacement; it goes at v1.0.
`bwg server show env` reports whichever variable is actually in play,
because a tool that will not say where its credentials came from is
how this got confusing in the first place.

BREAKING CHANGE: none yet — BWG_KIWIVM_API_KEY keeps working until
v1.0. Rename it now and the warning goes away.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Three things `bwg info` and its neighbours got wrong on a real box:

- KiwiVM returns one PTR entry per address whether or not a record
  is set, and Tabbed drops empty values, so `bwg info` printed a bare
  "rDNS" heading with nothing under it — which reads as data that
  failed to load. output.Section prints a heading only when something
  survives beneath it; Bandwidth, rDNS and Health all use it.

- A box suspended at 100% bandwidth with zero abuse points was told
  "see: bwg abuse", which correctly answered "nothing outstanding".
  A dead end at the moment the answer mattered. It now reads
  "yes — transfer quota exhausted (the usual cause); resets in 30d",
  phrased as the inference it is, and still points at bwg abuse when
  there are abuse points or a violation on the record.

- "1 keys", "1 points", "%d server(s)". output.Count(n, noun) means
  no message has to hedge with (s).

Also: colour detection is now a pure function over (env, isTTY) so
the NO_COLOR / BWG_COLOR / TERM=dumb precedence is testable without a
pty, and `bwg run` checks whether the stream it is about to read is a
terminal rather than asking os.Stdin on principle.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`bwg usage` defaulted to every sample KiwiVM kept — 600-odd rows,
oldest first, which put the recent end of the series and the quota
summary off the bottom of the screen.

The defect underneath was worse: --days 7 trimmed the table but not
the arithmetic, so seven rows sat above "Total: 5.9 TiB ... over
608d", and --raw ignored the window entirely. Three parts of one
screen describing three different spans, each individually correct.

One trim now feeds the table, --raw, the totals line and the JSON
payload, so they cannot disagree. The default window is 30 days —
the billing cycle the quota line underneath it is measured against —
and the render says what it withheld:

    Showing 30 of the 608 days KiwiVM kept — for all of it: bwg usage --days 0

JSON gains "window":{"days","available"}; "totals" now covers the
window rather than the whole series.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Download writes the new binary to $TMPDIR, which is a separate
filesystem from $HOME on most Linux boxes. os.Rename cannot cross
that boundary, so `bwg update` reported a failed install on a
perfectly healthy update — for anyone whose /tmp is a tmpfs.

Replace now falls back to copying into the target directory when the
rename fails, and still restores the old binary if the install does
not complete. Tests cover Download's asset selection, both archive
formats, the copy fallback and the restore path; the zip branch had
never been executed at all.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
internal/cli tests every command for breadth; the MCP run closures
are a second execution path and nothing called them. Coverage there
went 56.6% -> 86.4%, which is mostly "these fifteen tools do not
panic and return JSON an agent can read".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
TASTE.md gains the scars for the credential-name decision and the
usage window. SKILL.md and CLAUDE.md follow the JSON shape and the
new output helpers, so agents are not reading a second contract.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@lroolle
lroolle merged commit d62c718 into main Aug 14, 2026
4 checks passed
@lroolle
lroolle deleted the refine/env-naming-and-output branch August 14, 2026 04:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant