Forgejo/Gitea CLI tool with agentic dev features
Find a file
sid 424fb63a8b chore: bump Gitea SDK v0.22.1 → v0.23.2
v0.24.0 and v0.24.1 require Go 1.26 (via module go directive), which
forces a toolchain download on any builder running older Go. v0.23.2
is the most recent release that works with our Go 1.24 baseline.

Worth it: v0.23.x brings significant Issue/PR/Action method coverage
beyond v0.22.1. Tests + vet still clean, live smoke against
forgejo.zerova.net still passes (whoami, repo list).

ResolvePullReviewComment / UnresolvePullReviewComment are still not
in the SDK at v0.23.2 — they landed in v0.24 — so pr_review_comments.go
continues to call the raw REST endpoints. Swap to native methods once
we move to Go 1.26.
2026-04-19 22:04:32 -06:00
.gitea/workflows feat(release): v0.4.0 foundations — ldflags version + goreleaser + CI Go 1.24 2026-04-19 21:04:57 -06:00
cmd feat: add webhook, repo delete/search, admin, pr clean/resolve/review-comments 2026-04-19 22:01:29 -06:00
internal chore: migrate module path to public org 2026-04-11 10:34:34 -06:00
tests/functional test: rewrite functional tests for full CLI coverage 2026-03-23 12:42:24 -06:00
.editorconfig tools: add a basic .editorconfig 2026-01-05 12:57:57 +01:00
.gitignore feat(release): v0.4.0 foundations — ldflags version + goreleaser + CI Go 1.24 2026-04-19 21:04:57 -06:00
.golangci.yml chore: setup CI 2025-12-08 09:56:54 +01:00
.goreleaser.yaml feat(release): v0.4.0 foundations — ldflags version + goreleaser + CI Go 1.24 2026-04-19 21:04:57 -06:00
CHANGELOG.md feat(release): v0.4.0 foundations — ldflags version + goreleaser + CI Go 1.24 2026-04-19 21:04:57 -06:00
go.mod chore: bump Gitea SDK v0.22.1 → v0.23.2 2026-04-19 22:04:32 -06:00
go.sum chore: bump Gitea SDK v0.22.1 → v0.23.2 2026-04-19 22:04:32 -06:00
LICENSE feat: initial version of the project 2025-12-08 09:49:07 +01:00
main.go chore: migrate module path to public org 2026-04-11 10:34:34 -06:00
Makefile feat(release): v0.4.0 foundations — ldflags version + goreleaser + CI Go 1.24 2026-04-19 21:04:57 -06:00
README.md chore: migrate module path to public org 2026-04-11 10:34:34 -06:00

fgj - Forgejo/Gitea CLI Tool

Go Version License: MIT

fgj is a command-line tool for working with Forgejo and Gitea instances. It brings pull requests, issues, and other forge concepts to the terminal, similar to what gh does for GitHub. This fork adds agentic dev features — raw API access, PR review workflows, structured error output, and machine-readable I/O for AI coding agents.

Forked from codeberg.org/romaintb/fgj and hosted at forgejo.zerova.net/public/fgj-sid.

Features

  • Multi-instance support (works with any Forgejo or Gitea instance)
  • Pull request management (create, list, view, merge, diff, comment, review)
  • Issue tracking (create, list, view, comment, close, labels)
  • Repository operations (view, list, create, edit, clone, fork)
  • Label management (list, create, edit, delete)
  • Milestone management (list, view, create, edit, delete)
  • Wiki page management (list, view, create, edit, delete)
  • Issue dependencies (--add-dependency, --remove-dependency)
  • Forgejo Actions (workflow runs, watch/rerun/cancel, enable/disable, secrets, variables)
  • Releases (create, upload, delete)
  • Raw API access (fgj api) for arbitrary REST calls
  • Shell completions (bash, zsh, fish, PowerShell) and man pages
  • JSON output (--json) for all list/view commands
  • Structured JSON error output (--json-errors) for machine consumption
  • Automatic repository and hostname detection from git context
  • Secure authentication with personal access tokens
  • XDG Base Directory compliant config location
  • AI coding agent friendly

Installation

macOS (Homebrew)

brew tap sid/fgj-sid https://forgejo.zerova.net/sid/homebrew-fgj-sid.git
brew install fgj

