A command line tool to connect forgejo instance.
- Rust 100%
| .agents/skills | ||
| skills/fj-cli-guide | ||
| src | ||
| tests | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| README.md | ||
| README_CN.md | ||
fj — Forgejo CLI
fj is a command-line tool for Forgejo instances, analogous to gh for GitHub. Connect to any Forgejo instance (Codeberg, self-hosted) to manage repos, issues, PRs, branches, releases, and more.
Install
Prebuilt binaries
All static, drop into any Linux / Termux:
| Platform | Download |
|---|---|
| x86_64 (Linux) | curl -L -o fj http://git.apas.com/attachments/57e3f6a1-6f16-4dc4-b925-e09616daf25f |
| aarch64 (Termux/RPi) | curl -L -o fj http://git.apas.com/attachments/c8b7a584-f74e-44aa-800e-7dbad658c9e2 |
| armv7 (RPi 32-bit) | curl -L -o fj http://git.apas.com/attachments/d8e01084-05a1-4a49-88bd-7210b282766c |
| i686 (32-bit Linux) | curl -L -o fj http://git.apas.com/attachments/119eda30-3de4-40e1-a182-45657bc583e8 |
chmod +x fj && mv fj $PREFIX/bin/ # Termux
# or
chmod +x fj && sudo mv fj /usr/local/bin/ # Linux
From crates.io
cargo install fj
Build from source
git clone https://github.com/your/fj.git
cd fj
cargo build --release
Configuration
fj connects to Forgejo via environment variables:
export FORGEJO_URL=https://codeberg.org
export FORGEJO_ACCESS_TOKEN=your_token_here
CLI flags also work (not recommended — exposed in shell history):
fj --forgejo-url https://codeberg.org --access-token your_token repo list
Create a token at Settings → Applications → Generate New Token in the Forgejo web UI.
Commands
| Command | Description |
|---|---|
repo |
Repositories (list, commits, create, fork, search) |
issue |
Issues (list, view, create, update, close, open, add-labels, remove-labels) |
pr |
Pull Requests (list, view, create, update, merge, diff) |
branch |
Branches (list, create, delete) |
branch-protection |
Branch protection rules (list, view, create, edit, delete) |
file |
Files (view, create, update, delete) |
comment |
Comments (list, view, create, edit, delete) |
review |
PR Reviews (list, view, create, list-comments) |
release |
Releases (list, view, create, edit, delete) |
workflow |
CI workflows (list, view, dispatch) |
notification |
Notifications (list, view, mark-read, mark-all-read) |
user |
Users (view, search) |
milestone |
Milestones (list) |
label |
Labels (list) |
org |
Organizations (search-teams, list-labels) |
time |
Time tracking (list, add, reset, delete, stopwatch) |
issue-attach |
Issue attachments (list, view, download, create, edit, delete) |
comment-attach |
Comment attachments (list, view, download, create, edit, delete) |
Global Options
| Option | Description |
|---|---|
--json |
JSON output (for scripting) |
--help / -h |
Show help |
Running fj without arguments prints the full help.
Detailed Usage
repo
# List your repos
fj repo list
# Search repos
fj repo search --query "rust" --language rust --limit 10
# Create a repo
fj repo create --name my-project --description "My new project" --private
# Create an org repo
fj repo create --name my-project --org my-org
# Fork a repo
fj repo fork --owner someone --repo their-project
# Fork into an org
fj repo fork --owner someone --repo their-project --org my-org
# View commit history
fj repo commits --owner someone --repo my-project --sha main --limit 20
issue
# List issues
fj issue list --owner someone --repo my-project --state open
# Filter by labels/milestone
fj issue list --owner someone --repo my-project --labels "bug,enhancement" --milestone "v1.0"
# View an issue
fj issue view --owner someone --repo my-project --index 42
# Create an issue
fj issue create --title "Bug: crash on startup" --body "Steps to reproduce..." --owner someone --repo my-project
# With labels and assignees
fj issue create --title "Feature request" --owner someone --repo my-project --labels "1,2" --assignees "alice,bob" --milestone 3
# Update an issue
fj issue update --owner someone --repo my-project --index 42 --title "Updated title" --state closed
# Close / re-open
fj issue close --owner someone --repo my-project --index 42
fj issue open --owner someone --repo my-project --index 42
# Manage labels
fj issue add-labels --owner someone --repo my-project --index 42 --labels "1,2,3"
fj issue remove-labels --owner someone --repo my-project --index 42 --labels "1"
pr
# List PRs
fj pr list --owner someone --repo my-project --state open
# View a PR
fj pr view --owner someone --repo my-project --index 10
# Create a PR
fj pr create --title "Add new feature" --head feature-branch --base main --owner someone --repo my-project
# With description and labels
fj pr create --title "Fix bug" --body "Fixes #42" --head fix/bug --base main --owner someone --repo my-project --labels "1" --assignees "alice"
# Update a PR
fj pr update --owner someone --repo my-project --index 10 --title "New title" --milestone 3
# Merge a PR
fj pr merge --owner someone --repo my-project --index 10
# Merge with a different strategy
fj pr merge --owner someone --repo my-project --index 10 --style squash --delete-branch
# View PR diff
fj pr diff --owner someone --repo my-project --index 10
# Diff a single file
fj pr diff --owner someone --repo my-project --index 10 --file src/main.rs
branch
# List branches
fj branch list --owner someone --repo my-project
# Create a branch
fj branch create --owner someone --repo my-project --name feature-x --ref main
# Delete a branch
fj branch delete --owner someone --repo my-project --name feature-x
branch-protection
# List protection rules
fj branch-protection list --owner someone --repo my-project
# View a rule
fj branch-protection view --owner someone --repo my-project --name main
# Create a rule
fj branch-protection create --owner someone --repo my-project --branch-name "main" --required-approvals 1 --enable-push
# Edit a rule
fj branch-protection edit --owner someone --repo my-project --name main --required-approvals 2
# Delete a rule
fj branch-protection delete --owner someone --repo my-project --name main
file
# View a file
fj file view --owner someone --repo my-project --path README.md
# From a specific branch
fj file view --owner someone --repo my-project --path src/main.rs --ref develop
# With line range
fj file view --owner someone --repo my-project --path Cargo.toml --start-line 1 --end-line 20
# Create a file
fj file create --owner someone --repo my-project --path docs/notes.md --content "# Notes" --message "Add notes"
# Create on a new branch
fj file create --owner someone --repo my-project --path new-feature.md --content "..." --branch main --new-branch feature/docs
# Update a file (needs current SHA)
fj file update --owner someone --repo my-project --path README.md --content "Updated" --sha abc1234
# Delete a file
fj file delete --owner someone --repo my-project --path old-file.txt --sha abc1234
comment
# List issue comments
fj comment list --owner someone --repo my-project --type issue --index 42
# List PR comments
fj comment list --owner someone --repo my-project --type pr --index 10
# View a comment
fj comment view --owner someone --repo my-project --comment-id 123
# Add a comment
fj comment create --owner someone --repo my-project --type issue --index 42 --body "Looks good!"
# Edit a comment
fj comment edit --owner someone --repo my-project --comment-id 123 --body "Updated comment"
# Delete a comment
fj comment delete --owner someone --repo my-project --comment-id 123
review
# List PR reviews
fj review list --owner someone --repo my-project --pr-index 10
# View a review
fj review view --owner someone --repo my-project --pr-index 10 --review-id 5
# Approve
fj review create --owner someone --repo my-project --pr-index 10 --state APPROVED --body "LGTM!"
# Request changes
fj review create --owner someone --repo my-project --pr-index 10 --state REQUEST_CHANGES --body "Please fix the null check"
# List inline review comments across all reviews on a PR
fj review list-comments --owner someone --repo my-project --pr-index 10
# List inline review comments for one review
fj review list-comments --owner someone --repo my-project --pr-index 10 --review-id 5
release
# List releases
fj release list --owner someone --repo my-project
# Filter by type
fj release list --owner someone --repo my-project --filter draft
fj release list --owner someone --repo my-project --filter prerelease
# View latest release
fj release view --owner someone --repo my-project --latest
# View by tag
fj release view --owner someone --repo my-project --tag v1.0.0
# Create a release
fj release create --owner someone --repo my-project --tag-name v1.0.0 --name "First Release"
# Create draft / pre-release
fj release create --owner someone --repo my-project --tag-name v2.0.0-beta --name "Beta" --prerelease --draft
# Edit a release
fj release edit --owner someone --repo my-project --id 1 --name "Updated Name" --draft false
# Delete a release
fj release delete --owner someone --repo my-project --id 1
fj release delete --owner someone --repo my-project --tag v1.0.0
# Release attachments
fj release attachment list --owner someone --repo my-project --release-id 1
fj release attachment download --owner someone --repo my-project --release-id 1 --attachment-id 5
fj release attachment create --owner someone --repo my-project --release-id 1 --file ./build/output.tar.gz
workflow
# List workflow runs
fj workflow list --owner someone --repo my-project
# View a run
fj workflow view --owner someone --repo my-project --run-id 123
# Dispatch a workflow
fj workflow dispatch --owner someone --repo my-project --workflow ci.yml --ref main
# Dispatch with inputs
fj workflow dispatch --owner someone --repo my-project --workflow release.yml --ref main --inputs "version=1.0.0,dry_run=false"
notification
# List unread notifications
fj notification list
# Include read
fj notification list --all
# Filter by repo
fj notification list --repo someone/my-project
# View a notification
fj notification view --id 123
# Mark read
fj notification mark-read --id 123
fj notification mark-all-read
# Mark all read for a repo
fj notification mark-all-read --repo someone/my-project
user
# View current user
fj user view
# View a specific user
fj user view --username alice
# Search users
fj user search --query "john"
time
# List time records for an issue
fj time list --type issue --owner someone --repo my-project --index 42
# List time for a repo
fj time list --type repo --owner someone --repo my-project
# Add time (seconds)
fj time add --owner someone --repo my-project --index 42 --time 3600
# Reset all time on an issue
fj time reset --owner someone --repo my-project --index 42
# Delete an entry
fj time delete --owner someone --repo my-project --index 42 --id 5
# Stopwatch
fj time stopwatch start --owner someone --repo my-project --index 42
fj time stopwatch stop --owner someone --repo my-project --index 42
fj time stopwatch cancel --owner someone --repo my-project --index 42
fj time stopwatch list
Attachments
# Issue attachments
fj issue-attach list --owner someone --repo my-project --index 42
fj issue-attach download --owner someone --repo my-project --index 42 --attachment-id 5
fj issue-attach create --owner someone --repo my-project --index 42 --file ./screenshot.png
# Comment attachments
fj comment-attach list --owner someone --repo my-project --comment-id 123
fj comment-attach download --owner someone --repo my-project --comment-id 123 --attachment-id 5
JSON Output
All commands support --json for structured output:
fj --json issue list --owner someone --repo my-project | jq '.[] | {number, title}'
License
Apache-2.0 OR MIT