Skip to content

Commit 21d4904

Browse files
fix(cli): BugBash B15 P0 fixes — whoami env-token, --version stamping, sub-cmd exit codes, --json error envelope
Resolves four P0 findings from B15 BugBash 2026-05-20: 1. **whoami respects INSTANT_TOKEN.** whoami.go now reads INSTANT_TOKEN from the env first (with TrimSpace) and falls back to cliconfig. Mirrors the existing precedence in cmd/root.go::initConfig. Env-token agent runs no longer appear anonymous. whoami --json now resolves api_url from INSTANT_API_URL env or APIBaseURL fallback so api_url:"" is gone. 2. **--version is stamped.** main.go declares Version/Commit/BuildTime vars wired in at link time via -X ldflags; SetBuildInfo() propagates them into the cobra root's Version field. New VERSION file (0.2.0). Makefile builds with -ldflags "-X main.Version=$(cat VERSION) -X main.Commit=$(git rev-parse --short HEAD) -X main.BuildTime=..." so CLAUDE.md rule 14 (build-SHA gate) can be enforced via `instant --version | grep <sha>`. Local verify works: $ make version instant version 0.2.0 (eadcc21, 2026-05-20T14:26:38Z) 3. **Unknown sub-sub-commands exit non-zero.** dbCmd/cacheCmd/nosqlCmd/ queueCmd (plus new storageCmd/webhookCmd/vectorCmd) now ship via newGroupCmd() which sets Args:NoArgs + RunE that prints help when called bare. cobra's "unknown command" error fires for any positional arg that doesn't match a registered sub-sub-command: $ instant db delete some-token Error: unknown command "delete" for "instant db" exit code 1 4. **--json mode emits JSON error envelopes.** New cmd/json_error.go defines wrapJSONErr() that intercepts errors when --json is on, emits {ok:false, error, message, agent_action, exit_code, ...} to stdout, and suppresses cobra's usage block. Wired into resources, status, whoami, resource detail/delete. Network errors get classified as "network_error" with a stable agent_action so DNS failures don't surface as raw Go strings. Also addresses B15 P1 findings: - INSTANT_TOKEN env value is TrimSpace'd in root.go::initConfig and haveAuth() so $(cat .pat) trailing newline doesn't break auth. - whoami --json api_url resolves correctly when cliconfig is empty. - Network errors → network_error envelope (DNS lookup, connection refused). Scope-gap additions (B15 missing surface): - `instant storage new --name X` — provisions DO Spaces / R2 prefix. - `instant webhook new --name X` — provisions a webhook receiver URL. - `instant vector new --name X` — provisions Postgres + pgvector. - `instant resource <token>` — detail view (GET /api/v1/resources/:token). - `instant resource delete <token>` — destructive op with --yes gate. Non-TTY stdin without --yes refuses to fire (prevents accidental pipe-driven deletes). On success, also drops the entry from the local ~/.instant-tokens store via tokens.Store.Remove(). Deploy commands are intentionally out of scope — they need a multipart client that doesn't exist in cli/ yet (per the BugBash brief). Test coverage (all pass under -race): TestWhoami_RespectsInstantToken — B15-P0 (1) TestWhoami_RespectsInstantToken_TrimsWhitespace — B15-P1 TestRoot_VersionStamped — B15-P0 (2) TestUnknownSubcommand_ExitNonZero — B15-P0 (3) TestUnknownSubcommand_BareGroupPrintsHelp — B15-P0 (3) no-regression TestJSONMode_ErrorEnvelope — B15-P0 (4) TestJSONMode_NetworkErrorWrapped — B15-P1 network classifier TestExtras_StorageWebhookVector — new commands smoke TestExtras_ResourceDetail TestExtras_ResourceDeleteRequiresYes TestExtras_ResourceDeleteWithYes TestExtras_ResourceDelete_JSON Files: Makefile — ldflags + install + version targets VERSION — new file, contents: 0.2.0 main.go — Version/Commit/BuildTime vars + SetBuildInfo cmd/root.go — cobra.Command.Version + SetBuildInfo + TrimSpace cmd/whoami.go — INSTANT_TOKEN env-first + api_url resolution cmd/monitor.go — newGroupCmd() helper, Args:NoArgs + RunE cmd/extras.go — new: storage/webhook/vector + resource <token> cmd/json_error.go — new: wrapJSONErr + envelope schema cmd/discover.go — wrap resources errors via wrapJSONErr cmd/up.go — haveAuth TrimSpace cmd/testapi_test.go — handle /vector/new, GET resource detail cmd/integration_test.go — resetJSONFlags covers resource cmd flags cmd/bughunt_b15_test.go — new: 11 regression tests internal/tokens/store.go — new: Store.Remove(token) bool Coverage block (CLAUDE.md rule 17): Symptom: whoami ignores INSTANT_TOKEN; no --version; sub-sub-cmd exit 0; --json crashes jq pipes Enumeration: rg INSTANT_TOKEN cli/ → 4 hits, all root/up/whoami; rg "cobra.Command{Use" cli/cmd/ → 4 parent groups + 4 new; rg -- "--json" cli/cmd/ → 6 sites Sites found: INSTANT_TOKEN: 4; parent-group: 7; --json: 6 Sites touched: INSTANT_TOKEN: 3 read sites + 1 doc line; parent-group: 7/7 via newGroupCmd helper; --json: 6/6 funnel through wrapJSONErr Coverage test: TestUnknownSubcommand_ExitNonZero iterates the live group list (db/cache/nosql/queue/storage/webhook/vector); TestJSONMode_ErrorEnvelope drives a 401 through resources --json and asserts envelope shape. Live verified: awaiting user verification — pushed to master per brief; ci.yml runs `go test ./... -v -race -count=1` which equals the local `make ci` gate (rule 23). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent eadcc21 commit 21d4904

