Skip to content

feat(output): pretty whoami + token-refresh fix + renderer cleanups#3

Merged
yurenju merged 3 commits into
mainfrom
claude/suspicious-mclean-6a3684
May 27, 2026
Merged

feat(output): pretty whoami + token-refresh fix + renderer cleanups#3
yurenju merged 3 commits into
mainfrom
claude/suspicious-mclean-6a3684

Conversation

@yurenju
Copy link
Copy Markdown
Contributor

@yurenju yurenju commented May 27, 2026

Companion to sadcoderlabs/wspc#350 which adds the upstream x-cli hints this branch consumes.

What this changes

Three handwritten commands move off raw JSON dumps onto the renderer:

  • wspc whoami — now a sectioned ENV / USER / ORG overview. Local env config (name, api_base, actor, agent_label) sits next to /auth/me and /auth/me/org. Org fetch is best-effort; --json / pipe emits a combined { env, user, org? } object.
  • wspc todo done — pretty path now mirrors wspc todo update (id-short, status badge, relative timestamps).
  • wspc config show — table of envs with green ✓ next to current, hides token contents entirely, shows auth mode (api_key / oauth / none).

Real bug fix in whoami:

runWhoami used to make a raw fetch to /auth/me with the persisted access_token. When that token had expired, the call 401'd and we returned { status: \"logged_out\" } — even though refresh_token + client_id were sitting right there in config. Any subsequent command going through loadSdkClient would refresh transparently and rewrite config.json, after which whoami suddenly worked again. Net effect: whoami's correctness depended on the order commands were run in.

Fix: route whoami through the same SDK + auth-interceptor pipeline as every other command. runWhoami is deleted (not part of the public SDK surface). WspcAuthExpiredError is caught locally and shown as logged_out — for a status-check command, auto-triggering re-login via dispatch() is too aggressive.

Renderer:

  • renderObject is now exported so handwritten renderers can compose sections without duplicating the field/format pipeline (used by whoami).
  • New codegen output: wspc auth me + wspc org show, driven by the upstream x-cli hints.

Commits

  • 8bfa1b6 chore: regenerate from wspc spec with auth_me + org_get x-cli
  • 59e8715 feat(output): route whoami, todo done, config show through the renderer
  • a086be5 fix(whoami): refresh expired access tokens instead of reporting logged_out

Verification

  • typecheck ✓
  • 14 test files / 52 tests ✓ (3 fetch-mock tests for the removed runWhoami dropped; SDK auth flow is already covered by sdk-auth.test.ts)
  • tsup build ✓
  • Smoke-tested in worktree: config show pretty (table with ✓), whoami logged_out (dim message + exit 1), config show --json (clean shape for jq)

Depends on

sadcoderlabs/wspc#350 needs to merge first if the spec ever needs to be re-synced from the live API — but the spec change is already committed to this branch (spec/openapi.json updated in 8bfa1b6), so this PR is independently mergeable today.

🤖 Generated with Claude Code

yurenju and others added 3 commits May 27, 2026 12:22
Adds two new generated commands:
- `wspc auth me`   — low-level GET /auth/me
- `wspc org show`  — GET /auth/me/org

Both flow through the pretty renderer with object-shape display hints.
SDK regen has no semantic changes beyond the two new operations.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three handwritten commands were still dumping raw JSON regardless of TTY,
which the rest of the CLI no longer does. Move them all to render():

- whoami: now a sectioned ENV / USER / ORG overview. Local env config
  (name, api_base, actor, agent_label) sits next to /auth/me and
  /auth/me/org. Org fetch is best-effort — missing org doesn't fail the
  command. `--json` / pipe emits a combined { env, user, org? } object.

- todo done: pretty path now mirrors `todo update` (id-short, status
  badge, relative timestamps). Display hints duplicated from the spec
  block; if codegen ever exports them, switch over.

- config show: renders a table of envs with a green ✓ next to current,
  hides token contents entirely (was just redacting strings), shows
  auth mode (api_key / oauth / none). JSON path emits { current_env,
  envs: [...] } — nicer for jq than the previous map shape.

Renderer changes are minimal — `renderObject` is now exported so
handwritten renderers can compose sections without duplicating the
field/format pipeline.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…d_out

`runWhoami` was making a raw fetch to /auth/me with the persisted
access_token. When that token had expired, the call 401'd and we
returned { status: "logged_out" } — even though refresh_token + client_id
were sitting right there in the config. Any subsequent command that
went through `loadSdkClient` would refresh the token transparently
(via the auth interceptor) and rewrite config.json, after which whoami
suddenly worked again. Net effect: whoami's correctness depended on the
order commands were run in.

Fix: route whoami through the same SDK + interceptor pipeline as
everything else. Side effects:

- `runWhoami` deleted (only the command and one test used it; not part
  of the public SDK surface). The relevant integration is already
  covered by sdk-auth.test.ts.
- WspcAuthExpiredError (refresh itself failed) is caught locally and
  shown as logged_out, rather than bubbling to dispatch() which would
  auto-trigger a re-login flow. For a status-check command that's too
  aggressive — user can re-login when they actually want to.
- /auth/me and /auth/me/org now fire in parallel via Promise.all; org
  remains best-effort polish.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@yurenju yurenju merged commit 1198505 into main May 27, 2026
1 check passed
@yurenju yurenju deleted the claude/suspicious-mclean-6a3684 branch May 27, 2026 05:33
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