feat(issue): add attachment subcommand for issue attachments #54

Merged
David merged 2 commits from feat/issue-attachment-FJCLI-43 into main 2026-06-19 11:11:00 +02:00
Owner

fj issue could create and comment on issues but had no way to manage their attachments, so an agent or user filing an issue with fj could not attach evidence (a screenshot, a log file): the file had to be added by hand in the web UI. Mirror yt issue attachment with a new fj issue attachment group of add / list / get / remove, backed by Forgejo's Gitea-compatible issue-asset endpoints.

add <index> <file> [--name] uploads a local file via issue_create_issue_attachment (defaulting the asset name to the file name); list <index> lists each attachment's id, name, size, and download URL; get <index> <name|id> [--out] resolves the asset (name first, then numeric id) and downloads its bytes to a path or directory; remove <index> <asset_id> deletes by id. Every command honors the existing host selection (--host / --remote / remote inference) and the --format text|json / --json conventions; the server enforces the attachment size limit, so an oversized upload surfaces its error like the other subcommands.

forgejo-api exposes issue attachments only as metadata (no byte-download method, and the Forgejo client's inner reqwest client is private), so the byte download lives in fj-client (download_attachment) next to action_run_logs, reusing the host bearer token and following redirects with the Authorization header marked sensitive. The CLI-agnostic operations live in fj-core::issues; rendering, the clap tree, and the new Fluent messages stay in the binary, keeping the fj-client / fj-core MCP-reuse contract (no clap/crossterm/fluent) intact.

#FJCLI-43

Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

`fj issue` could create and comment on issues but had no way to manage their attachments, so an agent or user filing an issue with `fj` could not attach evidence (a screenshot, a log file): the file had to be added by hand in the web UI. Mirror `yt issue attachment` with a new `fj issue attachment` group of `add` / `list` / `get` / `remove`, backed by Forgejo's Gitea-compatible issue-asset endpoints. `add <index> <file> [--name]` uploads a local file via `issue_create_issue_attachment` (defaulting the asset name to the file name); `list <index>` lists each attachment's id, name, size, and download URL; `get <index> <name|id> [--out]` resolves the asset (name first, then numeric id) and downloads its bytes to a path or directory; `remove <index> <asset_id>` deletes by id. Every command honors the existing host selection (`--host` / `--remote` / remote inference) and the `--format text|json` / `--json` conventions; the server enforces the attachment size limit, so an oversized upload surfaces its error like the other subcommands. `forgejo-api` exposes issue attachments only as metadata (no byte-download method, and the `Forgejo` client's inner reqwest client is private), so the byte download lives in `fj-client` (`download_attachment`) next to `action_run_logs`, reusing the host bearer token and following redirects with the `Authorization` header marked sensitive. The CLI-agnostic operations live in `fj-core::issues`; rendering, the clap tree, and the new Fluent messages stay in the binary, keeping the `fj-client` / `fj-core` MCP-reuse contract (no clap/crossterm/fluent) intact. #FJCLI-43 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat(issue): add attachment subcommand for issue attachments
All checks were successful
Check / fmt + clippy + build + tests (pull_request) Successful in 37s
262b6be5a1
`fj issue` could create and comment on issues but had no way to manage their attachments, so an agent or user filing an issue with `fj` could not attach evidence (a screenshot, a log file): the file had to be added by hand in the web UI. Mirror `yt issue attachment` with a new `fj issue attachment` group of `add` / `list` / `get` / `remove`, backed by Forgejo's Gitea-compatible issue-asset endpoints.

`add <index> <file> [--name]` uploads a local file via `issue_create_issue_attachment` (defaulting the asset name to the file name); `list <index>` lists each attachment's id, name, size, and download URL; `get <index> <name|id> [--out]` resolves the asset (name first, then numeric id) and downloads its bytes to a path or directory; `remove <index> <asset_id>` deletes by id. Every command honors the existing host selection (`--host` / `--remote` / remote inference) and the `--format text|json` / `--json` conventions; the server enforces the attachment size limit, so an oversized upload surfaces its error like the other subcommands.

`forgejo-api` exposes issue attachments only as metadata (no byte-download method, and the `Forgejo` client's inner reqwest client is private), so the byte download lives in `fj-client` (`download_attachment`) next to `action_run_logs`, reusing the host bearer token and following redirects with the `Authorization` header marked sensitive. The CLI-agnostic operations live in `fj-core::issues`; rendering, the clap tree, and the new Fluent messages stay in the binary, keeping the `fj-client` / `fj-core` MCP-reuse contract (no clap/crossterm/fluent) intact.

#FJCLI-43

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Merge branch 'main' into feat/issue-attachment-FJCLI-43
All checks were successful
Create release / Create release from merged PR (pull_request) Has been skipped
Check / fmt + clippy + build + tests (pull_request) Successful in 55s
66930e2093
David merged commit 8f27115dbb into main 2026-06-19 11:11:00 +02:00
David deleted branch feat/issue-attachment-FJCLI-43 2026-06-19 11:11:00 +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!54
No description provided.