# fgj - Forgejo/Gitea CLI Tool [![Go Version](https://img.shields.io/badge/Go-1.23+-00ADD8?style=flat-square&logo=go)](https://golang.org) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](LICENSE) `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](https://codeberg.org/romaintb/fgj) and hosted at [forgejo.zerova.net/public/fgj-sid](https://forgejo.zerova.net/public/fgj-sid). ## Features - Multi-instance support (works with any Forgejo or Gitea instance) - Pull requests — list, view, create, merge, close, reopen, edit, checkout, clean, diff, comment, review, approve, reject, checks, review-comments, resolve/unresolve - Issues — create, list, view, comment, close, reopen, edit, labels, dependencies - Repositories — view, list, create, edit, clone, fork, rename, delete, search, migrate, create-from-template - Branches — list, rename, delete - Labels / milestones / wiki — full CRUD - Organizations — list, create, delete - Webhooks — list, create, update, delete - Notifications — list (unread or all), mark read - Forgejo Actions — workflow runs, watch/rerun/cancel, workflows enable/disable, secrets, variables - Releases — create, upload, delete - Admin — `admin user list` (admin-token only) - `fgj open` — launch a repo / issue / PR in the browser - `fgj whoami` — show the authenticated user on the current host - Raw API access (`fgj api`) for arbitrary REST calls - Shell completions (bash, zsh, fish, PowerShell) and man pages - JSON output (`--json`, `--json-fields`, `--jq`) for all list/view commands - Structured JSON error output (`--json-errors`) for machine consumption - Automatic repository and hostname detection from git context - Directory-scoped host defaults (`match_dirs`) - Secure authentication with personal access tokens - XDG Base Directory compliant config location - AI coding agent friendly ## Installation ### macOS (Homebrew) ```bash brew tap sid/fgj-sid https://forgejo.zerova.net/sid/homebrew-fgj-sid.git brew install fgj ``` ### Using Go Install ```bash go install forgejo.zerova.net/public/fgj-sid@latest ``` ### From Source ```bash 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: ```bash 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 ```bash fgj auth status ``` ### Auth Helpers ```bash # 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`: ```bash # 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 ```bash # 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 ```bash # 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 ```bash # 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 ```bash # 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 ```bash # 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 ```bash # 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 ```bash # 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 ```bash # 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 ```bash # 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 ```bash # 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: ```bash 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: ```bash # 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`: ```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. ```yaml 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: ```bash # Create PR from agent's changes fgj pr create -R owner/repo -t "feat: add new feature" -b "$(cat <errors.json ``` ## Supported Instances `fgj` works with any Forgejo or Gitea instance, including: - Self-hosted Forgejo instances - Self-hosted Gitea instances - [Codeberg.org](https://codeberg.org) ## Contributing Contributions are welcome! Please feel free to submit a Pull Request at [forgejo.zerova.net/public/fgj-sid](https://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](https://codeberg.org/romaintb/fgj). Enhanced with agentic dev features for AI-assisted workflows. ## License MIT License