Table of contents
- Agent Watcher
- Agent-Dashboard (TUI)
- ACP-Jobende
- Konfigurationsdatei
- Workspace-Modus (außerhalb eines Repos)
- Config-Mode (TUI)
- Harness-Tasks (agents)
- Prompt-Templates (prompts)
- Mention-Mapping (agent_mapping)
- User-Impersonierung (impersonate)
- Limits
- --commit-Modus: aktueller Branch
- --pr-Modus: WIP-PR und Fortschritt
- Inkrementelle Commits während der Arbeit
- Bare Mode (Repos per URL)
- Agent-Status-Labels (agent:*)
- Health-Loop und Job-Store (agent.db)
- Projekt-Spalten (--project-column)
- Wichtige Flags
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Agent Watcher
forge agent watch pollt Forgejo-Issues und übergibt Treffer an lokale Coding-Agent-CLIs (cursor-agent, codex, pi, opencode, claude).
Agent-Dashboard (TUI)
In einem interaktiven Terminal startet forge agent watch standardmäßig das Agent-Dashboard. Es zeigt Repositories, Queue, laufende und blockierte Issues, Limits und offene Agent-PRs. Mit Enter oder 1–9 öffnet man die Output-Ansicht eines Runs; n / p / Tab wechseln zwischen parallelen Runs; d oder Esc kehren zum Dashboard zurück.
c öffnet die Agent-Konfiguration (wie forge agent config) direkt im laufenden Dashboard; nach dem Speichern gelten die Werte sofort für den Watcher (Persistenz in die Workspace- bzw. Projekt-agent.yaml). a startet einen kurzen Dialog zum Hinzufügen eines Repositories per HTTPS-URL (z. B. https://repository.hildebrandt.io/frank/forgecli.git): Eintrag in die Config, Bare-Clone und Aufnahme in den Poll ohne Neustart. Im URL-Feld funktioniert normales Terminal-Paste (Ctrl/Cmd+V bzw. Bracketed Paste).
Am unteren Rand zeigt ein Activity-Log-Drawer Orchestrierungs-Events chronologisch (Agent start/stop/fail/done, Worktree anlegen/entfernen, Issue claim/label, …). Jede Zeile kann ein Task-Kind-Präfix tragen (siehe unten). Standardmäßig ist der Drawer aufgeklappt und nimmt etwa ein Drittel der Terminalhöhe ein; l klappt ihn zu/auf, f filtert nach Kategorie (Agent / Worktree / Issue), [/] scrollt in der Historie. Das Web-Dashboard (--ui) zeigt dieselben Events in einem einklappbaren Panel.
Task Kinds (Aufgabenarten)
Laufende und geloggte Jobs tragen ein stabiles Task Kind (task_kind in JSON) plus menschenlesbares Label in TUI, Web-UI, Activity-Log und Plain-Logs (--no-tui):
| Kind-ID | Label | Bedeutung |
|---|---|---|
coding |
Agent Coding | Neues Issue / Implementierung im Coding-Agent |
verify |
Verifying Implementation | Nach Coding: Vollständigkeit gegen Issue prüfen (max. verify_attempts) |
fix_build |
Fixing Build | CI fehlgeschlagen → Repair am bestehenden PR/Worktree |
resolve_conflicts |
Resolving Conflicts | Merge-Konflikte am PR beheben |
mention |
Mention Follow-up | PR-Kommentar mit @mention eines überwachten Logins als Follow-up |
Weitere Kinds lassen sich intern ergänzen; UI und Log-Formatierung nutzen TaskKindLabel. Die Detail-Activity (coding agent is working, babysitting PR #…, …) bleibt ergänzend sichtbar.
Für jeden laufenden Job zeigt das Dashboard die aktuelle Pipeline-Phase an, etwa Agent-Ausführung, WIP-PR-Eröffnung, Commit/Push, CI-Babysitting, Reparatur oder Abschluss. Wartet der Job, werden der konkrete Grund und der Zeitpunkt der nächsten Prüfung angezeigt. Der Repository-Poll läuft standardmäßig alle zehn Sekunden; während eine synchrone Pipeline aktiv ist, weist das Dashboard ausdrücklich darauf hin, dass der nächste Repository-Poll nach deren Abschluss folgt. Das CI-Babysitting prüft weiterhin mit --ci-interval (standardmäßig fünf Sekunden).
--no-tui schaltet auf Plain-Logs um. --ui startet stattdessen ein lokales Web-Dashboard (gegenseitig ausschließend mit der TUI).
ACP-Jobende
Ein ACP-Lauf endet regulär mit der Antwort auf session/prompt. Schließt ein Agent stattdessen die Verbindung oder lässt sie nach seiner letzten Antwort offen, wertet forge den Lauf nur dann als erfolgreich, wenn eine Agent-Antwort vorliegt, alle Tool-Aufrufe einen terminalen Status erreicht haben, kein Plan-Eintrag mehr in_progress/pending/active ist und ausstehende Updates verarbeitet wurden. Client-seitige FS-/Permission-RPCs (fs/read_text_file, fs/write_text_file, session/request_permission) zählen als Aktivität und verhindern einen vorzeitigen Abschluss. Bei offener Verbindung ohne Prompt-Antwort greift dieselbe Prüfung erst nach zwei Minuten ohne weitere Aktivität als Hang-Watchdog (nicht nach wenigen Sekunden Denkpause). Reine Tool-, Plan- oder Thought-Aktivität genügt nicht als erfolgreicher Abschluss. Der erkannte Abschlussgrund erscheint im Run-Log beziehungsweise im Agent-Dashboard.
Codex ACP
Für codex startet forge den Adapter codex-acp bzw. npx -y @agentclientprotocol/codex-acp. Authentifizierung:
- Mit gesetztem
CODEX_API_KEYoderOPENAI_API_KEYwird die Methodeapi-keygenutzt. - Sonst
chat-gpt(bestehender Codex-/ChatGPT-Login), oder Auth wird übersprungen, wennsession/newohnehin funktioniert. - Schlägt der ACP-Start fehl (
initialize/session/new/ Prozessstart), fällt forge aufcodex execzurück (acp fallback: …). Fehler mitten im Prompt starten keinen zweiten Raw-Lauf.
Headless setzt forge NO_BROWSER=1 und INITIAL_AGENT_MODE=agent, sofern diese Variablen nicht schon gesetzt sind. Adapter-stderr erscheint mit Präfix acp: im Run-Log.
Konfigurationsdatei
Einstellungen können in folgenden Dateien liegen:
./agent.yamlim Workspace-Modus (Start außerhalb eines Git-Repos, höchste Datei-Priorität)./.forge/agent.yaml(Projekt innerhalb eines Repos)~/.config/forge/agent.yaml
Mit --config /pfad/zur/agent.yaml lässt sich ein anderer Pfad wählen (unabhängig vom Workspace-Modus).
Precedence: CLI-Flags > Umgebung > agent.yaml > Defaults.
Workspace-Modus (außerhalb eines Repos)
Wird forge agent watch in einem Verzeichnis gestartet, das kein Git-Repository ist, gilt dieses Verzeichnis als Agent-Workspace:
agent.yamlliegt direkt im Workspace-Root (nicht unter.forge/)- Bare-Repos werden standardmäßig unter dem Workspace angelegt (
owner/repo.git), nicht unter~/.config/forge/repos/ repo_cache_dirin der Config oder--configüberschreiben das wie gewohnt
Beispiel:
mkdir -p ~/agent-ws && cd ~/agent-ws
forge agent config # legt ~/agent-ws/agent.yaml an
forge agent watch # nutzt dieselbe Datei; Bare-Caches unter ~/agent-ws/…
Innerhalb eines Git-Repos bleibt das bisherige Verhalten (./.forge/agent.yaml, globaler Default-Cache) erhalten.
Config-Mode (TUI)
forge agent config öffnet im aktuellen Verzeichnis eine interaktive TUI zum Anlegen und Bearbeiten der lokalen agent.yaml — ohne manuelles YAML-Editieren (Projekt: ./.forge/agent.yaml, Workspace: ./agent.yaml).
forge agent config --print liest dieselbe Config-Suchreihenfolge wie watch/run, füllt eingebaute Defaults auf (Labels, Intervalle, agent_mapping, Codex-Harness-Tasks, Prompt-Templates, …) und schreibt die effektive Config als YAML nach stdout (kein TTY nötig). Mit --config /pfad lässt sich eine konkrete Datei wählen.
- Lädt vorhandene Config beim Start
- Repositories hinzufügen, bearbeiten, entfernen (optional Vorschlag aus
git remote origin); Textfelder akzeptieren Paste - Limits (
parallel.max,parallel.per_repo,max_open_prs, per-Repo-Overrides) - Alle relevanten Agent-Optionen:
agent,model,git_mode, Trigger, Labels, CI/Babysit,interval,agent_user,agent_mapping, Harness-Tasks (agents.*), Prompt-Templates (prompts.*),impersonate,pre_prompt,repo_cache_dir, … - Speichern mit Bestätigung (überschreibt die Projekt-Datei); Zielpfad wird angezeigt
- Danach starten
forge agent watch/forge agent runmit den gespeicherten Werten ohne wiederholte Flags
Tasten (Auszug): ↑↓ navigieren, Enter bearbeiten, ←→ / Leertaste bei Auswahlfeldern, a/e/d in der Repo-Liste, q beenden.
Beispiel:
interval: 10s
agent: cursor-agent
model: ""
git_mode: pr # commit | pr
trigger:
label: agent # genau einer: user | label | project
parallel:
max: 3
per_repo: 1
max_open_prs: 2
# Watch every repository the authenticated user can access (merged with repos: overrides).
all_repos: false
repos:
- owner: frank
name: forgecli
# Bare mode (default): omit path — forge clones bare to ~/.config/forge/repos/owner/repo.git
- url: https://repository.hildebrandt.io/frank/forgecli.git
- owner: frank
name: legacy-app
path: ~/src/legacy-app # optional legacy checkout
max_parallel: 1
max_open_prs: 2
# Optional override for bare-repo cache root (default: ~/.config/forge/repos)
repo_cache_dir: ~/.config/forge/repos
# How often watch fetches origin and refreshes the default branch (default: 1m)
repo_sync_interval: 1m
working_label: agent:working
ready_label: agent:ready
done_label: agent:done
babysit_attempts: 3
verify_attempts: 3
# Optional per-harness task profiles (model / reasoning / pre_prompt).
# Codex defaults when unset: code→gpt-5.6-sol; fix_build/resolve_conflicts/mention/verify→gpt-5.6-terra
# with escalate to gpt-5.6-sol after 2 failed fixes for fix_build and resolve_conflicts.
agents:
codex:
code:
model: gpt-5.6-sol
reasoning: high
labels:
- label: agent:deep
reasoning: xhigh
fix_build:
model: gpt-5.6-terra
reasoning: medium
escalate_after: 2
escalate:
model: gpt-5.6-sol
reasoning: high
verify:
model: gpt-5.6-terra
Harness-Tasks (agents)
Unter agents.<harness> lassen sich pro Coding-Agent und pro Aufgabenart Modell, Reasoning und Pre-Prompt setzen:
| YAML-Key | Task Kind | Verwendung |
|---|---|---|
code |
coding |
Issue-Implementierung |
verify |
verify |
Post-Coding-Vollständigkeitscheck |
fix_build |
fix_build |
CI-Repair (Babysit / Watch) |
resolve_conflicts |
resolve_conflicts |
Merge-Konflikt-Repair |
mention |
mention |
PR-@mention Follow-up |
Felder je Task: model, reasoning, pre_prompt, optional escalate_after + escalate.{model,reasoning,pre_prompt}.
- Escalation: wenn
fixAttempt > escalate_after, gelten dieescalate.*-Werte (leere Escalate-Felder erben vom Task). code.labels: Liste von Modifiern; erste passende Issue-Label (case-insensitive) überschreibt Model/Reasoning und hängtpre_promptan.- Pre-Prompt-Compose: globales
pre_prompt+ Task-pre_prompt(+ Label-pre_prompt) mit\n\n. - CLI
--modelüberschreibt nur das Modell für alle Tasks; Reasoning/PrePrompt bleiben aus dem Harness-Profil. - Codex-Defaults (wenn Felder leer):
code→gpt-5.6-sol;fix_build/resolve_conflicts/mention/verify→gpt-5.6-terra; beifix_buildundresolve_conflictsEscalation nach 2 Fixes →gpt-5.6-sol. - Reasoning wird für Codex als
-c model_reasoning_effort=…(raw CLI) bzw. best-effort ACP-Session-Config gesetzt. - Bearbeitbar in
forge agent configunter Harness tasks (agents.*).
Prompt-Templates (prompts)
Die festen Prompt-Bodies pro Aufgabenart sind als Go text/template in agent.yaml überschreibbar. Leer = eingebauter Default. forge agent config --print zeigt die effektiven Templates inkl. Platzhalter.
prompts:
code: |
{{if .PrePrompt}}{{.PrePrompt}}
{{end}}## Forgejo issue to implement
...
verify: |
## Verify implementation completeness
...
fix_build: |
## Fix failing CI for this pull request
...
resolve_conflicts: |
## Resolve merge conflicts for this pull request
...
mention: |
## Respond to a pull request mention
...
| YAML-Key | Task | Wichtige Felder im Template |
|---|---|---|
code |
Issue-Implementierung | .PrePrompt, .Number, .Title, .HTMLURL, .Labels, .GitMode, .IsPR, .Body, .Todos, .WorkingLabel, .ProgressCommentStyle, .IncrementalGit |
verify |
Post-Coding-Check | .PrePrompt, .Number, .Title, .HTMLURL, .Labels, .GitMode, .IsPR, .Body, .Todos, .WorkingLabel, .ProgressCommentStyle, .IncrementalGit |
fix_build |
CI-Repair | .Number, .Title, .PRNumber, .Failure, .Todos, .ProgressCommentStyle, .IncrementalGit |
resolve_conflicts |
Merge-Konflikt-Repair | .Number, .Title, .PRNumber, .BaseBranch, .Detail, .Todos, .ProgressCommentStyle, .IncrementalGit |
mention |
PR-@mention Follow-up | .Number, .Title, .PRNumber, .MentionedLogin, .CommentAuthor, .CommentID, .CommentBody, .Todos, .ProgressCommentStyle, .IncrementalGit |
pre_prompt(global / Harness) wird zusätzlich vor den gerenderten Body gehängt (beim Coding-Task auch als.PrePromptim Template verfügbar).- Ungültige Templates erzeugen einen Fehler-Prompt statt eines Agent-Laufs mit leerem Text.
- Bearbeitbar in
forge agent configunter Prompt templates (prompts.*); für lange Texte ist YAML bzw.--printoft praktischer als die TUI-Zeile.
Mention-Mapping (agent_mapping)
Im PR-Modus (git_mode: pr) überwacht forge agent watch offene Pull Requests auf unbeantwortete @mentions. Standardmäßig gilt ein agent_user (Default: authentifizierter Config-Username) plus der stabile Alias @agent.
Mit agent_mapping lassen sich mehrere Forgejo-Logins gleichzeitig überwachen und jeweils einem Coding-Agent zuordnen:
agent_user: frank # eigener Login; wird zusätzlich überwacht, falls nicht schon ein Mapping-Key
agent_mapping:
agent: default # @agent → globaler Agent aus agent: / --agent
codex: codex
cursor: cursor-agent
claude: claude
pi: pi
defaultbedeutet: denselben Agent nutzen wie die globaleagent-Einstellung.- Alle Keys im Mapping werden auf @mentions geprüft;
agent_userwird ergänzt, wenn er nicht bereits als Key vorkommt. - Bei User-Trigger (
trigger.user/--user) matcht der Watcher zusätzlich Issues, die einem Mapping-Login zugewiesen sind (z. B. Assigneecodexbeitrigger.user: agent). - Mentions ohne Mapping-Eintrag werden ignoriert (wie bisher bei fremden Usern).
- Bei
@codex …startet der Watcher den gemappten Runner (codex) in derselben Worktree-Session, wenn möglich. - Bearbeitete Mentions werden mit 👀 markiert und danach nicht erneut eingeplant — unabhängig davon, welcher Login die Reaction gesetzt hat (Impersonation vs. Token-User).
- Bearbeitbar in
agent.yamlund perforge agent config(TUI-Menü Mention mapping).
User-Impersonierung (impersonate)
Damit Agent-Aktionen (Kommentare, Reactions, Labels, PRs) und forge-eigene Commits als der angesprochene bzw. zugewiesene Agent-User erscheinen, gibt es Admin-Impersonierung über die Forgejo-Sudo-API:
impersonate: true
agent_user: agent # Fallback, wenn kein Mapping-Assignee/Mention greift
agent_mapping:
cursor: cursor-agent
codex: codex
Oder per Flag: forge agent watch --impersonate …
Verhalten:
- Der authentifizierte Token muss Site-Admin sein (OAuth-Apps können fremde User nicht impersonieren).
- Beim Start wird Admin + Fallback-
agent_userper Sudo validiert. - Pro Job gilt:
@cursor-Mention oder Assigneecursor→Sudo: cursor; analog fürcodex,claude, … Ohne Mapping-Treffer → Fallbackagent_user. - Der Coding-Agent kommt aus
agent_mappingfür denselben Login (Assignee/Mention). - Existierende Logins aus
agent_user+agent_mappingerhalten auf allen watched Repos automatisch Collaborator-Rechtwrite(fehlende Accounts werden übersprungen, nicht angelegt). GIT_AUTHOR_*/GIT_COMMITTER_*werden aus dem Job-Ziel-User gesetzt.
Out of scope: Auto-Create von Forgejo-Accounts, Rechterücknahme beim Entfernen aus dem Mapping.
Limits
| Einstellung | Flag | Bedeutung |
|---|---|---|
parallel.max |
--parallel |
Max. gleichzeitige Pipelines global |
parallel.per_repo |
--parallel-per-repo |
Max. gleichzeitige Pipelines pro Repository |
max_open_prs |
--max-open-prs |
Max. offene Agent-PRs, bevor neue Issue-Runs warten |
repos[].max_parallel |
— | Per-Repo-Override für Parallelität |
repos[].max_open_prs |
— | Per-Repo-Override für offene PRs |
max_open_prs ist ausschließlich ein Gate für neue Issue-Pipelines, die einen weiteren PR erzeugen könnten. Bereits offene PRs werden auch bei erreichtem oder überschrittenem Limit weiter gebabysittet; CI-Fehler, Mentions und Merge-Konflikte bleiben reparaturberechtigt und werden vor neuen Issues eingeplant. Parallelitätslimits gelten weiterhin.
Issues ohne freien Slot bleiben in der internen Queue (Dashboard: queued) und erhalten kein agent:*-Label. Laufende Pipelines und noch nicht sichtbare WIP-PRs reservieren ihre Slots beim Dispatch; ein erneuter Limit-Check vor dem Claim verhindert vorzeitiges agent:ready bei überbuchten Slots.
Beim Babysitting ordnet forge einen Actions-Run über den Branch oder den exakten gepushten Commit-SHA zu. Das ist für Forgejo-PR-Workflows erforderlich, weil deren Runs häufig prettyref: "#<pr>" statt des Quell-Branches und den Commit nur als commit_sha liefern.
Erscheint innerhalb von zwei Minuten (bzw. ci_timeout, falls kürzer) kein Actions-Run, oder der Run hat keine Build-Jobs, überspringt forge das Babysitting und schließt den PR-Lauf normal ab (agent:ready) — ohne den Coding-Agenten erneut zu starten.
--commit-Modus: aktueller Branch
Im Git-Modus --commit (bzw. git_mode: commit) gilt:
- Arbeitsverzeichnis ist der bestehende Checkout (
repos[].pathoder aktuelles Working Tree). Es werden keine Agent-Worktrees und keine Agent-Branches angelegt. - Branch bleibt unverändert: forge wechselt den Checkout nicht (Health-Sync nur
fetch, keincheckout/pullder Default-Branch). Der Coding-Agent darf den Branch weder wechseln noch neu anlegen; Verstöße werden erkannt und der Checkout zurückgesetzt. - Parallelität ist fest 1:
parallel.max,parallel.per_repo,--parallelund Repo-Overrides werden auf1geklemmt. Es läuft immer nur ein Job. - Keine Pull Requests: Es werden keine PRs benötigt oder erzeugt. forge öffnet, aktualisiert oder babysittet keine PRs; der Coding-Agent soll auch keine anlegen.
max_open_prswird ignoriert. - Publish: Dirty-Änderungen werden commitet und mit normalem
git push(ohne Force) auf dem aktuellen Branch veröffentlicht. - Abschluss: Während des Laufs fasst forge ACP-Chat-Abschnitte zusammen und postet sie als lesbare Issue-Kommentare (kein PR). Nach erfolgreichem Publish folgt der Agent usage-Block am Issue; Labels wechseln direkt zu
agent:done(keinagent:ready-Zwischenzustand wie im PR-Modus). Das Issue wird geschlossen (auch ohne--close/close: true). - Bare-Cache ist in diesem Modus nicht erlaubt — ohne Working Tree fehlt der „aktuelle Branch“. Für bare-only-Setups
--prnutzen oderrepos[].pathauf einen Checkout setzen.
Beispiel:
git_mode: commit
# parallel wird auf 1 geklemmt, auch wenn hier höher steht
parallel:
max: 1
repos:
- owner: frank
name: forgecli
path: ~/src/forgecli
forge agent watch --label agent --agent cursor-agent --commit
--pr-Modus: WIP-PR und Fortschritt
Im Git-Modus --pr (bzw. git_mode: pr) gilt:
- Claim/Start bleibt am Issue (Kommentar, Working-Label, optional Projekt-Spalte).
- Sofort nach Worktree-Anlage force-pusht forge den Branch und öffnet einen Pull Request mit Titel
WIP: #<issue> <titel>und einer Kurzbeschreibung der Aufgabe. - Während des Haupt-Agent-Laufs fasst forge zusammenhängende ACP-Chat-Abschnitte zwischen Tool-Calls zusammen und postet sie als lesbare PR-Kommentare (keine Roh-Tool-Dumps). Die Default-Prompts fordern den Coding-Agenten auf, Intent/Fortschritt nur im Stil kurzer PR-Arbeitskommentare zu formulieren (technisch, ohne Chat-Fülltext).
- Nach erfolgreichem Agent-Lauf committe forge verbleibende Dirty-Änderungen selbst, force-pusht den Agent-Branch (
git push --force), lehnt einen leeren PR (keine Commits vor dem Default-Branch) ab, entfernt sonst dasWIP:-Präfix, aktualisiert Titel und Description (inkl.PR_TITLE:/PR_BODY:aus der Agent-Ausgabe,Closes #<issue>) und babysittet CI. - CI-/Konflikt-Reparaturen (Watch-Babysit,
RunCIFix,RunConflictFix, Mention-Follow-ups) kommentieren nur am PR — Titel und Description werden dabei nicht erneut geschrieben. Follow-ups stellen für die Dauer der Arbeit dasWIP:-Präfix wieder her. Vor dem Konflikt-Agenten sync’t forge die Default-Branch im Repo-Cache (git fetch+ Fast-Forward von lokalemmain/masterauforigin/<base>), damit Merge/Rebase gegen den aktuellen Remote-Stand laufen. - Merge-Konflikt-Detection vs. Repair: Forgejo setzt
mergeable=falseauch bei WIP, während der Konfliktprüfung (Checking) oder bei Fehlern — ohne echten Merge-Konflikt. Watch und Babysit behandelnmergeable=falsenur als Kandidat und bestätigen Konflikte lokal mitgit merge-treegegenorigin/<base>. Explizitemergeable_state-Werteconflicts/dirty(GitHub-Kompat) zählen ebenfalls als Signal, werden aber ebenfalls per Git verifiziert. Repair-Fortschritt und „resolved“ hängen am Git-Check, nicht am Forgejo-mergeable-Flag (nachbeginPRFollowUpbleibt der Titel wieder WIP und damit API-seitig oft unmergeable).
Fortschritt nach dem Claim liegt am PR; der Issue-Start-Kommentar verweist weiterhin auf die Aufgabe.
Agent usage am Abschluss
Wenn forge einen Lauf abschließt — im --pr-Modus nach grünem CI (agent:ready), im --commit-Modus nach erfolgreichem Publish (agent:done + Issue schließen) — postet forge einen Agent usage-Block als Kommentar am PR bzw. am Issue. Enthalten sind — soweit vom Harness geliefert:
| Feld | Quelle |
|---|---|
| In/Out tokens (+ Cache) | ACP PromptResponse.usage, sessionUpdate: usage_update |
| Cost | ACP Cost oder CLI-Log-Heuristiken (cost_usd, cost:) |
| Limits | Context used/size aus ACP; Provider-Quota via Usage-Limit-Checker (Codex/Claude) |
| Runtime | Gesamtdauer vom ersten Agent-Start bis zum Abschluss |
Fehlende Werte werden weggelassen; der Abschluss bricht nicht ab. Follow-up-Läufe (CI-Fix, Mentions) fließen in die Aggregation ein, solange Metriken kumuliert oder pro Lauf committet werden können.
Beispiel:
📊 **Agent usage** (`cursor-agent` / ACP)
| | |
| --- | --- |
| In tokens | 120 000 (cached read 80 000) |
| Out tokens | 8 500 |
| Cost | $1.23 USD |
| Limits | context 142 000 / 200 000 · quota ok |
| Runtime | 12m 34s |
Inkrementelle Commits während der Arbeit
Der Agent-Prompt fordert regelmäßige, thematisch kleine Commits mit sofortigem Push nach abgeschlossenen Teilschritten (conventional commit messages). So bleibt der bereits geöffnete WIP-PR früh mit sichtbarem Verlauf aktualisiert und CI kann früher Feedback geben.
Nach dem Agent-Lauf gilt:
- Uncommittet → forge committe die Reständerungen selbst (
git add -A+ Commit). Kein Agent-Follow-up nur zum Committen — der hatte zuvor leere PRs begünstigt (Reset statt Commit). - Force-Push → forge force-pusht den Agent-Branch (
git push --force origin HEAD:refs/heads/<branch>), prüft danach, dass nichts mehr ungepusht ist. - Keine publizierte Arbeit → fehlen Commits vor dem Default-Branch (
--pr) bzw. hat sich HEAD nicht bewegt (--commit), versucht forge zuerst Orphan-Tree-Recovery, kommentiert klar am Issue/PR und startet einen Follow-up-Agent-Lauf („Issue jetzt implementieren und committen“). Scheitert auch der, bricht der Lauf mit einer verständlichen Fehlermeldung ab (kein leerer „fertig“-PR); Issue erneut mitagent:ready/forge agent runanstoßen. - Verify → nach erfolgreichem Publish startet forge bis zu
verify_attempts(Default 3) Verify-Läufe (prompts.verify/agents.*.verify). Der Agent prüft die Branch-Arbeit gegen das Issue, zieht fehlendes nach und commitet. Enthält die AusgabeAlles Implementiert(case-insensitive), endet die Schleife früh; fehlt der Marker nach allen Versuchen, läuft die Pipeline best-effort weiter (kein Fail). Mentions, CI- und Konflikt-Repairs überspringen Verify.
Dasselbe gilt für bestehende Worktrees (Reuse nach Restart/Update, WIP-PR-Wiederaufnahme, CI-/Mention-/Konflikt-Follow-ups): vor dem Weiterarbeiten werden Reständerungen forge-seitig publiziert — bei dirty Worktree zuerst Commit, dann Force-Push. Die Worktree-Maintenance flushed offene PR-Worktrees nach Restart ebenso (Commit + Force-Push). Leere offene PRs versuchen zusätzlich, verlorene Agent-Arbeit aus dangling Git-Trees wiederherzustellen (nur wenn der Diff nicht vorwiegend neueres Base-Work löscht); Branches mit eigenen Commits werden beim Flush immer force-gepusht.
Pull Requests öffnet und finalisiert weiterhin nur der Watcher (git_mode: pr). Derselbe Commit-/Push-Abschluss gilt für CI-Fixes, Mentions und Konflikt-Reparaturen.
Optional kann pre_prompt das Verhalten verstärken, z. B.:
pre_prompt: |
Commit and push after every logical step. Keep commits small and conventional.
Do not open a pull request yourself.
Im --commit-Modus entfällt der PR-Bezug vollständig (nur Commit/Push auf dem aktuellen Branch).
Issues mit offenen Forgejo-Dependencies (blocked-by) werden als blocked angezeigt und nicht gestartet, bis die Blocker geschlossen sind.
Bare Mode (Repos per URL)
Ohne repos[].path braucht der Agent-Orchestrierer keinen manuellen Checkout mehr:
- Fehlende Repos werden als bare Clone unter
~/.config/forge/repos/owner/repo.gitangelegt (Cache-Root konfigurierbar viarepo_cache_dir; im Workspace-Modus standardmäßig das Workspace-Verzeichnis). - Vor jedem neuen Issue-Worktree läuft
git fetch --prune origin; bei Bare-Caches wird der lokale Default-Branch-Ref auforigin/<default>nachgezogen. Neue Agent-Branches starten immer vonorigin/<default>(auch bei Legacy-Checkouts), damit frischemain/master-Änderungen Konflikte reduzieren. Nach gemergten Agent-PRs wird der Default-Branch ebenfalls aktualisiert. - Agent-Worktrees liegen unter
.forge-worktrees/issue-<n>/bzw.pr-<n>/innerhalb des Bare-Caches; Push aus dem Worktree funktioniert wie gewohnt.
Repos können per url: (HTTPS/SSH), owner/name (+ optional host), CLI --repos owner/repo oder --all-repos angegeben werden. Mit --all-repos (bzw. all_repos: true) lädt forge die Liste zugänglicher Repositories über die Forgejo-API (/user/repos) und merged sie mit expliziten repos:-Einträgen; vorhandene Einträge überschreiben Pfad und Limits für dasselbe owner/name. Ohne --all-repos bleibt das Verhalten unverändert (nur konfigurierte repos: bzw. -R/--repos). Bei vielen Repositories empfiehlt sich das Setzen von parallel.max, parallel.per_repo und max_open_prs. Legacy-Checkouts mit repos[].path oder cwd-Erkennung bleiben parallel nutzbar.
Nach dem Merge eines Agent-PRs holt forge bei Bare-Repos per fetch --prune; bei Legacy-Checkouts weiterhin fetch + pull --ff-only auf dem Default-Branch. Anschließend wird der zugehörige Worktree entfernt und das Issue erhält agent:done (ersetzt agent:ready).
Agent-Status-Labels (agent:*)
Der Agent pflegt genau ein agent:*-Label pro Issue:
| Phase | Label |
|---|---|
| Claim / aktive Pipeline | agent:working |
| Arbeit abgeschlossen (Coding/Babysit fertig, PR offen) | agent:ready |
| PR gemerged und Worktree gelöscht | agent:done |
Beim Setzen eines neuen agent:*-Labels entfernt forge alle anderen Labels derselben Familie. Fehlende Repo-Labels (agent:working, agent:ready, agent:done) werden bei Bedarf automatisch angelegt.
Konfiguration: working_label, ready_label, done_label in agent.yaml oder --working-label, --ready-label, --done-label (Defaults siehe forge agent watch --help). Der Issue-Trigger (--label / trigger.label) ist davon getrennt und nutzt typischerweise kein agent:-Präfix.
Bei Pipeline-Fehlschlag wird agent:working entfernt; es wird kein agent:ready oder agent:done gesetzt.
Health-Loop und Job-Store (agent.db)
Während forge agent watch läuft ein Health-Loop parallel zu aktiven Pipelines (Intervall = --interval). Er hält die Instanz im Hintergrund stabil:
| Check | Aktion |
|---|---|
| Ghost-Jobs | Stale running-Einträge ohne aktive Pipeline → failed, agent:working entfernen |
| Labels | Genau ein erwartetes agent:* pro bekanntem Job wiederherstellen |
@login stop |
@agent/@codex/@cursor/… plus stop/abort/cancel/halt bricht den Job ab |
| Issue-Änderungen | Close / Trigger verloren → Stop; Body/Title-Fingerprint für laufende Jobs |
--all-repos |
Neue zugängliche Repos periodisch hinzufügen (ohne bestehende zu droppen) |
| Repo-Sync | Periodisch git fetch aller Remote-Branches; Default-Branch (meist main) lokal nachziehen — Intervall repo_sync_interval / --repo-sync-interval (Standard: 1m) |
| API/DB | Forgejo-Probe und SQLite-Ping; Poll-Fehler pro Repo isolieren, Watcher läuft weiter |
Der Repo-Sync hält Bare-Caches und Legacy-Checkouts nah am Server: alle origin/*-Refs werden aktualisiert, der Default-Branch zusätzlich als lokaler Tip. Unabhängig davon refreshed forge den Default-Branch unmittelbar vor jedem neuen Issue-Worktree; Startpunkt ist origin/<default>. Bei Legacy-Checkouts mit laufendem Job macht der periodische Sync nur Fetch (kein Checkout/Pull); neue Worktrees brauchen das nicht, weil sie vom Remote-Tip starten.
Persistenz liegt in SQLite ohne CGO (modernc.org/sqlite):
- Pfad:
~/Library/Application Support/forge/agent.db(bzw.os.UserConfigDir()/forge/agent.db) - Tabellen:
jobs,job_events,issue_snapshots,pr_snapshots - Einmaliger Import aus Legacy
agent-state.json→ Umbenennung nachagent-state.json.bak
Stop-Beispiel auf Issue oder PR: @agent stop oder @codex abort.
Projekt-Spalten (--project-column)
Wenn --project gesetzt ist, kann --project-column (oder project_column in agent.yaml) das Issue beim Claim in eine Board-Spalte verschieben. Der primäre Lock bleibt das Working-Label (agent:working); die Spalte ist ein zusätzlicher Board-Status.
forge erkennt zur Laufzeit, welche Project-REST-Variante die Forgejo-Instanz anbietet, und nutzt dann deterministisch genau diese Pfade:
| Forgejo | Gitea (Referenz) | Variante | Endpunkte |
|---|---|---|---|
| < 7.0 | < 1.22 | legacy-cards |
GET /projects/{id}/columns, Karten unter /projects/columns/{id}/cards |
| 7.0 – 10.x | 1.22 – 1.25 | legacy-cards |
Repository-Boards in der UI; REST meist Legacy-Karten-API |
| 11.0+ | 1.23+ (wenn REST vorhanden) | repo-issues |
GET /repos/{owner}/{repo}/projects/{id}/columns, POST /repos/.../projects/columns/{id}/issues/{index} |
| beliebig | beliebig | unsupported |
Projects-Unit deaktiviert oder kein Column-REST (404/501/405 auf allen Probes) |
Verhalten:
- API vorhanden und Spalte gefunden → Move muss gelingen, sonst bricht der Claim mit Fehler ab.
- API nicht unterstützt → expliziter Skip mit Grund im Log (
project column move skipped: …); der Agent-Lauf geht weiter. - Spaltenname nicht gefunden → Fehler (auch wenn die API grundsätzlich verfügbar ist).
Die Matrix steht auch im Code (ForgejoProjectColumnSupport in internal/agent/project_column.go) und wird bei jeder Instanz per Probe verifiziert, nicht nur anhand der Versionsnummer.
Wichtige Flags
Siehe forge agent watch --help für die vollständige Liste. Auszug (auch in agent.yaml möglich):
--agent— Coding-Agent-CLI--label/--user/--project— Issue-Trigger (genau einer)--project-column— Spalte im Projekt-Board beim Claim (z. B. „In Arbeit“)--commit/--pr— Git-Modus (--commit: aktueller Branch, max. 1 Job, kein PR;--pr: Worktree + WIP-PR sofort, Finalisierung nach Agent-Lauf)--repos owner/repo,...— weitere Watch-Targets (bare-cloned ohne lokales path; im--commit-Modus braucht jedes Target einen Working-Tree/path)--all-repos— alle für den Login zugänglichen Repositories überwachen (merged mitrepos:)--parallel,--parallel-per-repo,--max-open-prs— Dispatch-Limits (im--commit-Modus Parallelität=1,max_open_prsirrelevant)--interval— Repository-Prüfintervall (Standard:10s)--repo-sync-interval— Fetch/Sync der Default-Branch für watched Repos (Standard:1m)--ci-interval— CI-Prüfintervall beim PR-Babysitting (Standard:5s)--working-label,--ready-label,--done-label—agent:*Lifecycle-Labels (siehe Wiki)--no-tui— Plain-Logs statt Dashboard--config— Pfad zur Agent-Konfiguration
forge agent config — interaktive TUI für die lokale agent.yaml (siehe Abschnitt Config-Mode)