feat(render): default JSON-model renderer + bright-white values (v1.4.0)

Render(v) treats JSON as the model: in -json mode it prints v as JSON;
otherwise it paints it as text — object scalars on one line as key=value
(keys blue, values bright white: a structural key/value distinction, not
semantic color), nested objects indented, arrays one block per element,
field order preserved via an order-keeping JSON decode. EmitJSON(v) is
the JSON-only arm for commands that paint their own text. Operates on
JSON only, so core stays protobuf-free (NFR-4).

Adds White to the palette. The example gains an `inspect` command
demoing Render (text vs -json). design.md FR-4.5/4.6 document the
renderer and the "JSON is always the full record; synopsis-vs-detail is
text-only" principle.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-05 23:13:42 +02:00
parent 496557858d
commit d35e1f2832
5 changed files with 333 additions and 1 deletions
+10 -1
View File
@@ -7,7 +7,7 @@ SPDX-License-Identifier: Apache-2.0
| | |
| --- | --- |
| **Status** | Describes shipped behavior as of `v1.3.0` |
| **Status** | Describes shipped behavior as of `v1.4.0` |
| **Author** | Pim van Pelt `<pim@ipng.ch>` |
| **Last updated** | 2026-06-05 |
| **Audience** | Contributors, and authors of CLIs built on this library |
@@ -92,6 +92,15 @@ or JSON from the same code.
- **FR-4.3** With color off or JSON selected, no ANSI escapes MUST be emitted.
- **FR-4.4** Color MUST default on in the shell, off one-shot; `-color` overrides;
`-json` forces it off.
- **FR-4.5** `Render` MUST treat JSON as the model: in JSON mode it prints the
value as JSON; otherwise it paints it as text — object scalars on one line as
`key=value` (keys blue, values bright white, a purely *structural* distinction),
nested objects indented, arrays one block per element, source field order
preserved. It MUST NOT apply semantic (red/green) color; that is the caller's
job via its own printer (EmitJSON in the JSON arm, a painter otherwise).
- **FR-4.6** JSON MUST always be the full record. The synopsis-vs-detail choice
(a one-line overview list vs an expanded section) is a text-only concern; the
same command emits complete JSON in either case.
**FR-5 `App` entry point**