Forgejo CLI tool with web UI scraping for Actions (fork of codeberg.org/romaintb/fgj)
  • Go 99.9%
  • Makefile 0.1%
Find a file
Quik2007 6ef826e879
Some checks failed
CI / build (push) Successful in 1m43s
CI / test (push) Successful in 1m47s
CI / lint (push) Failing after 12m22s
fix(scrape): decode all HTML entities in run-view JSON (was missing +)
Forgejo emits the data-initial-post-response attribute with both named
(", &) and numeric (", +, etc.) HTML entities. The
decoder hand-picked four common entities via ReplaceAll, so any other
entity Forgejo encoded survived into the parsed JSON. The most visible
victim was '+' in job names: "Rust (check + test)" came back as
"Rust (check + test)", which didn't match the API's plain-text task
name. Every `run view --log-failed` and `run logs --job <name>` against
those jobs failed with "could not locate job in web view".

Swap the four ReplaceAll calls for one html.UnescapeString and extract
the parsing into a pure function so the regression can be locked down
with table-driven tests.

Confirmed live on tu-po/auralang run #4094: Rust (check + test) logs
now retrieve (4718 lines), surfacing the actual flaky test
`durable_replay_completeness` in akribes-server.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-30 19:40:30 +02:00
.gitea/workflows Merge upstream codeberg.org/romaintb/fgj@v0.4.0 features 2026-05-13 19:24:54 +02:00
cmd fix(run): list pages newest→oldest (was scanning oldest 500 runs) 2026-05-19 16:40:53 +02:00
docs/superpowers docs: spec + plan for run view + MCP toolset cleanup 2026-04-25 18:19:50 +02:00
internal fix(scrape): decode all HTML entities in run-view JSON (was missing &#43;) 2026-05-30 19:40:30 +02:00
tests/functional fix: add confirmation prompt to release delete 2026-04-14 14:48:40 +02:00
.editorconfig tools: add a basic .editorconfig 2026-01-05 12:57:57 +01:00
.gitignore feat(mcp): hygiene pass — structured errors, run_log_full, pr_refresh, prompts, --method 2026-04-25 12:23:59 +02:00
.golangci.yml chore: setup CI 2025-12-08 09:56:54 +01:00
CHANGELOG.md Merge upstream codeberg.org/romaintb/fgj@v0.4.0 features 2026-05-13 19:24:54 +02:00
CONTRIBUTORS.md docs: add contributors 2026-04-20 10:41:28 +02:00
go.mod feat(mcp): add fgj mcp server with 17 LLM-native tools + 3 prompts 2026-04-24 00:18:39 +02:00
go.sum feat(mcp): add fgj mcp server with 17 LLM-native tools + 3 prompts 2026-04-24 00:18:39 +02:00
LICENSE feat: initial version of the project 2025-12-08 09:49:07 +01:00
main.go feat: add web UI scraping for Actions on older Forgejo versions 2026-04-06 13:36:53 +02:00
Makefile make: add an install target 2026-01-05 12:58:11 +01:00
README.md Merge upstream codeberg.org/romaintb/fgj@v0.4.0 features 2026-05-13 19:24:54 +02:00
renovate.json Add renovate.json 2026-04-07 12:20:12 +00:00

fgj - Forgejo CLI Tool (tu-po fork)

Go Version License: MIT

Fork of codeberg.org/romaintb/fgj with web UI scraping for Forgejo Actions features not yet available via the REST API (logs, rerun, cancel, artifacts) on Forgejo < v16.

fgj is a command-line tool for working with Forgejo instances (including Codeberg.org). It brings pull requests, issues, and other Forgejo concepts to the terminal, similar to what gh does for GitHub.

Features

  • Multi-instance support (works with any Forgejo instance)
  • Pull request management (create, list, view, edit, merge)
  • Issue tracking (create, list, view, comment, close, labels)
  • Repository operations (view, list, create, clone, fork)
  • Forgejo Actions (workflow runs, watch/rerun/cancel, enable/disable, secrets, variables)
  • Web UI scraping fallback for action logs, rerun, cancel, and artifacts on older Forgejo versions
  • Releases (create, upload, delete)
  • Milestones (create, list, edit, delete)
  • Labels (create, list, edit, delete)
  • Shell completions (bash, zsh, fish, PowerShell) and man pages
  • JSON output (--json) for all list/view commands
  • 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

Using Go Install

GOPRIVATE=git.tu-po.com go install git.tu-po.com/tu-po/fgj@latest

Requires git credentials for git.tu-po.com (e.g., via ~/.netrc or git credential helper).

macOS (Homebrew)

brew tap tu-po/fgj https://git.tu-po.com/tu-po/homebrew-fgj.git
brew install fgj

Build from Source

git clone https://git.tu-po.com/tu-po/fgj.git
cd fgj
make build
# Binary is at bin/fgj

Quick Start

1. Authenticate

First, authenticate with your Forgejo instance:

fgj auth login

You'll be prompted for:

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

To create a personal access token:

  1. Go to your Forgejo instance (e.g., https://codeberg.org)
  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

3. (Optional) Set up Web UI Credentials

For Forgejo < v16, some Actions features (logs, rerun, cancel, artifacts) are not available via the REST API. To use these features, configure web UI credentials for a service account:

fgj auth login-ui

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 Forgejo 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

# Edit a pull request's title and body
fgj pr edit 123 -t "New title" -b "New description"

# Edit a pull request's body from a file (or stdin with -)
fgj pr edit 123 -F body.md

# Change the base branch
fgj pr edit 123 -B main

# Manage labels and assignees
fgj pr edit 123 --add-label bug --remove-label wontfix
fgj pr edit 123 --add-assignee @me --remove-assignee someone

# Manage reviewers
fgj pr edit 123 --add-reviewer monalisa --remove-reviewer hubot

# Comment on a pull request
fgj pr comment 123 -b "LGTM"

# Comment with body from a file (or stdin with -)
fgj pr comment 123 -F review.md

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

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

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), prompts for confirmation
fgj release delete v1.2.3

# Skip confirmation
fgj release delete v1.2.3 --yes

Milestones

# List open milestones (auto-detects repo)
fgj milestone list

# Filter by state
fgj milestone list --state closed
fgj milestone list --state all

# Create a milestone
fgj milestone create "v1.0" -d "First stable release" --due 2026-06-30

# Create or update if it already exists
fgj milestone create "v1.0" -d "Updated description" -f

# Edit a milestone (rename, change description, due date, or state)
fgj milestone edit "v1.0" --title "v1.0.0"
fgj milestone edit "v1.0.0" --due 2026-07-15
fgj milestone edit "v1.0.0" --state closed

# Delete a milestone (prompts for confirmation)
fgj milestone delete "v1.0.0"
fgj milestone delete "v1.0.0" --yes

Labels

# List labels (auto-detects repo)
fgj label list

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

# Create an exclusive (scoped) label
fgj label create priority/high -c ff8800 --exclusive

# Create or update if it already exists
fgj label create bug -c ee0701 -f

# Edit a label
fgj label edit bug -n defect -c cc0000

# Delete a label (prompts for confirmation)
fgj label delete wontfix
fgj label delete wontfix -y

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

# View full logs for a run (uses web UI scraping on older Forgejo)
fgj actions run logs 123

# View logs for a specific job
fgj actions run logs 123 --job 0

# List artifacts for a run
fgj actions run artifacts 123

# Download a specific artifact
fgj actions run artifacts 123 --download my-artifact -o output.zip

# Rerun a workflow run (falls back to web UI on older Forgejo)
fgj actions run rerun 123

# Cancel a running workflow (falls back to web UI on older Forgejo)
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

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

Configuration

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

hosts:
  codeberg.org:
    hostname: codeberg.org
    token: your_token_here
    user: your_username
    git_protocol: https
  my-forgejo.com:
    hostname: my-forgejo.com
    token: another_token
    user: another_username
    git_protocol: ssh

Environment Variables

  • FGJ_HOST: Override the default Forgejo 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. Default to codeberg.org

Command-line Flags

  • --hostname: Specify Forgejo 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 Forgejo 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. Common patterns:

# 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
)"

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

# View PR details for review
fgj pr view 123 -R owner/repo

Supported Forgejo Instances

fgj works with any Forgejo instance, including:

  • Codeberg.org (default)
  • Self-hosted Forgejo instances
  • Gitea instances (compatible API)

Contributing

Contributions are welcome! Please feel free to submit a Pull Request. See CONTRIBUTORS.md for a list of people who have contributed to the project.

Missing Features / Roadmap

fgj aims to be a drop-in replacement for gh when working with Forgejo 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 diff
  • pr review, pr checks, pr ready/draft
  • issue reopen, issue assign
  • release edit, release download, release generate-notes
  • repo delete, repo rename, repo visibility

We welcome contributions to implement any of these features! Please check the issues or create a new one to discuss implementation before starting work.

License

MIT License