Using Go Install

go install forgejo.zerova.net/public/fgj-sid@latest

From Source

git clone https://forgejo.zerova.net/public/fgj-sid.git
cd fgj-sid
go build -o fgj .

Quick Start

1. Authenticate

First, authenticate with your Forgejo or Gitea instance:

fgj auth login

You'll be prompted for:

  • Instance hostname (default: codeberg.org)
  • Personal access token

To create a personal access token:

  1. Go to your instance (e.g., https://forgejo.zerova.net)
  2. Navigate to Settings > Applications > Generate New Token
  3. Give it appropriate permissions (repo, issue, etc.)
  4. Copy the token and paste it when prompted

2. Check Authentication Status

fgj auth status

Auth Helpers

# Print the stored token for the current host
fgj auth token

# Remove authentication for a host
fgj auth logout

Usage

Repository Detection

fgj automatically detects the repository from your git context, similar to gh:

# When inside a git repository, no -R flag needed!
cd /path/to/your/repo
fgj pr list              # Automatically uses current repo
fgj issue list           # Automatically uses current repo
fgj pr view 123          # Automatically uses current repo

# Or explicitly specify a repository with -R
fgj pr list -R owner/repo

The tool reads .git/config to find the origin remote and extract both the owner/repo information and the instance hostname. If you're not in a git repository, you'll need to use the -R flag.

Pull Requests

# List pull requests (auto-detects repo and hostname from git)
fgj pr list

# Or specify explicitly
fgj pr list -R owner/repo

# Filter by state
fgj pr list --state closed

# View a specific pull request
fgj pr view 123

# Create a pull request
fgj pr create -t "PR Title" -b "PR Description" -H feature-branch -B main

# Merge a pull request
fgj pr merge 123 --merge-method squash

# View PR diff
fgj pr diff 123

# View diff with color
fgj pr diff 123 --color always

# Show only changed file names
fgj pr diff 123 --name-only

# Show diffstat summary
fgj pr diff 123 --stat

# Comment on a pull request
fgj pr comment 123 -b "Looks good, minor nit on line 42"

# Comment from a file
fgj pr comment 123 --body-file review-notes.md

# Approve a pull request
fgj pr review 123 --approve -b "LGTM"

# Request changes
fgj pr review 123 --request-changes -b "Please fix the error handling"

# Submit a review comment (neither approve nor request changes)
fgj pr review 123 --comment -b "Some observations"

Issues

# List issues (auto-detects repo and hostname from git)
fgj issue list

# Or specify explicitly
fgj issue list -R owner/repo

# Filter by state
fgj issue list --state all

# View an issue
fgj issue view 456

# Create an issue
fgj issue create -t "Issue Title" -b "Issue Description"

# Create an issue with labels
fgj issue create -t "Issue Title" -b "Issue Description" -l bug -l enhancement

# Comment on an issue
fgj issue comment 456 -b "My comment"

# Close an issue
fgj issue close 456

# Close an issue with a comment
fgj issue close 456 -c "Fixed in v2.0"

# Edit an issue (title, body, state, labels)
fgj issue edit 456 -t "New Title"
fgj issue edit 456 --add-label priority --remove-label bug

# Manage issue dependencies
fgj issue edit 456 --add-dependency 123
fgj issue edit 456 --remove-dependency 123

Labels

# List labels
fgj label list

# Create a label
fgj label create bug --color ff0000 -d "Something isn't working"

# Edit a label
fgj label edit bug --name bugfix --color ee0000

# Delete a label
fgj label delete bug

Milestones

# List milestones
fgj milestone list
fgj milestone list --state all

# View a milestone
fgj milestone view "v1.0"

# Create a milestone with due date
fgj milestone create "v2.0" -d "Next major release" --due 2026-06-01

# Edit a milestone
fgj milestone edit "v2.0" --title "v2.0-rc1" --state closed

# Delete a milestone
fgj milestone delete "v2.0"

Wiki

# List wiki pages
fgj wiki list

# View a wiki page
fgj wiki view "Home"

# Create a wiki page
fgj wiki create "Setup Guide" -b "# Setup\n\nFollow these steps..."

# Create from file
fgj wiki create "API Docs" --body-file docs/api.md

# Edit a wiki page
fgj wiki edit "Home" -b "Updated content"

# Delete a wiki page
fgj wiki delete "Old Page"

Repositories

# View repository details
fgj repo view owner/repo

# List your repositories
fgj repo list

# Create a repository
fgj repo create my-repo
fgj repo create my-repo -d "My project" --private --add-readme -g Go -l MIT

# Clone a repository
fgj repo clone owner/repo

# Clone via SSH
fgj repo clone owner/repo -p ssh

# Fork a repository
fgj repo fork owner/repo

# Edit repository settings
fgj repo edit owner/repo --public
fgj repo edit owner/repo --private
fgj repo edit owner/repo -d "New description" --homepage https://example.com
fgj repo edit --default-branch develop
fgj repo edit owner/repo --name new-name

# Rename a repository (shorthand)
fgj repo rename new-name
fgj repo rename new-name -R owner/old-name

Releases

# List releases
fgj release list

# View a release (or use "latest")
fgj release view v1.2.3

# Create a release with notes and optional assets
fgj release create v1.2.3 -t "v1.2.3" -n "Release notes" ./dist/app.tar.gz

# Upload assets to an existing release
fgj release upload v1.2.3 ./dist/app.tar.gz --clobber

# Delete a release (keeps the Git tag)
fgj release delete v1.2.3

Forgejo Actions

# List workflows
fgj actions workflow list

# View a workflow
fgj actions workflow view ci.yml

# Run a workflow (trigger workflow_dispatch)
fgj actions workflow run deploy.yml

# Run a workflow with inputs
fgj actions workflow run deploy.yml -f environment=production -f version=1.2.3

# Run a workflow on a specific branch
fgj actions workflow run deploy.yml -r feature-branch

# Enable or disable a workflow
fgj actions workflow enable ci.yml
fgj actions workflow disable ci.yml

# List workflow runs
fgj actions run list

# View a specific run
fgj actions run view 123

# View run with job details
fgj actions run view 123 --verbose

# View run logs
fgj actions run view 123 --log

# View specific job logs
fgj actions run view 123 --job 456 --log

# Watch a run until completion
fgj actions run watch 123

# Rerun a workflow run
fgj actions run rerun 123

# Cancel a running workflow
fgj actions run cancel 123

# List secrets
fgj actions secret list

# Create a secret
fgj actions secret create MY_SECRET

# Delete a secret
fgj actions secret delete MY_SECRET

# List variables
fgj actions variable list

# Get a variable
fgj actions variable get MY_VAR

# Create a variable
fgj actions variable create MY_VAR "value"

# Update a variable
fgj actions variable update MY_VAR "new value"

# Delete a variable
fgj actions variable delete MY_VAR

Raw API Access

# GET request (auto-detects owner/repo from git context)
fgj api /repos/{owner}/{repo}/pulls

# POST with fields
fgj api /repos/{owner}/{repo}/issues -X POST -f title="Bug report" -f body="Description"

# Explicit method and hostname
fgj api /repos/myorg/myrepo/labels --hostname my-forgejo.example.com

# Read request body from file
fgj api /repos/{owner}/{repo}/issues -X POST --input issue.json

# Read from stdin
echo '{"title":"test"}' | fgj api /repos/{owner}/{repo}/issues -X POST --input -

# Include response headers
fgj api /repos/{owner}/{repo} -i

# Suppress output (useful for DELETE)
fgj api /repos/{owner}/{repo}/issues/123 -X DELETE --silent

Shell Completions and Man Pages

# Generate shell completion scripts
fgj completion bash > /etc/bash_completion.d/fgj
fgj completion zsh > "${fpath[1]}/_fgj"
fgj completion fish > ~/.config/fish/completions/fgj.fish

# Generate man pages to a directory
fgj manpages --dir ~/.local/share/man/man1

JSON Output

Most list and view commands support --json for machine-readable output:

fgj pr list --json
fgj issue view 456 --json
fgj release list --json
fgj actions run list --json
fgj actions workflow view ci.yml --json

# Get JSON output from PR comment/review
fgj pr comment 123 -b "LGTM" --json
fgj pr review 123 --approve -b "Ship it" --json

Structured Error Output

For machine consumption (ideal for AI agents and scripts), use --json-errors to get structured JSON errors on stderr:

# Errors are written to stderr as JSON
fgj pr view 9999 --json-errors
# stderr: {"error":{"code":"not_found","message":"...","status":404}}

# Combine with --json for fully machine-readable I/O
fgj pr list --json --json-errors

Configuration

Configuration is stored in ~/.config/fgj/config.yaml:

hosts:
  forgejo.zerova.net:
    hostname: forgejo.zerova.net
    token: your_token_here
    user: your_username
    git_protocol: ssh
    match_dirs:
      - /              # catch-all: use this host when no git remote is detected
  codeberg.org:
    hostname: codeberg.org
    token: another_token
    user: another_username
    git_protocol: https
    match_dirs:
      - ~/repos/codeberg   # use this host for repos under this directory

Directory-Based Host Selection (match_dirs)

When you work with multiple Forgejo/Gitea instances, fgj can automatically select the right host based on your current working directory — no --hostname flag needed.

Each host entry supports a match_dirs list of directory paths. When fgj can't determine the host from a git remote, it finds the host whose match_dirs entry is the longest prefix match for your current directory.

hosts:
  work.example.com:
    # ...
    match_dirs:
      - ~/work          # any repo under ~/work uses this host
  personal.example.com:
    # ...
    match_dirs:
      - ~/personal
      - ~/side-projects  # multiple directories can map to the same host
  codeberg.org:
    # ...
    match_dirs:
      - /                # catch-all fallback (shortest prefix, lowest priority)
  • Paths support ~ expansion and symlink resolution
  • More specific (longer) paths always win over shorter ones
  • Use / as a catch-all to override the default codeberg.org fallback
  • On ties (same prefix length), the host appearing first in the config file wins

Environment Variables

  • FGJ_HOST: Override the default instance (auto-detected from git remote if not set)
  • FGJ_TOKEN: Provide authentication token

Hostname is resolved in this priority order:

  1. Command-specific flags (e.g., --hostname)
  2. FGJ_HOST environment variable
  3. Auto-detected from git remote URL
  4. match_dirs lookup (longest prefix match against current directory)
  5. Default to codeberg.org

Command-line Flags

  • --hostname: Specify instance for a command (overrides auto-detection and environment variables)
  • --config: Use a custom config file

When working in a git repository, fgj automatically detects the instance from your origin remote URL, so you typically don't need to specify --hostname unless working with multiple instances.

Use with AI Coding Agents

fgj is designed to work seamlessly with AI coding agents like Claude Code. Use --json and --json-errors for fully machine-readable I/O:

# Create PR from agent's changes
fgj pr create -R owner/repo -t "feat: add new feature" -b "$(cat <<EOF
## Summary
- Added new feature X
- Fixed bug Y

Generated with AI assistance
EOF
)" --json

