Skip to content

feat: add TOON usage output - #3021

Merged
steipete merged 1 commit into
steipete:mainfrom
elijahfriedman:feat/2996-toon-format
Aug 18, 2026
Merged

feat: add TOON usage output#3021
steipete merged 1 commit into
steipete:mainfrom
elijahfriedman:feat/2996-toon-format

Conversation

@elijahfriedman

@elijahfriedman elijahfriedman commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Resolves #2996

Summary

  • Adds codexbar usage --format toon, which emits the same data as --format json, encoded as TOON v4.1—a denser, human-readable format intended for agents that would otherwise parse JSON.

  • Adds ToonFormatter, a generic Encodable → TOON encoder rather than a hand-mapped schema. It round-trips values through a custom Encoder conformance into an order-preserving node tree instead of using JSONSerialization, which does not preserve key order, then serializes that tree according to the TOON spec.

    • Uniform arrays of scalar-only objects with identical ordered field sets collapse into table form: rows[N]{label,value}:.
    • Non-uniform arrays fall back to indented list form.
  • Reuses the existing --format json fetch/render pipeline for --format toon, including the same credits, color, and account behavior. Only the final output step changes.

  • Does not add .toon to the shared OutputFormat enum. That enum is used by several other commands with exhaustive format switches (hooks, config, cost, cache, and cookie), and adding full TOON support across those commands is outside the scope of this change.

  • usage --format toon is the only command wired up, and TOON recognition is scoped to that command in the resolver as well, so no other command's --format handling changes. This intentionally keeps the implementation to the MVP described in Feature request: --format toon for agent-compatible structured output #2996: a presentation-only formatter over the existing JSON schema, with no new data or providers.

Addressed review feedback

  • TOON recognition is restricted to the usage command.

    • The previous revision resolved toon inside the shared CLIOutputPreferences.from(values:), which is also called by cost, cache, config, hooks, diagnose, guard, plugins, and cookie. Those commands advertise only text | json, so they silently accepted --format toon and emitted JSON where they previously emitted text.
    • from(values:) and both resolveOutputFormat overloads now take an allowsToon parameter that defaults to false. resolveUsageOutputPreferences is the only site that passes true.
    • The argv-level bootstrap scanner derives the same verdict from the command itself via commandSupportsToon(argv:), which mirrors effectiveArgv: a leading usage, or a bare codexbar --format toon that resolves to the implicit usage command.
    • Every other command is back to its exact pre-TOON decoding: toon is an unrecognized --format value that falls through to text, or to JSON only when --json / --json-only is also passed—identical to how --format xml has always behaved.
    • docs/cli.md now states this explicitly: usage --format toon is the only command that supports it, and every other command accepts only --format text|json.
  • Early failures now render as TOON, both before and after argument parsing.

    • CLIOutputPreferences carries a toonRequested flag.
    • Post-parse paths inside runUsage—including Self.exit, printError, and loadConfig—respect it.
    • CLIOutputPreferences.from(argv:) provides an argv-level bootstrap scanner for failures that happen before ParsedValues exists, such as Program.resolve rejecting an unknown option.
    • Both --format toon and --format=toon are recognized, so early exits remain consistent with the requested output format rather than falling back to JSON or plain stderr text.
  • --help advertises TOON.

    • CLIHelp.usageHelp and CLIHelp.rootHelp—the hand-written help strings that CLIEntry actually prints ahead of Commander's descriptor—now advertise text|json|toon and include a --format toon example. codexbar cost and the other commands keep advertising --format text|json, which now matches their behavior exactly.
  • Tabular collapse no longer fabricates fields.

    • CodexBar's JSON payloads use encodeIfPresent for optional fields, so an absent value means the key is omitted rather than encoded as null.
    • Table form now requires every row to have exactly the same fields in exactly the same order.
    • Otherwise, the formatter falls back to list form, where each row contains only the fields actually present. No synthetic null values are introduced.
  • Non-finite doubles are rejected.

    • The TOON encoder rejects non-finite floating-point values, keeping the output valid and avoiding values that TOON consumers cannot reliably round-trip.
  • Commander does not reject --format toon during parsing.

    • I checked the vendored Commander source: CommandParser.parse does not validate an option value against its declared type. It only rejects unknown option names and missing values.
    • The @Option property's ExpressibleFromArgument constraint is compile-time-only, and CommanderError.invalidValue has no call sites in the package.
    • This was also confirmed empirically: usage --format toon parses and renders TOON successfully.
    • As a result, the P1 concern that Commander rejects --format toon at parse time does not reproduce, and no parser change is required.

