feat(repo): read a raw file at a ref #86

Merged
Claude-Run merged 1 commit from feat/repo-file-command into main 2026-08-01 03:42:36 +02:00
Member

fj could fetch a repository file's raw bytes only for two hardcoded paths (fj repo readme and the issue-template parser), so a consumer that needs an arbitrary path at an exact commit, such as claude-run's fetch_workflow_yaml, hand-rolled GET /api/v1/repos/{owner}/{repo}/raw/{path}?ref={commit} instead. The MCP server already exposed the general capability as its get_raw_file tool; the CLI was the only surface missing it.

Add fj repo file <PATH>, which writes the file's bytes to stdout unchanged (no trailing newline added, so binary files and exact-byte comparisons survive a pipe) and takes --ref <commit|branch|tag> plus the standard --repo / --remote / --host selectors. Omitting --ref resolves the repository's default branch first, so both the JSON output and any error name a concrete ref rather than whatever the API happened to pick. Under --json the command emits path, ref, and content, and fails naming the file when the bytes are not UTF-8 rather than emitting lossy text; raw stdout stays the way to get non-UTF-8 bytes.

fj_core::repo::get_raw_file now maps the raw endpoint's 404 to an error naming the path, the ref, and the repo, keeping Forgejo's own text as context, because the server answers a missing file, an unresolvable ref, and an out-of-reach repository alike with a bare "not found". Any other error passes through unchanged, and every caller (the new command, repo readme, and the MCP tool) gets the mapped message.

Covered by unit tests over the error mapping (missing path with a ref, without a ref, and a non-404 that must pass through), over the clap surface, and over the non-UTF-8 JSON rejection. Verified live against dev.a8n.run reading .forgejo/workflows/check.yml from the public pandoras-box/forgejo-cli at a commit sha, a branch, a tag, and the default branch (bytes identical to git show), and from the private niceguyit/claude-run at an explicit commit sha.

#FJ-67

`fj` could fetch a repository file's raw bytes only for two hardcoded paths (`fj repo readme` and the issue-template parser), so a consumer that needs an arbitrary path at an exact commit, such as claude-run's `fetch_workflow_yaml`, hand-rolled `GET /api/v1/repos/{owner}/{repo}/raw/{path}?ref={commit}` instead. The MCP server already exposed the general capability as its `get_raw_file` tool; the CLI was the only surface missing it. Add `fj repo file <PATH>`, which writes the file's bytes to stdout unchanged (no trailing newline added, so binary files and exact-byte comparisons survive a pipe) and takes `--ref <commit|branch|tag>` plus the standard `--repo` / `--remote` / `--host` selectors. Omitting `--ref` resolves the repository's default branch first, so both the JSON output and any error name a concrete ref rather than whatever the API happened to pick. Under `--json` the command emits `path`, `ref`, and `content`, and fails naming the file when the bytes are not UTF-8 rather than emitting lossy text; raw stdout stays the way to get non-UTF-8 bytes. `fj_core::repo::get_raw_file` now maps the raw endpoint's `404` to an error naming the path, the ref, and the repo, keeping Forgejo's own text as context, because the server answers a missing file, an unresolvable ref, and an out-of-reach repository alike with a bare "not found". Any other error passes through unchanged, and every caller (the new command, `repo readme`, and the MCP tool) gets the mapped message. Covered by unit tests over the error mapping (missing path with a ref, without a ref, and a non-404 that must pass through), over the clap surface, and over the non-UTF-8 JSON rejection. Verified live against dev.a8n.run reading `.forgejo/workflows/check.yml` from the public `pandoras-box/forgejo-cli` at a commit sha, a branch, a tag, and the default branch (bytes identical to `git show`), and from the private `niceguyit/claude-run` at an explicit commit sha. #FJ-67
feat(repo): read a raw file at a ref
All checks were successful
Check / fmt + clippy + build + tests (pull_request) Successful in 31s
Create release / Create release from merged PR (pull_request) Has been skipped
870ceed032
`fj` could fetch a repository file's raw bytes only for two hardcoded paths (`fj repo readme` and the issue-template parser), so a consumer that needs an arbitrary path at an exact commit, such as claude-run's `fetch_workflow_yaml`, hand-rolled `GET /api/v1/repos/{owner}/{repo}/raw/{path}?ref={commit}` instead. The MCP server already exposed the general capability as its `get_raw_file` tool; the CLI was the only surface missing it.

Add `fj repo file <PATH>`, which writes the file's bytes to stdout unchanged (no trailing newline added, so binary files and exact-byte comparisons survive a pipe) and takes `--ref <commit|branch|tag>` plus the standard `--repo` / `--remote` / `--host` selectors. Omitting `--ref` resolves the repository's default branch first, so both the JSON output and any error name a concrete ref rather than whatever the API happened to pick. Under `--json` the command emits `path`, `ref`, and `content`, and fails naming the file when the bytes are not UTF-8 rather than emitting lossy text; raw stdout stays the way to get non-UTF-8 bytes.

`fj_core::repo::get_raw_file` now maps the raw endpoint's `404` to an error naming the path, the ref, and the repo, keeping Forgejo's own text as context, because the server answers a missing file, an unresolvable ref, and an out-of-reach repository alike with a bare "not found". Any other error passes through unchanged, and every caller (the new command, `repo readme`, and the MCP tool) gets the mapped message.

Covered by unit tests over the error mapping (missing path with a ref, without a ref, and a non-404 that must pass through), over the clap surface, and over the non-UTF-8 JSON rejection. Verified live against dev.a8n.run reading `.forgejo/workflows/check.yml` from the public `pandoras-box/forgejo-cli` at a commit sha, a branch, a tag, and the default branch (bytes identical to `git show`), and from the private `niceguyit/claude-run` at an explicit commit sha.

#FJ-67
Claude-Run deleted branch feat/repo-file-command 2026-08-01 03:42:36 +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!86
No description provided.