Goha: a local agent workbench in one Go binary
Goha is a workbench for letting a coding agent operate on a developer’s local project while keeping its actions visible. It combines a command line program with an embedded browser interface. A user can register a project, follow an agent run, approve proposed commands, inspect durable session history, and use a real terminal. The project favors local operation: its demo binds to loopback and its web assets are embedded instead of fetched from a content network.
The implementation is deliberately compact in its production dependencies. It is written mainly in Go 1.25, with a small handwritten HTML, CSS, and JavaScript interface. Cobra provides the CLI; WebSockets carry live browser updates; Unix PTYs support terminal sessions; YAML defines embedded application behavior. The four direct Go dependencies are Cobra, coder/websocket, creack/pty, and yaml.v3. The browser also embeds xterm.js and Mermaid.js. Commands run as operating-system processes with a project working directory. A model adapter speaks an OpenAI-compatible streaming API when used by the headless CLI. Linux is the stated first platform.
The core design choice is to make activity durable and reviewable. The agent loop writes typed events to an append-only JSONL store. The browser follows those events rather than acting as the only record of a run, so reconnecting can recover history. Tools are described and governed by a command policy. Proposed actions pass through an approval step before execution. The product documentation is explicit that these process and workspace controls are guardrails, not a security boundary.
A particularly clear design episode came from turning the demo into a real coding workflow. The first demo could show approval transport but did not create an application. The expanded deterministic scenario needed to write source files, yet the normal tool set had no safe write operation. The team added a project-contained atomic write_file tool and kept it inside the same proposal, approval, execution, and event path as other tools. The story for issue 020 records two more concrete failures: gofmt -w . was invalid because gofmt needs file paths, and the restricted command environment lacked Go’s cache locations. The fix was to name files explicitly and provide disposable cache directories inside the demo project. Those decisions made the demo exercise the product’s actual boundaries instead of bypassing them.
The interface then exposed a separate layout bug. Opening xterm caused a feedback loop: fitting the terminal changed its child size, which changed an automatically sized parent, which triggered another fit. The initial CSS containment still let the mount grow from 224 to 404 pixels in a mobile browser. The final change put an explicit 18 rem cap on the terminal mount, coalesced fits to an animation frame, and suppressed duplicate PTY resize messages. The browser canary was strengthened to assert that opening the terminal does not increase document height. This is a useful example of a test boundary being improved after a real user interaction revealed what the earlier width-only check missed.
The repository makes substantial use of agent-ready work artifacts: 22 numbered issue files, 17 feature contracts under docs/specs/, 18 development stories, and a Make preflight that formats code, runs go vet, checks dependencies and vendored assets, validates embedded specs, and runs tests. The codebase contains about 5,070 lines of Go across production and tests, including about 1,456 lines in 13 Go test files. PTY, browser sizing, and other external mechanisms have standalone canaries. Recent commits on 2026-08-29 and 2026-09-05 synchronize the shared Harnez conventions and agentic-loop documentation.
These artifacts show how a coding agent can work inside a bounded process: a ticket points to a design contract, acceptance checks cover a vertical slice, and a story preserves the bug or decision that shaped the implementation. The evidence supports breadth across CLI, web UI, process execution, persistence, and browser behavior. It does not prove that parallel agents were required or that a solo developer could not have built it; commit history instead shows a small team workflow with agent co-authorship and explicit verification records. The strongest lesson is practical: agentic development becomes easier to inspect when each action has an owner-facing explanation, a durable event, and a test at the boundary where failure actually appeared.
Facts
| Item | Verified facts |
|---|---|
| Stack | Go 1.25; HTML, CSS, JavaScript; Cobra; WebSockets; Unix PTY; YAML; embedded xterm.js and Mermaid.js |
| Size | 5,070 Go LOC total; 1,456 test LOC; 13 Go test files; 22 numbered issue files; 18 stories |
| Product milestones | Agentic demo 4509752 (2026-08-14); terminal layout fix 4e90a4f (2026-08-14); Harnez docs sync df46cc6 (2026-08-29), ca5134a (2026-09-05) |
| Recent activity | 2 commits in the six weeks before 2026-10-04; documentation-only and therefore quiet |
| Verification caveat | Issue 020 records that a fresh browser-canary run remained blocked by a corrupted local browser cache |