fix(cli): return structured results from configure and auth login/logout in machine output modes

Merged
TR
19h ago
+192-24

Stacked on #140 (the cleared field reports values removed with configure --clear, and auth logout uses the config.DeleteStoredSecret helper from #140). Retarget to main once #140 merges.

Why

In machine output modes (-o json, -o yaml, -o toon, --jq, agent mode) a successful live configure, auth login or auth logout still printed prose such as Configuration saved to ... to stdout. The --dry-run path of the same commands already returns a structured no-op object, and whoami already returns a structured result, so scripts got a parseable answer from the preview but not from the real run.

What changed

On success, in machine mode the commands return an output.LocalResult instead of prose. Human output is unchanged.

  • configure: {"config_file": ..., "keychain_stored": bool, "cleared": [...]}. keychain_stored is present when the API declares secret credentials; cleared only when --clear removed something. This applies whether or not interactive features are generated.
  • configure resolves the output mode and format before it saves, via a new output.PinOutputFormat. Otherwise configure --default-output-format json (or clearing a saved json default) would change how its own result is rendered.
  • auth login: {"config_file": ..., "keychain_stored": bool}.
  • auth logout: {"config_file": ..., "cleared": true, "keychain_cleared": bool}. Logout still clears every credential from the config file, but if the OS keychain refuses to delete one it now returns an error naming the credential instead of reporting success, so keychain_cleared: true means the keychain deletes worked. An unavailable or unresponsive keychain is reported as skipped as before (keychain_cleared: false).
  • Primary tests for configure --clear JSON output (with a saved json default being cleared), auth logout JSON output, and a failed keychain delete on logout.
  • Review SDK regenerated; changeset added.

Example:

$ cli configure --api-version v1 -o json
{"config_file":"/home/user/.config/cli/config.yaml","keychain_stored":false}
$ cli configure --clear api-version -o json
{"cleared":["api-version"],"config_file":"/home/user/.config/cli/config.yaml","keychain_stored":false}

Testing

  • TARGET=review make test-cli and TARGET=primary make test-cli: pass.
  • make check-template-cli: passes.
  • Generated the review CLI with interactiveAuth: false and interactiveMode: false: builds, and configure -o json ends with the structured result.
  • Manually on a generated CLI: configure set and --clear under -o json, and auth logout -o json.

Public-safety check

  • This change contains no credentials, customer documents, private repository URLs, private filesystem paths, or unredacted private logs.
  • Title, body, comments, and commit messages name no customers or customer-derived identifiers, private paths or trackers, or workflow provenance, and are understandable without private context (.claude/skills/public-repo-communication/SKILL.md).
  • Generated fixtures and review SDK changes are public-safe.
  • I reviewed git diff --check.