Tests

  • ToonFormatterTests

    • Flat objects
    • Tabular collapse for uniform scalar arrays
    • List-form fallback for non-uniform field sets
    • Omitted optional fields, including assertions that no null is fabricated and no {...} table header is emitted
    • Inline primitive arrays
    • Empty arrays
    • TOON quoting rules
    • ISO 8601 dates
    • End-to-end ProviderPayload encoding
  • CLIOutputTests

    • renderProviderPayloads selects TOON vs. JSON based on toonRequested
    • The argv bootstrap scanner recognizes both --format toon and --format=toon
    • A later --json overrides an earlier TOON request
    • Command boundary: the same ParsedValues resolves to TOON through resolveUsageOutputPreferences and to plain text through the shared from(values:)
    • Command boundary: decodeFormat returns .text for --format toon, and .json only when --json is present—identical to its handling of an unrelated unsupported value such as xml
    • Command boundary: an argv sweep over cost, cache, config, hooks, diagnose, guard, and serve asserts no TOON request and no format change, while the implicit-usage form (--format toon with no command) still resolves to TOON
  • CLIEntryTests

    • Two real entry-point regression tests spawn the built binary with an unrecognized option, exercising a genuine Program.resolve parse failure
    • Both --format toon and --format=toon are verified to emit the TOON error payload on stdout
    • Command boundary: cost, diagnose, and cache invoked with --format toon and an unrecognized option must keep stdout empty and report the parse failure as text on stderr

Each of the new command-boundary tests was verified to be discriminating: with the scoping fix temporarily reverted, all three fail; with it restored, all three pass.

  • CLIProviderSelectionTests

    • usageHelp and rootHelp advertise --format text|json|toon

Verification

  • swift build — clean

  • make check — clean, 0 lint violations

  • Focused CLI suites (CLIOutputTests, CLIEntryTests) — passing, including all new command-boundary regressions

  • Full make test — every suite passes except two pre-existing AdaptiveRefreshTimerTests timing failures (AdaptiveRefreshTimerTests.swift:39 and :78, both 30s CancellationError while waiting on store.adaptiveRefreshScheduledAt). Those reproduce identically with this PR's changes stashed out; they live in the app's UsageStore refresh-timer path and come from unrelated commits on this branch.

  • Validated real CLI behavior with:

    • codexbar usage --bogus-flag-xyz --format toon
    • codexbar usage --bogus-flag-xyz --format=toon
  • Decoded real output with the official reference decoder, @toon-format/toon v4.1.1, confirming interoperability with the published TOON spec.

Real CLI behavior

$ codexbar usage --bogus-flag-xyz --format toon
[1]:
  - provider: cli
    source: cli
    error:
      code: 1
      message: Unknown option --bogus-flag-xyz
      kind: args

$ codexbar usage --bogus-flag-xyz --format=toon
[1]:
  - provider: cli
    source: cli
    error:
      code: 1
      message: Unknown option --bogus-flag-xyz
      kind: args

Interoperability with a real TOON consumer

Decoded real output using the official reference decoder, @toon-format/toon v4.1.1, matching the spec version targeted by this encoder and independent of CodexBar's own tests:

  1. CLI parse failure: The transcript above decodes to the same data as CodexBar's --format json output for the same invocation, byte-for-byte after accounting for key order.
  2. Tabular collapse: rows[2]{id,label}: decodes to {"rows":[{"id":1,"label":"Ada"},{"id":2,"label":"Bob"}]}.
  3. Omitted optional field: The post-fix rows[2]: list form decodes to {"rows":[{"id":1,"note":"hi"},{"id":2}]}. Row 2 has no note key, exactly matching the JSON produced by encodeIfPresent.

Example

$ codexbar usage --provider claude --format toon
[1]:
  - provider: claude
    account: null
    source: oauth
    usage:
      primary:
        usedPercent: 7
        windowMinutes: 300
      details[1]:
        - title: Usage summary
          rows[2]{label,value}:
            Requests,"120"
            Tokens,4.2k
      updatedAt: "2026-08-17T02:00:00Z"

@clawsweeper

clawsweeper Bot commented Aug 17, 2026

Copy link
Copy Markdown

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

@clawsweeper clawsweeper Bot added P3 Low-risk cleanup, docs, polish, ergonomics, or speculative feature. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Aug 17, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6df165e4ed

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread Sources/CodexBarCLI/CLIUsageCommand.swift Outdated
Comment thread Sources/CodexBarCLI/CLIOptions.swift
@elijahfriedman
elijahfriedman marked this pull request as draft August 17, 2026 20:04
@clawsweeper

