Kommandozeilen-Client für Forgejo
  • Go 99.8%
  • Makefile 0.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Frank Hildebrandt 0c9bf707b5
All checks were successful
CI / test (push) Successful in 1m26s
CI / race (push) Successful in 1m26s
fix(agent): clip TUI overflow when overview lists grow large
Hard-limit panel and view height so many Done entries no longer break the dashboard layout.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-21 23:04:15 +02:00
.cursor/hooks/state chore: update continual-learning hook state 2026-07-17 14:39:12 +02:00
.forgejo/workflows fix(ci): fetch bare remotes without requiring remote HEAD 2026-07-12 14:23:38 +02:00
.github/workflows ci: use native Forgejo checkout 2026-07-11 22:21:14 +02:00
cmd fix: package releases with Go standard library 2026-07-11 22:04:26 +02:00
docs fix(agent): post commit-mode progress and usage on the issue 2026-07-21 13:22:05 +02:00
internal fix(agent): clip TUI overflow when overview lists grow large 2026-07-21 23:04:15 +02:00
vendor feat(agent): add health loop and SQLite job store 2026-07-15 12:47:30 +02:00
.gitignore feat: add forge agent watch and run for coding-agent dispatch 2026-07-12 08:39:02 +02:00
AGENTS.md feat(agent): close issues automatically in commit mode 2026-07-21 10:00:25 +02:00
go.mod feat(agent): add health loop and SQLite job store 2026-07-15 12:47:30 +02:00
go.sum feat(agent): add health loop and SQLite job store 2026-07-15 12:47:30 +02:00
Makefile fix(ci): expose /usr/bin/git on narrowed CI PATH for integration tests 2026-07-12 14:16:06 +02:00
README.md fix(agent): never switch branches in commit mode 2026-07-21 09:52:25 +02:00

forge

forge is a cross-platform command-line client for Forgejo, written in Go. The first release provides OAuth2 PKCE authentication for multiple Forgejo instances and core repository operations.

Build

go build -o forge ./cmd/forge

For versioned builds and all development tasks, use the Makefile. make build, make install, and make release derive the CLI version from git describe --tags and embed it into forge --version.

Installed binaries can be refreshed from the latest Forgejo release:

forge update --check
forge update
make run ARGS="--help"
make test
make vet
make build
make install
make release
make ci

OAuth setup

Before logging in, create a public OAuth2 application in Forgejo under Settings → Applications. Configure a loopback redirect URI such as http://127.0.0.1/; Forgejo permits any loopback port for public clients. Copy the generated client ID.

forge auth login --server https://forge.example.com --client-id YOUR_CLIENT_ID
forge auth status

An existing personal access token can be imported from standard input:

printf '%s' "$FORGE_TOKEN" | forge auth login --server https://forge.example.com --with-token

Username/password login securely prompts for the password and creates a personal access token automatically. Forgejo 2FA is handled with an additional hidden OTP prompt.

forge auth login --server https://forge.example.com --username alice

The browser login uses Authorization Code with PKCE. Access and refresh tokens are stored in the operating system keychain when available. On headless Linux without a Secret Service (no D-Bus keyring / X11), forge falls back to credentials.json in the platform user configuration directory (~/.config/forge/credentials.json on Linux), mode 0600. Force the file store with FORGE_CREDENTIAL_STORE=file. Non-secret host metadata is stored in config.json in the same directory.

# Headless server (optional explicit file store)
export FORGE_CREDENTIAL_STORE=file
forge auth login --server https://forge.example.com --username alice

Repositories

forge repo list
forge repo list --owner alice --limit 20
forge repo view alice/project
forge repo clone alice/project
forge repo clone alice/project --ssh
forge repo create project --private --add-readme --clone
forge repo create project --owner my-organization

Configure and synchronize the current Git repository without another password prompt. Existing SSH or Git credential configuration remains usable; HTTPS falls back to the token stored by forge auth login.

forge repo set-remote owner/project
forge pull
forge push
forge push --wait-for-ci

When the current branch has no tracking branch yet, forge push automatically performs the equivalent of git push --set-upstream origin <branch>. Subsequent pushes use the configured upstream normally.

If Git reports that everything is already up to date, --wait-for-ci exits immediately because no new CI run was triggered.

