fix(cli): real whoami auth, --json on provision verbs, headless login#32
Merged
Merged
Conversation
Three agent-DX fixes found in a dogfood pass: B1: whoami now validates the bearer token against GET /auth/me instead of reflecting local config. A bogus/expired token reports authenticated:false (exit 3) so an agent gating on `whoami --json | jq .authenticated` can no longer get a false positive. Network failures surface a distinct offline state (authenticated:false + error note, exit 1) rather than masquerading as logged-out. tier/email/team_name come from the server response. B2: every provisioning `new` verb (db/cache/nosql/queue/storage/webhook/ vector) honors --json, emitting the full structured response (token, connection_url/receive_url, environment, tier, env_override_reason) — the wedge action an agent most needs machine-readable. Errors funnel through the shared JSON envelope. U2: login honors $BROWSER on every platform and adds --no-browser, which prints the auth URL + session id and polls without attempting to spawn a browser — usable on headless/agent boxes. Named consts authMePath / browserEnvVar / defaultAPIBaseURL avoid scattered literals. 100%-patch coverage via httptest-mock tests for all new lines. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
mastermanas805
added a commit
that referenced
this pull request
Jun 10, 2026
…e, full token in list (#33) Four agent-DX follow-ups found in a live cohort dogfood (round 2, building on #32): F1 (P0): add `instant resource creds <token>` (alias `credentials`) — GETs /api/v1/resources/:id/credentials and prints the connection_url (webhook receive_url fallback; --json for the full response). Closes the broken first-provision recovery loop: `db new` frequently hits the 60s client timeout and the URL — printed only by `new` — was otherwise lost forever. Path fragment is the named const resourceCredsSuffix. F2 (P1): `webhook new` printed a blank `url` line — the human path read creds.ConnectionURL only, but /webhook/new returns receive_url. Fall back to ReceiveURL like the local token-store code already does. (--json already emits receive_url via emitProvisionJSON; verified.) F3 (P1): a 401 with INSTANT_TOKEN set advised `instant login`, which is useless — the env var SHADOWS any saved login. errSessionExpired() + classifyError() now branch on token SOURCE (new authFromEnvToken helper): an env-sourced reject tells the user to fix/unset INSTANT_TOKEN. This also fixes the dead session_expired JSON code (a 401 was mis-coded auth_required because errSessionExpired carries ExitAuthRequired). F4 (P2): `instant resources` truncated the token (`d3cef90f-a75…`) — the exact value every other command needs as an argument, so it was un-copyable. Print the FULL token; truncate the NAME column instead (new truncateName + nameDisplayMaxLen). --json unchanged. Tests: cmd/agent_dx_followups_test.go covers all four (creds happy/alias/json/ webhook-fallback/unauth/missing-token/empty/parse/server-error + token fallback; webhook receive_url human+json; env-vs-saved 401 advice + json action + flag-over-env; full-token + name-truncation + truncateName unit). 100%-patch on the diff; make ci green (build+vet+race+lint). Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A dogfood pass found three agent-facing issues in the
instantCLI. All three are fixed here in one PR.B1 (High) —
whoamifalse-positive authenticationSymptom:
instant whoami --token <bogus> --jsonreturned{"authenticated":true,"tier":"flag-token"}exit 0 for ANY non-empty token (andtier:"env-token"viaINSTANT_TOKEN).cmd/whoami.gowas a pure local-credential reflector that never validated against the server.Fix:
whoaminow callsGET /auth/me(named constauthMePath) and setsauthenticated:trueonly when the server confirms the token;tier/email/team_namecome from the/auth/meresponse. Offline handling: a transport failure reportsauthenticated:falsewith a distincterrornote (exit 1, "could not reach the server…") so a flaky network never masquerades as logged-out; a server 401/403 →authenticated:false+ exit 3 (session expired). No-token path is unchanged (clean anonymous, exit 0, no network). In--jsonmode stdout is a single JSON object; the human-readable reason goes to stderr (main.go), sowhoami --json | jq .authenticatedparses cleanly.B2 (Medium) — provision verbs reject
--jsonSymptom:
instant db new --name x --json→unknown flag: --jsonexit 1. The flag existed on resource/resources/whoami/status/etc. but NOT on the provisionnewverbs.Fix:
--jsonadded to every provisionnewverb (db/cache/nosql/queue/storage/webhook/vector — all route throughmakeProvisionCmd). Success emits the full structured response (token,connection_url/receive_url,env+environment,tier,env_override_reason,note). Errors funnel through the shared JSON envelope (provisionJSONadded tojsonModeOn).U2 (Medium) — login unusable on headless/agent boxes
Symptom:
browserLauncherForGOOShardcodedopen/xdg-open/rundll32, ignored$BROWSER; on a headless box it printed "Could not open browser automatically" then blocked polling 5 min with no escape.Fix: (a)
$BROWSER(named constbrowserEnvVar) takes precedence over the per-GOOS default on every platform, treated as a bare command name (no shell parsing). (b)--no-browserflag prints the login URL + session id to stdout and continues polling without ever attempting to launch a browser — the most useful behavior for a supervising agent (URL is captured, login still completes hands-free if a human/agent opens it). Interactive happy path unchanged.Gate
make ci(build + vet +-racetests) greengolangci-lint run→ 0 issuesorigin/master+ the cover profile; mirrors the CIdiff-cover --fail-under=100gate)authMePath,browserEnvVar,defaultAPIBaseURL) — no scattered literals🤖 Generated with Claude Code