gofer

module
v0.8.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 4, 2026 License: Apache-2.0

README

gofer

Your errand-runner for agents. gofer is a daemon + TUI for running and supervising many coding agents at once — a roster of live sessions, peek/attach navigation, and phone-driven sessions over ACP — built in Go on agent-sdk-go. (Tool-call approvals reach your phone over ACP; see the roadmap.)

Status: M6 — process isolation — shipped; M5 in flight. M6 runs each session in its own detached gofer session-worker process behind a thin router daemon, so the daemon and CLI can be upgraded in place while live turns finish on the binary that started them. It is opt-in and off by default — enable it with gofer daemon --workers. M5 (ACP v1 featureset expansion) is in progress alongside it: usage_update, the diff/plan pass-throughs, resume (session/load with full-history replay), and model discovery (gofer/models) are all on the ACP surface; the image/resource content blocks and the Agmente client legs are still landing. Earlier milestones stand: M3's permission engine

  • approvals relay and M4's slash dispatcher and command panel — /status (per-provider auth), /config (a settings registry backed by config.Save), and /model (a picker that hot-swaps a live session's model), with autocomplete and a chat-style redesign. gofer exec runs headless one-shots; gofer daemon install runs it as a service; OpenTelemetry export is off by default. gofer run/resume route through a daemon or fall back in-process; gofer ps/kill/archive manage the roster; gofer demo streams a faux-provider session with no network. See docs/PRD.md and docs/TUI.md and the roadmap.

What it is