14 files changed

Lines changed: 1221 additions & 88 deletions

File tree

‎Makefile‎

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,40 @@
22
# The local gate (`make test`) is IDENTICAL to the CI gate so a CLI change
33
# cannot pass locally and fail in CI (or vice versa).
44

5-
.PHONY: all build vet test test-race test-integration test-livesmoke ci clean
5+
.PHONY: all build vet test test-race test-integration test-livesmoke ci clean install version
6+
7+
# ── B15-P0 (2) — build-info stamping ────────────────────────────────────────
8+
# Wired in at link time via Go's -X linker flag. CLAUDE.md rule 14 (build-SHA
9+
# gate) requires every deploy to verify the live binary's commit matches
10+
# `git rev-parse --short HEAD`. The `make build` target stamps real values;
11+
# unflagged `go build` falls back to the "dev" / "unknown" defaults declared
12+
# in main.go so `go test` and `go run` still work.
13+
VERSION := $(shell cat VERSION 2>/dev/null || echo dev)
14+
COMMIT := $(shell git rev-parse --short HEAD 2>/dev/null || echo unknown)
15+
BUILD_TIME := $(shell date -u +%Y-%m-%dT%H:%M:%SZ)
16+
LDFLAGS := -X main.Version=$(VERSION) -X main.Commit=$(COMMIT) -X main.BuildTime=$(BUILD_TIME)
617

718
# `make` with no target = the full local gate.
819
all: ci
920

21+
# build — produces the `instant` binary with version stamping. Drop into
22+
# bin/instant so `make install` can pick it up; `go build ./...` builds every
23+
# package which is what CI's gate wants.
1024
build:
11-
go build ./...
25+
go build -ldflags "$(LDFLAGS)" ./...
26+
27+
# install — drop the stamped binary under bin/ for local verification of
28+
# `instant --version`. Use `go install` semantics: produce one binary named
29+
# `instant`.
30+
install:
31+
mkdir -p bin
32+
go build -ldflags "$(LDFLAGS)" -o bin/instant .
33+
34+
# version — for the deploy ritual (CLAUDE.md rule 23 step 4). After building,
35+
# `make version` prints what the binary will report so an operator can grep
36+
# the expected SHA before shipping.
37+
version: install
38+
./bin/instant --version
1239

1340
vet:
1441
go vet ./...

‎VERSION‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0.2.0

0 commit comments

Comments
 (0)