A command-line tool for Forgejo instances.
Find a file
Stephen Way 08bc6d611d
Some checks are pending
ci / check (push) Waiting to run
plugin: drop strict:false from marketplace entry
Default (strict:true) merges plugin.json with marketplace overrides;
this is what's needed to auto-discover skills/<name>/SKILL.md inside
the plugin directory. strict:false says "marketplace entry IS the
entire definition" which conflicts with the plugin.json we ship.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 16:38:56 -07:00
.forgejo open-source readiness: release workflow, homebrew template, templates, compat doc 2026-05-13 15:09:18 -07:00
assets docs: record initial v0.1.0 demo GIF + fix record-demo.sh argument parsing 2026-05-13 16:00:02 -07:00
claude plugin: drop strict:false from marketplace entry 2026-05-13 16:38:56 -07:00
dist/homebrew chore: gitignore release build artifacts and local Claude state 2026-05-13 15:47:55 -07:00
docs open-source readiness: release workflow, homebrew template, templates, compat doc 2026-05-13 15:09:18 -07:00
hooks fix: pager via libc::dup2, harden pre-push hook stdin handling 2026-05-13 08:53:13 -07:00
scripts docs: record initial v0.1.0 demo GIF + fix record-demo.sh argument parsing 2026-05-13 16:00:02 -07:00
src open-source readiness: release workflow, homebrew template, templates, compat doc 2026-05-13 15:09:18 -07:00
.gitignore chore: gitignore release build artifacts and local Claude state 2026-05-13 15:47:55 -07:00
Cargo.lock bugs + agent-focused Forgejo gaps + CI + docs 2026-05-13 14:52:28 -07:00
Cargo.toml bugs + agent-focused Forgejo gaps + CI + docs 2026-05-13 14:52:28 -07:00
CHANGELOG.md open-source readiness: release workflow, homebrew template, templates, compat doc 2026-05-13 15:09:18 -07:00
CLAUDE.md docs: sync README + CLAUDE.md + architecture.md with recent additions 2026-05-13 14:57:07 -07:00
CONTRIBUTING.md docs: CLAUDE.md, CONTRIBUTING.md, CHANGELOG.md, docs/ 2026-05-13 12:48:46 -07:00
LICENSE docs: add LICENSE file (MIT, matches Cargo.toml) 2026-05-13 14:58:03 -07:00
README.md plugin: add marketplace.json + correct install instructions 2026-05-13 16:15:24 -07:00
SECURITY.md docs: SECURITY.md address → security@rasterstate.com 2026-05-13 15:19:48 -07:00

fj logo

fj

A command-line tool for Forgejo, in the spirit of GitHub's gh.
Multi-host from day one. Tokens are stored in your OS keychain.

fj demo

Install

# Homebrew (macOS + Linux):
brew tap rasterandstate/tap
brew install fj

# From source:
cargo install --path .
# or
cargo build --release && cp target/release/fj ~/.local/bin/fj

Quick start

fj auth login                          # add a host and token
fj auth status                         # show signed-in hosts
fj repo list                           # repos you own
fj repo view owner/name                # repo overview
fj issue list -R owner/name            # issues
fj pr list -R owner/name --state open  # pull requests
fj api /repos/search -X GET -f q=foo   # raw API escape hatch

-R/--repo is optional inside a git clone. fj detects the upstream from upstream, then origin, then any other remote.

Commands

Group Common operations
auth login, status, logout, list, switch, token, refresh, setup-git
repo list, view, clone, create, fork, sync, edit, rename, archive, unarchive, delete, branches, topics, mirror, mirror-sync, watch, unwatch, star, unstar, starred
issue list, view, create, edit, close, reopen, comment, edit-comment, delete-comment, develop
pr list, view, create, edit, diff, commits, files, checks, ready, review, request-review, unrequest-review, status, checkout, merge, close, reopen
release list, view, create, edit, delete, upload, download
label list, create, edit, delete
milestone list, view, create, edit, close, reopen, delete, assign
run list, view, rerun, cancel (Forgejo Actions workflow runs)
secret list, set, delete (Actions secrets)
variable list, set, delete (Actions variables)
search repos, issues, prs, users, code
browse open the current repo (or a path within it) in your browser
status notifications inbox + --mark-read
org list, view, teams
ssh-key list, add, delete
gpg-key list, add, delete
alias list, set, delete
config get, set, list, path
protect list, view, set, delete branch protection rules
hook list, create, delete, test webhooks
gist list, create (thin wrapper over gist-* repos)
extension list, run discovered fj-<name> plugins on PATH
api raw HTTP with -X, -f, -F, -H, -q (jq-ish), --paginate, --include
completion Print shell completions (bash, zsh, fish, powershell, elvish)
man Generate man pages into a directory

Global flags

  • --host <hostname> (or FJ_HOST): pick the host explicitly.
  • --debug (or FJ_DEBUG=1): log every HTTP request to stderr.
  • --no-pager (or FJ_NO_PAGER=1): skip the pager.
  • --json-fields foo,bar: gh-style projection on top of any --json output. Dotted paths supported (--json-fields owner.login,id).
  • --web on most list/view subcommands: open the relevant page in your default browser.

Config

  • Hosts and the current host live in $XDG_CONFIG_HOME/fj/hosts.toml (~/Library/Application Support/fj/hosts.toml on macOS).
  • Aliases in aliases.toml. Preferences in config.toml.
  • Tokens live in the OS keychain under service fj, keyed by hostname.

Aliases

fj alias set co "pr checkout"
fj co 42                   # equivalent to: fj pr checkout 42

Extensions

Any executable on $PATH named fj-<name> is invokable as fj <name> [args].

fj extension list          # show discovered plugins
fj my-plugin some-arg      # invokes `fj-my-plugin some-arg`

Plugin-style usage of fj api

# Auto-paginate a list endpoint into a single JSON array:
fj api /repos/search -f q=fj --paginate -q .

# Pass a custom request header:
fj api /user -H "X-Trace-Id: foo"

# Show response headers along with the body:
fj api /version --include

# Send a literal JSON body:
fj api /repos/migrate --input '{"clone_addr":"...","repo_name":"x","repo_owner":"y"}'

Hooks

  • hooks/pre-push runs cargo fmt --check, cargo clippy -D warnings, cargo test, and a release build before any push.
  • With FJ_E2E=1, the hook also runs scripts/e2e-smoke.sh against the configured host.
  • Install via ./scripts/install-hooks.sh.

Building

cargo build --release            # ~4 MB stripped binary at target/release/fj
./target/release/fj completion zsh > ~/.zfunc/_fj
./target/release/fj man -o ~/man/man1

Claude Code plugin

fj ships a Claude Code plugin so AI agents and developers using Claude Code can drive fj directly from natural-language requests.

/plugin marketplace add rasterandstate/fj-claude-plugin
/plugin install fj@rasterandstate

The source of truth for the plugin lives in claude/ inside this repo; the canonical install URL points at the mirror at rasterandstate/fj-claude-plugin.

Documentation

License

MIT