Release creation can also wait for the Actions run triggered by the release tag. While waiting, Forge prints the run, jobs, and individual steps in a compact status view.

On Forgejo 16 and newer, the active job and action are followed by an incrementally streamed, indented live log. Forgejo 1115 do not expose Actions logs through their public API; on those versions Forge still shows the live job/action state and reports the missing log capability once.

forge release create 0.3.0 --title "0.3.0" --notes "Release notes" --wait-for-ci

Use --host forge.example.com when multiple servers are configured and --json for machine-readable output.

Wiki

Repository wikis are available when the Forgejo instance exposes the wiki REST API. Section references use hierarchical ATX heading numbers (#1, ##1.1, ###1.1.1).

forge wiki list
forge wiki read Home
forge wiki toc Home
forge wiki read Home --section 1.3.2
forge wiki search "deployment"
forge wiki create "Setup Guide" --body-file guide.md
forge wiki update Home --section 1.3.2 --body-file section.md --message "Update deployment steps"
forge wiki update Home --section 1.3.2 --replace-old "docker run" --replace-new "podman run"
forge wiki delete Old-Page --confirm

Agent watcher

forge agent watch polls open issues that match exactly one of --user, --label, or --project, then hands each match to a local coding-agent CLI. forge agent run <number> runs the same pipeline once for a single issue.

In an interactive terminal, watch opens the agent dashboard TUI by default (--no-tui for plain logs). Settings can live in ./.forge/agent.yaml or ~/.config/forge/agent.yaml (see docs/wiki/Agent-Watch.md); CLI flags override the file.

Supported agents: cursor-agent, codex, pi, opencode, claude. Choose exactly one git mode: --commit (current branch, no switch, single job, no PR) or --pr (worktree + pull request).

forge agent watch --label ready --agent claude --model sonnet --pr --close
forge agent watch --user alice --agent codex --commit --once --dry-run
forge agent watch --label ready --agent claude --pr --ui
forge agent watch --label ready --agent claude --pr
forge agent watch --label ready --agent claude --pr --no-tui
forge agent run 42 --label ready --agent cursor-agent --pr --pre-prompt "Follow AGENTS.md"

While working, forge sets --working-label (default agent:working), posts start/finish comments, sets --ready-label (agent:ready) after successful work, and --done-label (agent:done) after the PR is merged and the worktree is removed. It can also move --project-column and --close the issue. Job state and issue/PR snapshots live in the platform config directory as agent.db (SQLite; legacy agent-state.json is imported once). A background health loop clears ghost jobs, reconciles agent:* labels, honors @agent stop (and mapped logins), and with --all-repos picks up newly accessible repositories.

forge agent watch --ui serves a status dashboard on --ui-addr (default 127.0.0.1:8787) with queue, running, done, and failed issues, a live agent output panel (ACP events or raw log), and agent/model/git-mode metadata. The UI binds to loopback by default; use --ui-token when exposing it on a non-loopback address.

In interactive terminals, the agent dashboard TUI opens by default: overview with queue, blocked issues, parallel limits, and per-run output views (n/p/Tab switch runs, d returns to overview). Every running job shows its current pipeline activity (agent, Git, PR, CI, repair, or finalization), what it is waiting for, and the next check time. The repository poll interval defaults to 10 seconds. Use --no-tui for plain logs (--ui and the TUI are mutually exclusive). When the agent supports ACP (Agent Client Protocol), forge connects as an ACP client and renders structured messages, tool calls, plans, and thinking in the agent window instead of raw stdout. Press q or Ctrl+C to stop the watcher and exit the TUI.

Dispatch respects parallel.max, parallel.per_repo, and max_open_prs from agent.yaml or flags. Issues with open Forgejo dependencies stay blocked until blockers close. After an agent PR merges, forge fetches and fast-forward pulls the local default branch.

ACP (structured agent output)

Forge acts as an ACP client (JSON-RPC 2.0 over stdio) when the selected runner exposes an ACP entry point. Structured session/update events are shown in --tui and --ui (live output panel via the status API). Headless runs auto-approve tool permissions (allow_always / allow_once). If ACP startup fails (initialize, session/new, or process start), forge falls back to the previous raw subprocess mode. For Codex, API-key auth is used only when CODEX_API_KEY or OPENAI_API_KEY is set; otherwise forge uses ChatGPT login / skips authenticate so an existing Codex login can open a session.

Forge normally finishes an ACP turn from the authoritative session/prompt response. Some agent versions close the peer or leave it open after their final answer; forge accepts those cases only after agent output was received, every tool call reached a terminal state, and pending updates were drained. An open peer is closed after five quiet seconds with the same completion evidence. Tool activity by itself is never treated as a successful turn end. The completion reason is shown in the run log/TUI.

Runner ACP Entry Fallback
cursor-agent native cursor-agent acp / agent acp cursor-agent -p --force
opencode native opencode acp opencode run --auto
codex adapter npx -y @agentclientprotocol/codex-acp codex exec
claude adapter npx -y claude-code-acp (if installed) claude -p
pi adapter npx -y pi-acp (if installed) pi -p

Post-run parsing (PR_TITLE, TODO_DONE:, usage limits) uses ACP message text when available, otherwise the captured raw output.

In --pr mode, forge babysits the pull request until CI is green (--babysit-attempts, --ci-timeout, --ci-interval), re-running the coding agent on failures. If no Actions run appears (or the run has no build jobs), babysitting is skipped and the PR run finishes normally. Markdown ToDos (- [ ]) in the issue body are checked off when the agent reports TODO_DONE: lines. Progress comments go on the issue in --commit mode and on the pull request in --pr mode (claim/start stays on the issue).

In --pr mode, each issue gets a persistent worktree under .forge-worktrees/issue-<n> that stays on disk while the pull request is open. forge agent watch removes the worktree (and optional local branch metadata) once the PR is merged or closed, and also cleans orphaned worktrees without an open PR on each poll. On every poll, forge also lists all open PRs in the watched repos, loads their full merge state, and checks for failed CI, @agent-user mentions, and merge conflicts (Forgejo mergeable=false alone is not enough — conflicts are confirmed with git merge-tree). Repairs are queued ahead of new issues in this order: failed builds, mentions, then conflicts. --max-open-prs only prevents new issue pipelines from creating more PRs; existing PRs remain eligible for babysitting and repair even when the cap is reached or exceeded. CI runs are associated by branch or exact pushed commit SHA because Forgejo pull-request workflows may expose prettyref: "#<pr>" instead of the source branch. At most one repair is selected per PR and poll. Agent branches keep .forge-worktrees/issue-<n>; other PRs use .forge-worktrees/pr-<n>. A worktree is created or restored only after a repair condition is found, so a broken branch cannot prevent unrelated PRs from being inspected. Coding-agent sessions are resumed when the CLI supports it; all repair progress is documented as PR comments. Accepted mentions are marked with a 👀 reaction, with local state as the fallback when Forgejo rejects the reaction.

Each PR poll logs how many open PRs were inspected and how many CI, mention, and conflict repairs were queued. Per-PR API, branch, or worktree failures are logged and skipped without aborting the remaining repository scan; these diagnostics also appear in the --tui output panel.

@agent is always accepted as the stable watcher alias. --agent-user additionally defaults to the authenticated Forgejo username from forge auth login / config, so either @agent or the configured login can request follow-up work in the same worktree. A comment by the authenticated repository owner is not discarded when it addresses @agent.

For codex and claude agents, the watcher pauses dispatch when usage limits are exhausted (5h / weekly windows) and rechecks every --usage-limit-interval (default 2m) until quota returns. Limit detection uses Codex app-server rate-limit data, Claude OAuth usage when credentials are present, and common rate-limit patterns in agent output.

The extended CLI also provides issue, pr, release, label, org, project, workflow, run, search, wiki, agent, ruleset, ssh-key, gpg-key, browse, status, update, and the authenticated api escape hatch. Repository-aware commands accept -R OWNER/REPO. Structured output supports --json field1,field2, --jq, and --template.

See docs/parity.md for the GitHub CLI compatibility matrix and Forgejo-specific limits.

Development

go test ./...
go test -race ./...
go vet ./...

OAuth tokens currently have the permissions granted by the Forgejo server; Forgejo does not yet implement OAuth scopes. HTTP is accepted only for loopback development instances.