Skip to content

Add --json and --toon shorthand flags#2

Merged
jgowdy-godaddy merged 1 commit into
mainfrom
feature/output-shorthand-aliases
May 22, 2026
Merged

Add --json and --toon shorthand flags#2
jgowdy-godaddy merged 1 commit into
mainfrom
feature/output-shorthand-aliases

Conversation

@jgowdy-godaddy
Copy link
Copy Markdown
Collaborator

Summary

  • Adds --json and --toon as global boolean flags that act as shorthand for --output json and --output toon
  • Recognized in both the pre-parse extract_output_format path and the clap-based global_flags_from_matches path
  • Registered as proper clap args so they don't cause unknown-flag errors

Test plan

  • Unit tests in foundation.rs verify extract_output_format recognizes --json and --toon
  • Integration tests in derive_bridge.rs exercise both flags through the full Cli::run path
  • All 238 existing tests continue to pass

Comment thread docs/concepts.md
Users can now type `--json`, `--toon`, or `--human` instead of the
longer `--output json` / `--output toon` / `--output human`. Both
the pre-parse extraction path and clap-based parsing recognize these
flags.
@jgowdy-godaddy jgowdy-godaddy force-pushed the feature/output-shorthand-aliases branch from 8f5865c to fac7586 Compare May 22, 2026 21:09
@jgowdy-godaddy jgowdy-godaddy merged commit 8786373 into main May 22, 2026
1 check passed
jpage-godaddy added a commit that referenced this pull request Jun 5, 2026
…(DEVEX-695) (#13)

## Addresses Rust-port review item #2 ([PR #49
review](godaddy/cli#49 (comment)))
· DEVEX-695

**Original concern (item 2):** the TypeScript CLI root returned JSON
discovery (command tree + environment/auth snapshot + next actions); the
Rust port renders clap long-help text for the empty command path → an
agent-first discovery regression.

How each part of that concern is handled here:

| Review item #2 expectation | Status | Notes |
|---|---|---|
| Bare root returns **JSON** for agents (the regression) | ✅ Addressed |
Empty command path now emits a JSON discovery envelope in machine
context (piped / CI / agent, or `--output json`). |
| **next actions** | ✅ Addressed (superset) | Original three (`auth
status`, `env get`, `application list`) + `tree`. |
| **command tree** inline | 🔀 Pivot | Surfaced as a `next_actions`
pointer to `tree` (`godaddy tree --output json` returns the full tree)
instead of embedded — hypermedia model. |
| **environment / auth snapshot** inline | 🔀 Pivot | Reachable via the
`env get` / `auth status` pointers instead of embedded. |
| Always-JSON default | 🔀 Pivot | TTY-aware default instead (human in a
terminal, JSON when piped/CI/agent), with `--output` /
`${APP_ID}_OUTPUT` overrides. Whether to force always-JSON is left for
the team. |

Net: agent-first discovery is restored, in a leaner **hypermedia** form
— the bare command returns pointers and the agent follows `tree` / `auth
status` / `env get` for details, rather than one fat payload. Nothing
from item 2 was dropped silently; each element is either restored or a
deliberate pivot above.

**Scope:** this PR is the **cli-engine capability**. The `godaddy` CLI
adopts it (calls `with_root_next_actions(...)` and rides the TTY-aware
default) in a follow-up PR once this releases; that PR will be linked to
DEVEX-695.

---

## Summary

Makes the bare-invocation and help experience friendlier for **humans**
without sacrificing machine-readable output for **agents**. Three
related engine changes:

### 1. Root discovery (`with_root_next_actions`)
New opt-in `CliConfig::with_root_next_actions` hook. On bare invocation
(no subcommand):
- **human** output appends a **"Suggested next actions"** section
(cold-start guidance), and
- **machine** output emits a small discovery envelope — `{ data: {
description, version }, next_actions }`.

Actions are *pointers* to existing commands (e.g. `auth status`, `env
get`, `tree`), not embedded snapshots — the agent follows only what it
needs. With no hook configured, behavior is unchanged long-help
(back-compat for existing consumers).

### 2. Curated root/group help
- A root help template suppresses clap's **duplicate command list** and
the **global-options wall** (still shown on leaf commands, where they
matter).
- Group pages keep their subcommand list but drop the options wall.
- Categories — and the commands within each — are **sorted**.
- The engine-injected `auth` command is filed under an **admin
category** (`CliConfig::with_admin_category`, default `"Admin"`) so it
stays discoverable once the auto list is suppressed; any uncategorized
top-level command falls under a generic `"Commands"` section, so nothing
is ever lost.

### 3. TTY-aware default output format
Default output is now **human on an interactive terminal, JSON
otherwise** (pipes, files, CI, most agents). Precedence:
1. explicit `--output`/`--json`/`--toon`/`--human`
2. `${APP_ID}_OUTPUT` env (e.g. `GODADDY_OUTPUT=json`,
`GDX_OUTPUT=json`)
3. TTY policy

Uses `std::io::IsTerminal` — **no new dependency**. Agents that capture
output via pipes (the norm) keep getting JSON automatically; PTY-backed
agents can force it via the env var or a flag.

## Why
Restores agent-first discoverability for the bare command (the original
TypeScript GoDaddy CLI returned JSON discovery on bare invocation; ref
DEVEX-695) while making the human terminal experience pleasant — the
engine is shared by the godaddy CLI and gdx.

## Consumers
No consumer **code** change is required. There is, however, one
**runtime behavior change on dependency bump**: with the TTY-aware
default, **interactive-terminal** invocations now default to **human**
output where they previously got JSON — across all commands, including
the `--search` and `--schema` raw-bypass paths (previously hardcoded to
JSON). **Machine / piped / CI / agent output is unchanged (still
JSON)**, so real-world breakage is low. Prior behavior is fully
preserved via explicit `--output`/`--json`/`--toon`/`--human` or the
`${APP_ID}_OUTPUT` env (e.g. `GODADDY_OUTPUT=json`). Whether to instead
force always-JSON is an open one-way-door decision for the team to
settle before release.

The godaddy CLI adopts the `with_root_next_actions` hook (and rides the
`"Admin"` default) in a follow-up PR once this releases; gdx is
unaffected until it bumps the dependency (it would set
`with_admin_category("Administration")`).

## Testing
- New unit tests for the output-format resolver and env-var derivation
(pure, no real TTY needed).
- New consumer/foundation tests for bare-root human + JSON paths,
group/leaf help shaping, and auth categorization (default + override).
- Full suite green; `clippy -D warnings` clean; `cargo fmt` applied.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Jay Gowdy <jgowdy@godaddy.com>
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.

2 participants