clawsweeper Bot commented Aug 17, 2026

Copy link
Copy Markdown

Codex review: found issues before merge. Reviewed August 17, 2026, 7:54 PM ET / 23:54 UTC.

ClawSweeper review

What this changes

This PR adds codexbar usage --format toon, rendering existing usage payloads as TOON with CLI error handling, help/docs, and regression coverage.

Merge readiness

⚠️ Ready for maintainer review - 4 items remain

The implementation is a coherent, well-proven usage-only TOON formatter, but it adds a maintained public CLI contract and needs a maintainer product decision before merge.

Priority: P3
Reviewed head: c20c3a49e1fefee7997babac37920f15cd8316f8
Owner decision: Required. See Decision needed.

Review scores

Measure Result What it means
Overall readiness 🐚 platinum hermit (4/6) The patch is focused and strongly evidenced; only a small documentation-scope correction and product approval remain.
Proof confidence 🦞 diamond lobster (5/6) Sufficient (terminal): The PR body provides after-fix terminal output for both format syntaxes and reports successful decoding by the TOON v4.1 reference decoder.
Patch quality 🐚 platinum hermit (4/6) 1 actionable review finding remain.

Verification

Check Result Evidence
Real behavior Verified Sufficient (terminal): The PR body provides after-fix terminal output for both format syntaxes and reports successful decoding by the TOON v4.1 reference decoder.
Evidence reviewed 5 items Usage-only output boundary: TOON is explicitly opt-in for the usage command; shared output preferences default to rejecting it for other commands.
TOON contract implementation: The new formatter targets TOON v4.1 and preserves object field order while selecting table form only for uniform scalar rows.
Current release baseline: The v0.52.0 source still advertises only text and JSON for the usage format, so this capability is not already shipped.
Findings 1 actionable finding [P3] Limit the format claim to commands that support it
Security None None.

How this fits together

CodexBar’s CLI collects provider usage payloads and renders them for terminal and agent consumers. The PR adds TOON only at the final usage-output rendering step, leaving provider fetching and other commands unchanged.

flowchart LR
A[CLI arguments] --> B[Usage command]
B --> C[Provider usage payloads]
C --> D[Output preference]
D --> E[JSON renderer]
D --> F[TOON renderer]
E --> G[Terminal and agents]
F --> G
Loading

Decision needed

Question Recommendation
Should CodexBar adopt TOON v4.1 as a maintained public output contract for usage while keeping every other command unchanged? Adopt usage-only TOON: Approve the v4.1 usage-only contract and retain the existing JSON-equivalent payload boundary.

Why: The patch is bounded and proof-backed, but accepting a new documented machine-readable format commits the project to compatibility expectations beyond an internal display change.

Before merge

  • Limit the format claim to commands that support it (P3) - The sentence says every other command accepts --format text|json, but commands such as cards, sessions, dashboard, and serve have no --format option. Scope this to commands that already expose --format so the docs do not advertise unsupported invocations.
  • Resolve merge risk (P1) - Merging creates a documented TOON v4.1 machine-readable output contract that agents may rely on as the usage schema and TOON specification evolve.
  • Complete next step (P2) - A maintainer must decide whether the new TOON output is a supported public compatibility commitment before this otherwise bounded PR can merge.

Findings

  • [P3] Limit the format claim to commands that support it — docs/cli.md:58-59
Agent review details

Security

None.

Review metrics

Metric Value Why it matters
Implementation and coverage production +735 net, tests +576, docs +7 net The generic serializer is substantial but is paired with focused CLI, snapshot, and formatter coverage.
Changed surface 13 files affected The feature spans rendering, argument handling, error paths, help, documentation, and tests.

Root-cause cluster

Relationship: fixed_by_candidate
Canonical: #2996
Summary: This PR explicitly implements the feature request’s usage-only TOON output proposal.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge-risk options

Maintainer options:

  1. Adopt the usage-only contract (recommended)
    Approve the documented TOON v4.1 mapping as a compatibility commitment limited to codexbar usage.
  2. Pause the new output mode
    Keep JSON as the sole structured usage format if maintaining a second serialized contract is not desired.

Technical review

Best possible solution:

If the public contract is approved, land the narrowly scoped usage-only formatter and clarify that only commands which already expose --format accept text or JSON.

Do we have a high-confidence way to reproduce the issue?

Not applicable: this PR adds a new optional output mode rather than fixing a reported failing behavior; its body supplies after-fix CLI transcripts and TOON-decoder results.

Is this the best way to solve the issue?