┌ overview ────────────────────────────────────────────┐
│ ● fix-ci        running   linux-build   $0.42  2m11s │
│ ● refactor-api  waiting   approval ⚠    $1.03  8m40s │
│ ○ docs-pass     done      —             $0.11  1h02m │
│                                                      │
│ [enter] open · [space] peek · [ctrl-x] kill          │
└──────────────────────────────────────────────────────┘
  • One roster, many agents — every running session, its state, cost, and pending approvals in one screen; overview ⇄ peek ⇄ attach navigation.
  • Everything is a client — the TUI, ACP clients (phone/editor), and headless exec all consume the same typed Event/Op stream. Attach from anywhere; the bytes are identical.
  • Structural permissions — allow/ask/deny rules; approvals are protocol messages that render in the TUI or on your phone (Claude Code settings-format import lands later).
  • Slash commands — a dispatcher with autocomplete opens a command panel: /status (per-provider auth), /config (live settings), /model (pick and hot-swap a session's model).
  • Session lifecycle you can trust — event-sourced JSONL journals; kill or archive from the roster, resume after a crash, fork at any point. Journals are never deleted.

Try it

go run ./cmd/gofer demo

Streams a scripted faux-provider session through the real event pipeline — no API key, no network.

Auth (M1)

gofer login anthropic          # subscription OAuth (paste the code back)
gofer login openai             # subscription OAuth (local browser redirect)
gofer login anthropic --api-key   # reads a key from stdin, never argv
gofer auth                     # show configured providers and credential status
gofer logout anthropic

Credentials persist in ~/.gofer/auth.json (mode 0600). gofer auth never prints token material.

Subscription-OAuth self-description caveat. Logging in with subscription OAuth (gofer login <provider>, no --api-key) authenticates over the vendor's coding-assistant credential path (Anthropic's "Claude Code", OpenAI's "Codex"), which carries a fixed assistant identity in the system context. That identity can bleed into how the model describes itself in a session — so an agent may call itself "Claude Code" regardless of gofer's own system prompt. This is inherent to subscription auth, not a gofer bug. Use --api-key (or the provider's API-key env var) if you need the model's self-description to reflect only gofer's system prompt.

Run a session (M1)

export ANTHROPIC_API_KEY=sk-...   # or `gofer login anthropic`
gofer run "create hello.txt containing hi using your tools, then summarize"
# Ctrl-C mid-run, then:
gofer resume <id> "continue"      # id was printed to stderr on start
gofer resume <id>                 # no prompt: print the transcript and exit

A real provider streams through the builtin tools (bash, read, edit, write, grep, glob, ls) into a durable JSONL journal — kill it and the settled prefix survives; resume folds it back into context.

Run interactively (a prompt given as an argument, in a real terminal, no --json) and the stream renders through gofer's minimal attach TUI instead of the plain transcript — esc or Ctrl-C interrupts the run, same as Ctrl-C on the line renderer. Anything non-interactive — --json, a piped/redirected stdout, or a prompt piped in on stdin — always renders as the line-oriented stream, so scripts and CI never hit the TUI.

Roadmap

Stage Ships
M0 · scaffold repo + gofer demo streaming the SDK's faux provider
M1 · one good session real provider, builtin tools, resumable sessions, cost accounting
M2 · the daemon supervisor, roster, overview⇄peek⇄attach TUI, native ACP over WebSocket, bearer auth
M3 · guardrails permission engine + approvals UX, sandboxed exec, headless mode
M4 · command views slash dispatcher, /status//config//model panels, autocomplete, TUI redesign
M5 · ACP v1 featureset expansion 🚧 in flight cross-repo ACP conformance push — usage_update on session/update, diff and plan pass-through, session/set_config_option + session/list (shipped); rich content blocks, resume, model discovery + set_model, capability stretch (titles, commands/mode) still landing
M6 · process isolation ✅ Phases 0-3 detached per-session gofer session-worker processes behind a thin router daemon; upgrade the binary mid-turn without interrupting live sessions. Opt-in, off by default (gofer daemon --workers). Phase 4 (offline resume, cost aggregation, graceful drain) has since shipped too — #139 and #140 are closed
M7 · ecosystem MCP servers, SKILL.md skills, out-of-process plugins, subagents first-class (the parent/child primitive + roster tree already landed — gofer run --parent/--agent; remaining is linked journals and the wider plugin UX)
M8 · auto + polish auto mode with reviewer pipeline, CC-asset import, multi-machine discovery

Contributing

See CONTRIBUTING.md for build/test/lint commands and the PR workflow.

License

Apache-2.0. See NOTICE for attribution requirements.

Directories

Path Synopsis
cmd
gofer command
Command gofer is the CLI entrypoint for the gofer agent platform.
Command gofer is the CLI entrypoint for the gofer agent platform.
internal
capability
Package capability carries the read-only runtime capability report the TUI's /mcp and /skills command-panel tabs render (gofer#303): which MCP servers are configured and which of them currently hold a live connection, how the tool surface is presented to the model, and which SKILL.md skills a session created here would load.
Package capability carries the read-only runtime capability report the TUI's /mcp and /skills command-panel tabs render (gofer#303): which MCP servers are configured and which of them currently hold a live connection, how the tool surface is presented to the model, and which SKILL.md skills a session created here would load.
config
Package config is gofer's native on-disk configuration.
Package config is gofer's native on-disk configuration.
daemon
Package daemon hosts a supervisor.Supervisor behind a WebSocket listener speaking the Agent Client Protocol (ACP) v1 over JSON-RPC 2.0, plus a small set of gofer-native control methods (namespaced "gofer/*") for the CLI client.
Package daemon hosts a supervisor.Supervisor behind a WebSocket listener speaking the Agent Client Protocol (ACP) v1 over JSON-RPC 2.0, plus a small set of gofer-native control methods (namespaced "gofer/*") for the CLI client.
daemonbridge
Package daemonbridge adapts a *daemon.Client — a JSON-RPC-over-WebSocket connection to a running `gofer daemon` — to the TUI's narrow tui.Supervisor consumer interface, so the same roster/peek/attach TUI that renders a local in-process supervisor (see internal/tuibridge) can instead render a daemon's live roster: a session created from a phone or editor ACP client appears in the laptop TUI too.
Package daemonbridge adapts a *daemon.Client — a JSON-RPC-over-WebSocket connection to a running `gofer daemon` — to the TUI's narrow tui.Supervisor consumer interface, so the same roster/peek/attach TUI that renders a local in-process supervisor (see internal/tuibridge) can instead render a daemon's live roster: a session created from a phone or editor ACP client appears in the laptop TUI too.
decision
Package decision carries gofer's structured-decision round trip: an agent asks the human one or more titled, multiple-choice questions through the `ask_user` tool and blocks until a client answers them.
Package decision carries gofer's structured-decision round trip: an agent asks the human one or more titled, multiple-choice questions through the `ask_user` tool and blocks until a client answers them.
lspdiag
Package lspdiag is the consuming layer over the SDK's lsp/ package (see agent-sdk-go's docs/DESIGN.md "LSP" section): it starts real language servers on demand, drives a diagnostics round-trip after an edit/write tool call, and hands the result to gofer's tool-result pipeline so it reaches both the transcript/event stream AND the model's own context.
Package lspdiag is the consuming layer over the SDK's lsp/ package (see agent-sdk-go's docs/DESIGN.md "LSP" section): it starts real language servers on demand, drives a diagnostics round-trip after an edit/write tool call, and hands the result to gofer's tool-result pipeline so it reaches both the transcript/event stream AND the model's own context.
mcpconn
Package mcpconn is gofer's MCP connection manager: the consuming-side piece the SDK's optional agent-sdk-go/mcp package deliberately does not build (see that package's doc — "server configuration, credential resolution, the connection manager, and any tool-index decorator are the consuming application's job").
Package mcpconn is gofer's MCP connection manager: the consuming-side piece the SDK's optional agent-sdk-go/mcp package deliberately does not build (see that package's doc — "server configuration, credential resolution, the connection manager, and any tool-index decorator are the consuming application's job").
modelcatalog
Package modelcatalog answers "which models can THIS credential actually reach, and which one should gofer default to?".
Package modelcatalog answers "which models can THIS credential actually reach, and which one should gofer default to?".
modelmeta
Package modelmeta is gofer's single source of truth for the short, friendly display name it shows per model id.
Package modelmeta is gofer's single source of truth for the short, friendly display name it shows per model id.
permrationale
Package permrationale derives the plain-English answer to "why is this tool call being gated?" from what the guard reported about it.
Package permrationale derives the plain-English answer to "why is this tool call being gated?" from what the guard reported about it.
prompt
Package prompt composes a session's system prompt from config.Prompt's ordered file list — the replacement for cmd/gofer's old defaultSystemPrompt string constant (see docs/PRD.md's "no hardcoded prompts" constraint).
Package prompt composes a session's system prompt from config.Prompt's ordered file list — the replacement for cmd/gofer's old defaultSystemPrompt string constant (see docs/PRD.md's "no hardcoded prompts" constraint).
render
Package render turns a session's typed SDK event stream into output for a terminal client.
Package render turns a session's typed SDK event stream into output for a terminal client.
router
Package router is the production router-side remote supervisor of M6 process isolation (docs/milestones/M6-process-isolation.md, Phases 2-3).
Package router is the production router-side remote supervisor of M6 process isolation (docs/milestones/M6-process-isolation.md, Phases 2-3).
sandbox
Package sandbox provides gofer's OS-specific containment backends for the SDK's permission guard.
Package sandbox provides gofer's OS-specific containment backends for the SDK's permission guard.
skillset
Package skillset wires the SDK's skill package (SKILL.md discovery with progressive disclosure — github.com/jedwards1230/agent-sdk-go/skill) into a gofer session: resolving config.Skills into a sdkskill.Load call, applying config.Skills.Disabled (a gofer-native config concept the SDK's skill.Set has no notion of), and exposing the single tool.Tool a session's registry is wired with — the invocation surface internal/supervisor.sessionGuard registers alongside internal/decision's ask_user, matching the "gofer owns config and invocation, the SDK owns discovery" split the SDK's skill package doc calls out explicitly.
Package skillset wires the SDK's skill package (SKILL.md discovery with progressive disclosure — github.com/jedwards1230/agent-sdk-go/skill) into a gofer session: resolving config.Skills into a sdkskill.Load call, applying config.Skills.Disabled (a gofer-native config concept the SDK's skill.Set has no notion of), and exposing the single tool.Tool a session's registry is wired with — the invocation surface internal/supervisor.sessionGuard registers alongside internal/decision's ask_user, matching the "gofer owns config and invocation, the SDK owns discovery" split the SDK's skill package doc calls out explicitly.
subagent
Package subagent is gofer's `spawn_subagent` tool.Tool: the model-facing surface of agent-initiated subagent spawning.
Package subagent is gofer's `spawn_subagent` tool.Tool: the model-facing surface of agent-initiated subagent spawning.
supervisor
Package supervisor is gofer's registry of live coding-agent sessions: the M2 daemon's core.
Package supervisor is gofer's registry of live coding-agent sessions: the M2 daemon's core.
telemetry
Package telemetry is gofer's OpenTelemetry integration: traces, metrics, and slog trace-correlation built entirely off the SDK's typed Event/Op stream.
Package telemetry is gofer's OpenTelemetry integration: traces, metrics, and slog trace-correlation built entirely off the SDK's typed Event/Op stream.
tui
Package tui is gofer's minimal attach surface: an ordered transcript, an input buffer, and a status line, rendered as a projection of a session's typed Event stream (per docs/CONTRACT.md's Event/Op contract in agent-sdk-go).
Package tui is gofer's minimal attach surface: an ordered transcript, an input buffer, and a status line, rendered as a projection of a session's typed Event stream (per docs/CONTRACT.md's Event/Op contract in agent-sdk-go).
tui/layout
Package layout holds the geometry constants the TUI screens share.
Package layout holds the geometry constants the TUI screens share.
tui/testkit
Package testkit is the golden-file harness for gofer's TUI components.
Package testkit is the golden-file harness for gofer's TUI components.
tui/theme
Package theme defines the small semantic token palette gofer's TUI renders through, plus the color-profile gate that lets golden tests force deterministic, colorless output.
Package theme defines the small semantic token palette gofer's TUI renders through, plus the color-profile gate that lets golden tests force deterministic, colorless output.
tuibridge
Package tuibridge adapts the daemon's *supervisor.Supervisor to the TUI's narrow tui.Supervisor consumer interface.
Package tuibridge adapts the daemon's *supervisor.Supervisor to the TUI's narrow tui.Supervisor consumer interface.
uicopy
Package uicopy is the single home for gofer's operator-facing TUI copy: every phrase a human reads on screen, in one place, so it can be changed once instead of hunted for across 46 files.
Package uicopy is the single home for gofer's operator-facing TUI copy: every phrase a human reads on screen, in one place, so it can be changed once instead of hunted for across 46 files.
usercmd
Package usercmd loads user-authored markdown slash commands — the files a user drops in `<store-root>/commands/` (user scope) or `<cwd>/.gofer/commands/` (project scope) to turn a saved prompt into a `/command`.
Package usercmd loads user-authored markdown slash commands — the files a user drops in `<store-root>/commands/` (user scope) or `<cwd>/.gofer/commands/` (project scope) to turn a saved prompt into a `/command`.
versionskew
Package versionskew classifies how a client's build relates to the daemon it connected to.
Package versionskew classifies how a client's build relates to the daemon it connected to.
websearch
Package websearch is gofer's `web_search` tool.Tool: the model-facing projection of the SDK's provider-agnostic `search` package (M7 workstream 4).
Package websearch is gofer's `web_search` tool.Tool: the model-facing projection of the SDK's provider-agnostic `search` package (M7 workstream 4).
wirestream
Package wirestream reconstructs a session's typed event.Event stream from a running `gofer daemon`'s wire — the tui-free reconstruction core shared by github.com/jedwards1230/gofer/internal/daemonbridge (which adapts it to the TUI's roster/attach consumer interface) and, in M6, the router's supervisor-shaped worker proxy (internal/router).
Package wirestream reconstructs a session's typed event.Event stream from a running `gofer daemon`'s wire — the tui-free reconstruction core shared by github.com/jedwards1230/gofer/internal/daemonbridge (which adapts it to the TUI's roster/attach consumer interface) and, in M6, the router's supervisor-shaped worker proxy (internal/router).
worker
Package worker hosts a single-session gofer daemon — the "a worker is a single-session daemon" realization from the M6 process-isolation design (docs/milestones/M6-process-isolation.md).
Package worker hosts a single-session gofer daemon — the "a worker is a single-session daemon" realization from the M6 process-isolation design (docs/milestones/M6-process-isolation.md).
vhs
harness command
Command harness drives the real gofer TUI (internal/tui) through fixed, canned data so charmbracelet VHS can capture true rendered frames — colors, spacing, glyphs — that the plain-text Ascii golden tests can't show.
Command harness drives the real gofer TUI (internal/tui) through fixed, canned data so charmbracelet VHS can capture true rendered frames — colors, spacing, glyphs — that the plain-text Ascii golden tests can't show.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL