feat(cli): default amy stdout to human-readable text; --json opts in
amy's default stdout is now a YAML-ish render of the underlying result
map; the previous single-line JSON contract moves behind a global
`--json` flag. Errors mirror the same rule (`error: <code>: <detail>`
on stderr by default, JSON `{"error":...,"detail":...}` under --json).
Exit codes (0/1/2/124) and the --json shape itself are unchanged —
only the default presentation flips.
- Replaces Json.writeLine / Json.error with mode-aware
Output.emit / Output.error. The same Jackson mapper is reused for
on-disk JSON via Output.mapper.
- Adds `--json` to the global flag set in Main.kt; honoured even when
argument parsing fails so error JSON keeps shape under --json.
- Updates the test harness wrappers (amy_a / amy_b / amy_d in
cli/tests/{headless,dm,cache}/) and the few direct $AMY_BIN call
sites whose stdout is consumed via $() / 2>&1 — they now pass
--json so the existing jq pipelines keep working.
- Rewrites the README "Output contract" and DEVELOPMENT design
principles to describe the new default, and clarifies that only
--json is the public API; the text shape is allowed to drift.
This commit is contained in:
+15
-9
@@ -27,13 +27,18 @@ Amy exists for three audiences at once:
|
||||
|
||||
What every caller — user, script, agent, CI — can rely on:
|
||||
|
||||
- **stdout is JSON. One line. One object.** Stable snake_case keys.
|
||||
Pipe it into `jq`, parse it from Python, hand it to an agent.
|
||||
- **Default stdout is human-readable text.** A YAML-ish render of the
|
||||
underlying result map. Friendly at a terminal; no shape promises.
|
||||
- **`--json` is the machine contract. One line. One object.** Stable
|
||||
snake_case keys. Pipe it into `jq`, parse it from Python, hand it
|
||||
to an agent. Pass `--json` anywhere before the subcommand:
|
||||
`amy --json whoami`, `amy --data-dir ./alice --json marmot group list`.
|
||||
- **stderr is for humans.** Progress, warnings, per-relay ACK traces.
|
||||
Safe to discard.
|
||||
Safe to discard. Errors land here too: `error: <code>: <detail>` by
|
||||
default, or JSON `{"error":"…","detail":"…"}` under `--json`.
|
||||
- **Exit codes are the real signal.**
|
||||
- `0` — success
|
||||
- `1` — runtime error (JSON `{"error":"…","detail":"…"}` on stderr)
|
||||
- `1` — runtime error
|
||||
- `2` — bad arguments
|
||||
- `124` — `await` timed out
|
||||
- **No interactive prompts, ever.** Passwords, names, keys — all flags.
|
||||
@@ -42,9 +47,9 @@ What every caller — user, script, agent, CI — can rely on:
|
||||
Delete to reset; copy to move; `AMETHYST_CLI_DATA` env var overrides
|
||||
the default `./amy`.
|
||||
|
||||
The rationale behind each of these lives in
|
||||
[DEVELOPMENT.md](./DEVELOPMENT.md). Breaking any of them is a breaking
|
||||
change to Amy's public API.
|
||||
Only the `--json` shape and the exit codes are public API. The default
|
||||
text format is allowed to change between releases. The rationale lives
|
||||
in [DEVELOPMENT.md](./DEVELOPMENT.md).
|
||||
|
||||
---
|
||||
|
||||
@@ -159,10 +164,11 @@ amy --data-dir ./bob marmot await group --name "Test Group" --timeout 60
|
||||
amy --data-dir ./bob marmot message list <GID>
|
||||
```
|
||||
|
||||
Compose with `jq` to chain commands:
|
||||
Compose with `jq` to chain commands — pass `--json` so stdout switches
|
||||
from the default human-readable text to the parseable single-line JSON:
|
||||
|
||||
```bash
|
||||
GID=$(amy --data-dir ./alice marmot group create --name "Test" | jq -r .group_id)
|
||||
GID=$(amy --data-dir ./alice --json marmot group create --name "Test" | jq -r .group_id)
|
||||
```
|
||||
|
||||
For an interop-test script template, see
|
||||
|
||||
Reference in New Issue
Block a user