feat(pr): add --json output to pr search (FJ-1) #1

Merged
David merged 1 commit from feat/pr-search-json into main 2026-05-24 23:38:14 +02:00
Owner

What

Adds a --json flag to fj pr search (FJ-1) that emits the matched pull requests as a JSON array, one record per PR, suitable for piping into nu / jq.

Why

fj pr search previously only produced human-readable output, so callers needing machine-readable data had to parse that fragile format or bypass fj entirely and hit the Forgejo REST API directly (re-implementing auth, field selection, and error handling). That is the Tooling Gap Discipline anti-pattern flagged in FJ-1, found while building claude-bot/actions/forgejo-ci-fix.yml.

How

Filters still flow through issue_list_issues, which honors --repo, --state, --labels, --creator, and --assignee. That endpoint only returns Issue records (no head/base/sha), so each matched PR is fetched via repo_get_pull_request to fill in head_sha, head_ref, and base_ref. An empty result prints [] instead of erroring.

Field names mirror the documented schema: number, title, state, head_sha, head_ref, base_ref, author, html_url, created_at, updated_at, draft, labels. Timestamps are normalized to UTC RFC 3339 (trailing Z) so output is deterministic regardless of the server's timezone; state serializes to "open" / "closed".

Acceptance criteria

  • fj pr search --state open --json returns a JSON array.
  • Each record includes number, head_sha, head_ref, base_ref, author, html_url, updated_at at minimum.
  • Empty result returns [], not an error.
  • Works with --repo, --state, --labels, --creator, --assignee filters.

Testing

Verified against longjacksonle/claude-fix-sandbox (the repo referenced in the issue): populated output matches the documented schema, --state open on the empty target repo returns [], and each filter (--state, --creator, --assignee, --labels, --repo) runs without error. cargo build, cargo clippy (no new warnings), and cargo test all pass.

Upstream

fj lives at https://codeberg.org/forgejo-contrib/forgejo-cli. This is a fork-local change; mirroring upstream is still a follow-up per FJ-1.

Closes FJ-1.

🤖 Generated with Claude Code

## What Adds a `--json` flag to `fj pr search` (FJ-1) that emits the matched pull requests as a JSON array, one record per PR, suitable for piping into nu / jq. ## Why `fj pr search` previously only produced human-readable output, so callers needing machine-readable data had to parse that fragile format or bypass `fj` entirely and hit the Forgejo REST API directly (re-implementing auth, field selection, and error handling). That is the Tooling Gap Discipline anti-pattern flagged in FJ-1, found while building `claude-bot/actions/forgejo-ci-fix.yml`. ## How Filters still flow through `issue_list_issues`, which honors `--repo`, `--state`, `--labels`, `--creator`, and `--assignee`. That endpoint only returns `Issue` records (no head/base/sha), so each matched PR is fetched via `repo_get_pull_request` to fill in `head_sha`, `head_ref`, and `base_ref`. An empty result prints `[]` instead of erroring. Field names mirror the documented schema: `number`, `title`, `state`, `head_sha`, `head_ref`, `base_ref`, `author`, `html_url`, `created_at`, `updated_at`, `draft`, `labels`. Timestamps are normalized to UTC RFC 3339 (trailing `Z`) so output is deterministic regardless of the server's timezone; `state` serializes to `"open"` / `"closed"`. ## Acceptance criteria - [x] `fj pr search --state open --json` returns a JSON array. - [x] Each record includes `number`, `head_sha`, `head_ref`, `base_ref`, `author`, `html_url`, `updated_at` at minimum. - [x] Empty result returns `[]`, not an error. - [x] Works with `--repo`, `--state`, `--labels`, `--creator`, `--assignee` filters. ## Testing Verified against `longjacksonle/claude-fix-sandbox` (the repo referenced in the issue): populated output matches the documented schema, `--state open` on the empty target repo returns `[]`, and each filter (`--state`, `--creator`, `--assignee`, `--labels`, `--repo`) runs without error. `cargo build`, `cargo clippy` (no new warnings), and `cargo test` all pass. ## Upstream `fj` lives at https://codeberg.org/forgejo-contrib/forgejo-cli. This is a fork-local change; mirroring upstream is still a follow-up per FJ-1. Closes FJ-1. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Add a `--json` flag to `fj pr search` that emits one record per PR as a JSON array, so callers needing machine-readable output no longer have to parse the human format or bypass `fj` and hit the Forgejo REST API directly (the Tooling Gap Discipline anti-pattern called out in the issue).

The filters still flow through `issue_list_issues`, which honors `--repo`, `--state`, `--labels`, `--creator`, and `--assignee`. That endpoint only returns `Issue` records (no head/base/sha), so each matched PR is fetched via `repo_get_pull_request` to fill in `head_sha`, `head_ref`, and `base_ref`. An empty result prints `[]` rather than erroring.

Field names mirror the documented schema (number, title, state, head_sha, head_ref, base_ref, author, html_url, created_at, updated_at, draft, labels). Timestamps are normalized to UTC RFC 3339 so output is deterministic regardless of the server's timezone, and `state` serializes to "open" / "closed".

#FJ-1 State Done

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
David merged commit 7aa32dc988 into main 2026-05-24 23:38:14 +02:00
David deleted branch feat/pr-search-json 2026-05-24 23:38:15 +02:00
Sign in to join this conversation.
No reviewers
No labels
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
pandoras-box/forgejo-cli!1
No description provided.