List commands: add --paginate and surface total-count so scripts can detect truncation #111

Closed
opened 2026-06-11 00:08:49 +00:00 by stephen · 0 comments
Owner

Task

Make list commands report completeness instead of silently truncating. Two parts:

  1. Add --paginate to the purpose-built list commands (pr list, issue list, repo list, release list), reusing the Client::get_all / Link: rel=next machinery that already backs fj api --paginate and the opts.limit > 50 branch in src/api/pull_core.rs.
  2. In --json mode, surface the total so a consumer can compare returned vs. available. Thread the already-parsed Page::total (X-Total-Count) through; emit an envelope ({ "total_count": N, "items": [...] }) or at minimum expose the count. For human output, print a dim footer when truncated (returned == limit < total): Showing 30 of 104. Use --limit or --paginate for more.

Source: rasterstate/fj#107.

Priority

p1. The single most dangerous automation failure mode: a truncated result set is indistinguishable from a complete one, so an agent calling fj issue list --json to "get all open issues" silently acts on a partial slice. Directly undercuts the JSON-for-scripts-and-agents core pitch, so it tops the scripting-reliability axis of the north-star.

Reason

Page<T> already parses total, next, prev, last, first, but every field is #[allow(dead_code)] (src/client/pagination.rs); handlers consume only page.items. Defaults compound it (all four lists default to 30) and the only paging escape hatch (--paginate) exists solely on fj api, not on any list command. gh mirrors api --paginate with list-level paging plus X-Total-Count. A team scripting triage on fj today cannot tell a complete set from a capped one.

Acceptance

  • fj <pr|issue|repo|release> list --paginate follows Link: rel=next and returns the full set.
  • fj issue list --json (and siblings) exposes the server total (envelope or count field) so returned-vs-total is comparable.
  • Human-facing list output prints a truncation footer when returned == limit < total.
  • The #[allow(dead_code)] on the consumed Page<T> metadata fields is removed (no longer dead).
  • Each list command's --help documents the default --limit and that results may be capped.
  • Wiremock coverage in src/client/integration_tests.rs for a multi-page list and the total surfaced in JSON.
  • cargo fmt --check, cargo clippy --all-targets --all-features -- -D warnings, and cargo test --all pass.

Dependencies

None. The get_all / Link-parsing machinery already exists; this is wiring it into the list handlers and threading existing parsed metadata.

Size

M

## Task Make `list` commands report completeness instead of silently truncating. Two parts: 1. Add `--paginate` to the purpose-built `list` commands (`pr list`, `issue list`, `repo list`, `release list`), reusing the `Client::get_all` / `Link: rel=next` machinery that already backs `fj api --paginate` and the `opts.limit > 50` branch in `src/api/pull_core.rs`. 2. In `--json` mode, surface the total so a consumer can compare returned vs. available. Thread the already-parsed `Page::total` (`X-Total-Count`) through; emit an envelope (`{ "total_count": N, "items": [...] }`) or at minimum expose the count. For human output, print a dim footer when truncated (returned == limit < total): `Showing 30 of 104. Use --limit or --paginate for more.` Source: `rasterstate/fj#107`. ## Priority p1. The single most dangerous automation failure mode: a truncated result set is indistinguishable from a complete one, so an agent calling `fj issue list --json` to "get all open issues" silently acts on a partial slice. Directly undercuts the JSON-for-scripts-and-agents core pitch, so it tops the scripting-reliability axis of the north-star. ## Reason `Page<T>` already parses `total`, `next`, `prev`, `last`, `first`, but every field is `#[allow(dead_code)]` (`src/client/pagination.rs`); handlers consume only `page.items`. Defaults compound it (all four lists default to 30) and the only paging escape hatch (`--paginate`) exists solely on `fj api`, not on any list command. `gh` mirrors `api --paginate` with list-level paging plus `X-Total-Count`. A team scripting triage on `fj` today cannot tell a complete set from a capped one. ## Acceptance - [ ] `fj <pr|issue|repo|release> list --paginate` follows `Link: rel=next` and returns the full set. - [ ] `fj issue list --json` (and siblings) exposes the server total (envelope or count field) so returned-vs-total is comparable. - [ ] Human-facing list output prints a truncation footer when `returned == limit < total`. - [ ] The `#[allow(dead_code)]` on the consumed `Page<T>` metadata fields is removed (no longer dead). - [ ] Each list command's `--help` documents the default `--limit` and that results may be capped. - [ ] Wiremock coverage in `src/client/integration_tests.rs` for a multi-page list and the total surfaced in JSON. - [ ] `cargo fmt --check`, `cargo clippy --all-targets --all-features -- -D warnings`, and `cargo test --all` pass. ## Dependencies None. The `get_all` / Link-parsing machinery already exists; this is wiring it into the list handlers and threading existing parsed metadata. ## Size M
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
rasterstate/fj#111
No description provided.