ux: render nested JSON as readable sub-sections in --human mode#104
ux: render nested JSON as readable sub-sections in --human mode#104somanshreddy merged 3 commits intomainfrom
Conversation
Nested objects and arrays in API responses were rendered as compact JSON strings, making --human output hard to read. Now they render as indented key-value sub-sections (get commands) and comma-separated or key=value inline formats (list commands). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Heterogeneous arrays (containing nulls or mixed types) were expanded via renderArrayOfObjects, losing null values. Now they fall back to compact JSON. The depth guard also uses compactJSON instead of formatValue, preventing empty collections from vanishing at max depth. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
jrusso1020
left a comment
There was a problem hiding this comment.
Nice work — clean decomposition, solid edge case handling, and thorough test coverage. The split between formatValue (single-line for tables) and renderNestedKeyValue (multi-line for key-value) is the right abstraction boundary. Null exclusion in isScalarArray/isFlatMap is a subtle but important detail. LGTM.
A few optional items below if you want to polish, none blocking.
Nit: Consider a blank line between numbered entries in renderArrayOfObjects
With objects that have 5+ fields, back-to-back entries become a wall of text:
[1]
Content: hello
Role: user
[2]
Content: hi
Role: model
A blank line between entries (maybe when the object has >2 keys) would improve scannability. Up to you — fine as-is for typical API shapes.
Nit: formatMapInline uses raw keys vs humanizeKey elsewhere
Table mode: code=bad_input, message=invalid
Key-value mode: Code: bad_input
This is clearly intentional for compactness in tables, but a one-line comment on formatMapInline noting the design choice would prevent a future contributor from "fixing" it.
Optional: doc note on vacuous truth for empty slices
isScalarArray([]any{}) and isObjectArray([]any{}) both return true. No functional impact since len(v) == 0 is checked first at every call site, but a brief doc note ("returns true for empty slices") would future-proof the contract if these helpers get reused.
Optional: name the separator width constant
valueIndent := prefix + strings.Repeat(" ", lipgloss.Width(label)+len(": ")+len(padding))len(": ") = 3 reads as a magic number. A const kvSeparator = ": " or brief comment would help.
- Blank line between array entries with 3+ fields for scannability - Comment on formatMapInline noting raw keys are intentional - Doc notes on vacuous truth for isScalarArray/isObjectArray - Extract kvSeparator constant for label-value separator width Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Merge activity
|

Description
Nested objects and arrays in API responses were rendered as compact JSON strings in
--humanmode (e.g.{"code":"not_found","message":"Video not found"}), making the output hard to scan.This PR makes the
HumanFormattercontext-aware for nested structures:Key-value mode (get commands) now renders nested data as indented sub-sections:
Table mode (list commands) renders string arrays as comma-separated and flat objects as
key=value:The approach is fully generic with no per-command special-casing. All 5 nesting types across 8 command groups are handled:
events,tags,supported_api_engines) -> comma-separatederror {code, message}) ->key=valueinline (tables) or indented sub-section (key-value)wallet,subscription) -> recursive indented sub-sectionsmessages,word_timestamps) -> numbered entries with indented fields(none)in key-value modeDesign decisions:
formatValue(shared single-line formatter) handles table cells.renderKeyValuehandles key-value mode separately to allow multi-line rendering.isScalarArray/isFlatMapexclude nil values to avoid malformed inline output like, xorkey=.formatCellfield-name-aware formatting (timestamps, durations) works at all nesting levels.Testing
make testpasses (all packages)make buildsucceeds🤖 Generated with Claude Code