# Check PR status during development
fgj pr list -R owner/repo --state open --json

# Review a PR diff, then approve
fgj pr diff 123
fgj pr review 123 --approve -b "LGTM" --json

# Post review feedback
fgj pr comment 123 -b "Consider using a map here for O(1) lookup" --json

# Request changes with detailed feedback
fgj pr review 123 --request-changes --body-file feedback.md --json

# Use raw API for anything not covered by commands
fgj api /repos/{owner}/{repo}/topics --json-errors
fgj api /repos/{owner}/{repo}/labels -X POST -f name=agent-reviewed -f color="#00ff00"

# Fully machine-readable error handling
fgj pr view 9999 --json --json-errors 2>errors.json

Supported Instances

fgj works with any Forgejo or Gitea instance, including:

  • Self-hosted Forgejo instances
  • Self-hosted Gitea instances
  • Codeberg.org

Contributing

Contributions are welcome! Please feel free to submit a Pull Request at forgejo.zerova.net/public/fgj-sid.

Missing Features / Roadmap

fgj aims to be a drop-in replacement for gh when working with Forgejo and Gitea instances. While we've implemented the core features, some gh commands are not yet available:

Not Yet Implemented:

  • run delete - Delete a workflow run
  • run download - Download workflow run artifacts
  • pr checkout, pr close/reopen
  • pr checks, pr ready/draft
  • issue reopen, issue assign
  • release edit, release download, release generate-notes
  • repo delete

We welcome contributions to implement any of these features!

Acknowledgments

Based on fgj by romaintb. Enhanced with agentic dev features for AI-assisted workflows.

License

MIT License