A command-line tool for Forgejo instances.
  • Rust 96.4%
  • Shell 3%
  • Makefile 0.6%
Find a file
Stephen Way 6ce9a1ebd1
Some checks failed
ci / check (push) Successful in 10m8s
ci / live-e2e (push) Successful in 1m53s
ci / coverage (push) Failing after 10m58s
Add issue and PR lock commands (#180)
2026-06-15 17:10:42 +00:00
.forgejo Add live E2E CI gate (#84) 2026-06-06 20:31:33 +00:00
assets Add demo GIFs recorded against a public demo repo (#77) 2026-06-05 17:16:26 +00:00
claude Sync fj release and Claude skill updates (#81) 2026-06-06 16:41:18 +00:00
dist/homebrew chore: gitignore release build artifacts and local Claude state 2026-05-13 15:47:55 -07:00
docs Add issue and PR lock commands (#180) 2026-06-15 17:10:42 +00:00
hooks Tighten local and CI quality gates (#82) 2026-06-06 19:53:56 +00:00
scripts Add live E2E CI gate (#84) 2026-06-06 20:31:33 +00:00
src Add issue and PR lock commands (#180) 2026-06-15 17:10:42 +00:00
tests Fix piped version output (#116) 2026-06-11 00:35:45 +00:00
.env.example chore: switch contact email + add .env defenses 2026-05-14 14:30:54 -07:00
.gitignore Untrack .wrangler cache and gitignore it (#61) 2026-06-02 22:58:04 +00:00
Cargo.lock Add create template support (#181) 2026-06-15 16:46:10 +00:00
Cargo.toml Add create template support (#181) 2026-06-15 16:46:10 +00:00
CHANGELOG.md fj run rerun: --failed and --job to rerun part of a run (#168) (#177) 2026-06-15 16:48:52 +00:00
CLAUDE.md Add live E2E CI gate (#84) 2026-06-06 20:31:33 +00:00
CONTRIBUTING.md Add live E2E CI gate (#84) 2026-06-06 20:31:33 +00:00
LICENSE docs: add LICENSE file (MIT, matches Cargo.toml) 2026-05-13 14:58:03 -07:00
Makefile Add tag and branch ref commands (#144) 2026-06-11 02:10:45 +00:00
README.md Add create template support (#181) 2026-06-15 16:46:10 +00:00
SECURITY.md docs: SECURITY.md address → security@rasterstate.com 2026-05-13 15:19:48 -07:00

fj logo

fj

A native CLI for Forgejo and Gitea-compatible forges.
Open PRs, triage issues, ship releases, and tail Actions logs from the terminal,
all from a single binary. Tokens prefer your OS keychain, with a 0600 file fallback for headless hosts. Multi-host from day one.

ci version license changelog

fj: view a repo, list issues and PRs from the terminal

Why fj

If you self-host Forgejo or Gitea, scripting it has meant pasting curl commands, juggling a ~/.netrc, or wrapping your own scripts around git and the web UI. tea exists but lags Forgejo features and ships no signed release.

fj is the piece in the middle: a single binary that tracks the Forgejo /api/v1 surface, ships signed and notarized macOS builds (no Gatekeeper warnings), a Linux binary, and a Homebrew tap. Tokens prefer the macOS Keychain, the Linux Secret Service, or the Windows Credential Manager. On headless systems without a usable keychain, fj falls back to a 0600 tokens.toml in its XDG config directory. FJ_TOKEN is always checked first and overrides persistent storage for that process.

What you get over hand-rolled scripts:

  • Repo auto-detection. Inside any clone, fj pr list already knows the repo and the host. No -R plumbing.
  • Retry, pagination, and a jq-ish projector built into every call.
  • JSON-native output (--json, --json-fields) so scripts and AI agents can drive it without screen-scraping.

Compatibility: built and tested against Forgejo (7.x and newer); most commands work on Gitea too. See docs/compatibility.md.

Install

Homebrew (macOS and Linux x86_64), signed and notarized:

brew tap rasterandstate/tap
brew install fj

Linux tarball:

curl -fsSL https://rasterhub.com/rasterstate/fj/releases/download/v0.2.0/fj-v0.2.0-linux-x86_64.tar.gz | tar -xz
sudo mv fj-v0.2.0-linux-x86_64/fj /usr/local/bin/fj

From source (any platform with a current Rust toolchain):

cargo install --git https://rasterhub.com/rasterstate/fj --tag v0.2.0

Windows compiles but is untested. File an issue if you try it.

Quickstart

fj auth login                            # pick Fjord Account or a Forgejo token; stored in keychain or 0600 file fallback
fj repo view                             # auto-detects the repo from your git remote
fj pr list --state all -L 10             # latest 10 PRs
fj pr list --base main --no-draft        # branch/draft filters
fj issue list --milestone v1 --mentioned alice
fj issue create --template bug            # seed body from repo templates
fj pr create --template                   # choose a PR template interactively
fj api /version                          # raw API escape hatch

-R/--repo is always optional inside a clone (fj reads origin then upstream to find the slug). Outside a clone, pass it explicitly. create --template uses Forgejo's issue-template API when present and falls back to reading template files from the repository's default branch.

Everyday workflows

Review a PR:

fj pr checkout 42                        # fetch and check out the PR branch
fj pr diff 42 | less                     # or `fj pr files 42` for a file summary
fj pr review 42 --event approve --body "LGTM"
fj pr request-review 42 alice bob        # tag specific reviewers

Triage your inbox:

fj pr status                             # cross-repo dashboard of PRs you care about
fj status                                # notifications inbox
fj status --mark-read                    # clear it

Cut a release:

fj release create v1.2.3 \
  --title "1.2.3" \
  --body "$(cat RELEASE_NOTES.md)" \
  --asset dist/foo-x86_64.tar.gz

Inspect an Actions run:

fj run view 42 --log-failed              # failed steps across every job
fj run view 42 --log --job 1             # one job's full log
fj run download 42 --list --json         # artifacts as JSON

Built for automation and agents

fj is JSON-native, so it scripts cleanly and AI agents can drive it without parsing tables:

fj pr list --json --json-fields number,title,user.login   # selective JSON projection
fj api /repos/foo/bar/pulls --paginate -q '.[].number'    # raw API + jq-ish path

fj: Actions runs, JSON projection, and raw API from the terminal

It also ships a Claude Code plugin so agents (and people) can drive fj from natural language:

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

And fj agent review / fix / explain bring AI code ops to the terminal, with local secret redaction before anything leaves your machine. See docs/agent.md. (preview)

Stacked PRs

fj stack manages a chain of dependent branches and their PRs: each PR targets the one below it, and the chain merges bottom-up. State is local and git-native in .git/fj/stack.json, with no server state.

fj stack new "Login Flow"     # author a stack and its first branch
fj stack review               # PR number, review, CI, and mergeability per item
fj stack sync                 # push branches and create/update the PRs
fj stack ship                 # merge bottom-up behind a green-and-approved gate

fj stack review and sync on a three-PR stack

Full guide, including split and absorb: docs/stacks.md. (preview)

Command reference

Run fj --help for the live list; every group has its own --help.

Area Commands
Repos and code repo, issue, pr, release, search, browse
Actions run, workflow, secret, variable
Account and host auth, instances, org, ssh-key, gpg-key
Power and config api, alias, config, protect, hook, extension, completion, man
Preview work, stack, agent

Global flags (work on every command): --host / FJ_HOST, --debug, --color, --no-pager, and --json-fields.

--color=auto|always|never controls ANSI color output. Precedence is --color, then NO_COLOR / FORCE_COLOR, then fj config set no_color true, then terminal detection.

--json applies to data-returning commands such as list, view, and other commands that document JSON output. --web applies to list/view commands that can open results in the browser.

Configuration

Location What
$XDG_CONFIG_HOME/fj/hosts.toml (~/Library/Application Support/fj/hosts.toml on macOS) host registry + current default
$XDG_CONFIG_HOME/fj/aliases.toml user-defined command shortcuts
$XDG_CONFIG_HOME/fj/config.toml editor / pager / browser / color preferences
OS keychain, service fj, key = hostname Preferred persistent API token store
$XDG_CONFIG_HOME/fj/tokens.toml 0600 fallback token store when the OS keychain is unavailable
FJ_TOKEN Process-scoped token override for headless/CI jobs; checked before persistent stores

Contributing

git clone https://rasterhub.com/rasterstate/fj
cd fj
cargo build --release        # ~4 MB stripped binary at target/release/fj
./scripts/install-hooks.sh   # local gates: fmt, clippy -D warnings, tests, audit, release build

make install puts a signed copy on your PATH and installs the man pages. See CONTRIBUTING.md for the full workflow and docs/architecture.md for the module graph and design.

Documentation

License

MIT.