Skip to content

refactor(output)!: emit table rows as NDJSON records, keyed by json tags - #135

Merged
Ilyes512 merged 1 commit into
fix/GH-119-non-interactive-promptsfrom
refactor/GH-109-ndjson-table-records
Sep 4, 2026
Merged

refactor(output)!: emit table rows as NDJSON records, keyed by json tags#135
Ilyes512 merged 1 commit into
fix/GH-119-non-interactive-promptsfrom
refactor/GH-109-ndjson-table-records

Conversation

@Ilyes512

@Ilyes512 Ilyes512 commented Sep 2, 2026

Copy link
Copy Markdown
Member

BREAKING CHANGE: -o json table output is one JSON object per line instead of
one array, its keys are snake_case from the row type's json tags instead of the
column headings, and each value keeps its own type. A pipeline reading
jq '.[].Name' becomes jq -r .name.

Table took [][]string, so the pretty renderer's display strings were the only
thing the JSON writer ever saw. A count arrived as "12", a timestamp as
whatever the table decided to render it as, and jq 'select(.count > 5)' could
not work on any of it. The array it emitted could not be parsed until its
closing bracket arrived, so a killed run left nothing readable — the property
NDJSON exists to provide, and which the docs already claimed. And the column
heading doubled as the JSON key, so one string was doing two jobs for two
audiences: prose a reader may reword freely, and what a consumer's filter
matches on.

None of the three could be fixed alone. Giving the two audiences separate
inputs answers the key-naming question by itself: a row type with json tags for
the consumer, Column headers for the reader, and a generic Table deriving both
from the same rows — which is also what now guarantees every row has exactly
one cell per header.

template list gains from the split immediately: it emits the timestamps
themselves rather than the "3 days ago" the table shows, and omits a field it
has no value for rather than the "-" placeholder. template update emits
up_to_date beside the status sentence, so a consumer filters on the fact
rather than on a phrase that may be reworded.

Closes #109


Stack created with GitHub Stacks CLIGive Feedback 💬

BREAKING CHANGE: `-o json` table output is one JSON object per line instead of
one array, its keys are snake_case from the row type's json tags instead of the
column headings, and each value keeps its own type. A pipeline reading
`jq '.[].Name'` becomes `jq -r .name`.

Table took [][]string, so the pretty renderer's display strings were the only
thing the JSON writer ever saw. A count arrived as "12", a timestamp as
whatever the table decided to render it as, and `jq 'select(.count > 5)'` could
not work on any of it. The array it emitted could not be parsed until its
closing bracket arrived, so a killed run left nothing readable — the property
NDJSON exists to provide, and which the docs already claimed. And the column
heading doubled as the JSON key, so one string was doing two jobs for two
audiences: prose a reader may reword freely, and what a consumer's filter
matches on.

None of the three could be fixed alone. Giving the two audiences separate
inputs answers the key-naming question by itself: a row type with json tags for
the consumer, Column headers for the reader, and a generic Table deriving both
from the same rows — which is also what now guarantees every row has exactly
one cell per header.

template list gains from the split immediately: it emits the timestamps
themselves rather than the "3 days ago" the table shows, and omits a field it
has no value for rather than the "-" placeholder. template update emits
up_to_date beside the status sentence, so a consumer filters on the fact
rather than on a phrase that may be reworded.

Closes #109
@Ilyes512
Ilyes512 marked this pull request as ready for review September 2, 2026 22:20
@Ilyes512
Ilyes512 merged commit 2ae6e40 into main Sep 4, 2026
5 checks passed
@Ilyes512
Ilyes512 deleted the refactor/GH-109-ndjson-table-records branch September 4, 2026 10:10
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.

output: JSONWriter.Table stringifies every value, emits an array rather than NDJSON, and uses headings as keys

1 participant