Unclear pending product approval: the usage-only implementation is the narrowest technical path, but maintainers must choose whether to support this additional public output contract.

Full review comments:

  • [P3] Limit the format claim to commands that support it — docs/cli.md:58-59
    The sentence says every other command accepts --format text|json, but commands such as cards, sessions, dashboard, and serve have no --format option. Scope this to commands that already expose --format so the docs do not advertise unsupported invocations.
    Confidence: 0.96

Overall correctness: patch is correct
Overall confidence: 0.93

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against f7723d33a169.

Labels

Label justifications:

  • P3: This is an optional new CLI output mode rather than a current user-facing regression.
  • merge-risk: 🚨 compatibility: The PR documents a new machine-readable output format that callers may treat as a stable CLI contract.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): The PR body provides after-fix terminal output for both format syntaxes and reports successful decoding by the TOON v4.1 reference decoder.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body provides after-fix terminal output for both format syntaxes and reports successful decoding by the TOON v4.1 reference decoder.

Evidence

What I checked:

Likely related people:

  • Peter Steinberger: Available blame ties the existing format resolver and implicit usage-command routing to the current release baseline. (role: current-main CLI output-contract owner; confidence: medium; commits: dc3ea3206c70; files: Sources/CodexBarCLI/CLIHelpers.swift, Sources/CodexBarCLI/CLIEntry.swift, Sources/CodexBarCLI/CLIOutputPreferences.swift)

Rank-up moves

Optional improvements that raise the rating; they are not merge blockers.

  • Clarify that the text/json statement applies only to commands that already support --format.
  • Obtain a maintainer decision on maintaining TOON as a public usage-output contract.

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

Workflow

  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

History

Review history (11 earlier review cycles; latest 8 shown)
  • reviewed 2026-08-17T20:23:40.520Z sha 4320987 :: needs real behavior proof before merge. :: [P1] Accept TOON in the usage argument parser | [P2] Preserve omitted fields when rendering table rows | [P2] Run the required full test suite
  • reviewed 2026-08-17T20:40:48.095Z sha 1393312 :: found issues before merge. :: [P2] Run the required full test suite
  • reviewed 2026-08-17T20:56:21.370Z sha 1393312 :: needs changes before merge. :: [P2] Reject non-finite values instead of reporting zero | [P2] Use one precedence rule for TOON and JSON
  • reviewed 2026-08-17T21:54:50.447Z sha bd27d35 :: needs changes before merge. :: [P2] Use one precedence rule for TOON and JSON
  • reviewed 2026-08-17T22:57:06.278Z sha c1b42bc :: found issues before merge. :: [P2] Restrict TOON recognition to the usage command
  • reviewed 2026-08-17T23:03:54.844Z sha c1b42bc :: found issues before merge. :: [P2] Restrict TOON recognition to the usage command
  • reviewed 2026-08-17T23:31:08.616Z sha 022b116 :: needs maintainer review before merge. :: none
  • reviewed 2026-08-17T23:39:00.546Z sha a7a0df1 :: needs maintainer review before merge. :: none

@elijahfriedman

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Aug 17, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event exact_review_queue).
Result: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

@clawsweeper clawsweeper Bot added proof: sufficient Contributor real behavior proof is sufficient. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. proof: sufficient Contributor real behavior proof is sufficient. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. labels Aug 17, 2026
@elijahfriedman
elijahfriedman marked this pull request as ready for review August 17, 2026 20:49

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1393312e7b

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread Sources/CodexBarCLI/ToonFormatter.swift Outdated
@clawsweeper clawsweeper Bot added merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. P2 Normal priority bug or improvement with limited blast radius. and removed P3 Low-risk cleanup, docs, polish, ergonomics, or speculative feature. labels Aug 17, 2026
@elijahfriedman

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Aug 17, 2026

Copy link
Copy Markdown

🦞👀
Exact review queued.

Re-review progress:

@clawsweeper clawsweeper Bot added P3 Low-risk cleanup, docs, polish, ergonomics, or speculative feature. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed P2 Normal priority bug or improvement with limited blast radius. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. labels Aug 17, 2026
@steipete
steipete merged commit 64df00b into steipete:main Aug 18, 2026
9 checks passed
steipete added a commit that referenced this pull request Aug 18, 2026
@elijahfriedman
elijahfriedman deleted the feat/2996-toon-format branch August 18, 2026 00:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. P3 Low-risk cleanup, docs, polish, ergonomics, or speculative feature. proof: sufficient Contributor real behavior proof is sufficient. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature request: --format toon for agent-compatible structured output

2 participants