feat(fj): global --format/--json output flag and JSON for all commands (FJ-23) #22
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/global-output-format-fj-23"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Implements FJ-23: a single global output-format flag so every command can emit stable, machine-readable JSON, with unchanged default (human-readable) behavior.
--format <text|json>flag (clapglobal = true) onApp, defaulting totextand accepted in any position for any subcommand, plus a--jsonshorthand.--jsonis equivalent to--format json; combining--jsonwith--format textis a usage error.OUTPUT_FORMATOnceCell (mirroringSPECIAL_RENDER), read everywhere viacrate::output_format()/crate::json_output(). Norun()signature threads a new parameter.--styleis forced to Minimal and all decorative, progress, spinner, interactive-prompt, browser, and fluent-rendered output is suppressed so stdout stays valid JSON.fj completionemits JSON following the issue taxonomy: reads/lists emit a record or array, mutations emit the affected resource (or{ "ok": true }), local side-effecting ops emit{ "path": ..., "ok": true }, browse commands emit{ "url": ... }without spawning a browser, andpr diff/pr patchwrap the raw text as{ "diff": ... }/{ "patch": ... }.serde::Serializeview (never serializingforgejo-apistructs directly), following thepr_to_jsonprecedent: RFC 3339 UTC timestamps, stable lowercase English field/enum names that are locale-independent and never routed through fluent.fjbinary, preserving the fj-core / fj-client MCP-reuse contract.json: boolclap fields onpr status/pr searchare removed and now driven by the global flag; both keep their existing schema unchanged.fj completionis documented as exempt and keeps emitting the raw completion script regardless of--format.Verification
cargo build,cargo clippy,cargo fmt --check, andcargo testall pass.cargo tree -p fj-client -p fj-core -e normal | grep -E 'clap|crossterm|fluent'returns nothing.fj --format text --json <cmd>exits non-zero with a clear conflict error;--format/--jsonappear on every subcommand's help (global).fj completion bashoutput is byte-identical with and without--json.pr status/pr searchJSON paths were left untouched (regression-safe), now driven by the global flag.Note on issue transition
This PR references the issue with a bare
#FJ-23(link only, noStatecommand). On Forgejo the VCS integration applies commit commands at push time, not merge time, so aState Donetrailer would resolve FJ-23 prematurely while this PR is still open. State is managed out-of-band: the issue isIn Progressnow and moves toDoneonly after a human merges.🤖 Generated with Claude Code
Add a global `--format <text|json>` flag (clap `global = true`) to `App`, defaulting to `text`, accepted in any position for any subcommand, plus a `--json` shorthand. `--json` equals `--format json`; pairing `--json` with `--format text` is a usage error. The resolved format is stored once in an `OUTPUT_FORMAT` OnceCell (mirroring `SPECIAL_RENDER`) and read everywhere via `crate::output_format()` / `crate::json_output()`, so no `run()` signature threads a new parameter. Under JSON, `--style` is forced to Minimal and all decorative, progress, spinner, browser, and fluent output is suppressed. Every command except `fj completion` now emits stable JSON on stdout under `--format json`, following the issue taxonomy: reads/lists emit a record or array, mutations emit the affected resource (or `{ "ok": true }`), local side-effecting ops emit `{ "path": ..., "ok": true }`, browse commands emit `{ "url": ... }` without spawning a browser, and `pr diff` / `pr patch` wrap the raw text as `{ "diff": ... }` / `{ "patch": ... }`. Each command renders through a local `serde::Serialize` view rather than serializing `forgejo-api` structs directly, following the existing `pr_to_json` precedent: timestamps are RFC 3339 normalized to UTC, field names and enum values are stable lowercase English and locale-independent (never routed through fluent). JSON serialization lives entirely in the `fj` binary, so the fj-core / fj-client MCP-reuse contract is preserved (`cargo tree -p fj-client -p fj-core -e normal | grep -E 'clap|crossterm|fluent'` still returns nothing). The per-subcommand `json: bool` clap fields on `pr status` and `pr search` are removed and now driven by the global flag; both produce their existing schema unchanged. `fj completion` is documented as exempt and keeps emitting the raw completion script regardless of `--format`. #FJ-23 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>