3.7 KiB
Agent Guide
Project Overview
patterm is a Go terminal orchestration TUI. It runs as one foreground process that owns:
- the host TUI chrome
- child PTYs
- headless
libghostty-vtemulators for rendered-grid snapshots - the in-process MCP server
- per-project scratchpads and command-preset trust state
There is no daemon or attach/detach model. Closing the patterm process tears down every child process it spawned.
Core packages:
cmd/patterm: main binary, includingmcp-stdioanddebug-harnesssubcommands.internal/app: TUI/session state, palette, child lifecycle, rendering, MCP tool host.internal/pty: thin wrapper aroundgithub.com/creack/pty.internal/vt:libghostty-vtbacked emulator wrapper.internal/mcp: JSON-RPC MCP socket server and tool surface.internal/preset: XDG-loaded agent/process presets.internal/trust: per-project command-preset trust grants.internal/harness: black-box PTY/MCP test harness.
Build Prerequisites
The normal build depends on the vendored libghostty-vt static library and headers under third_party/libghostty-vt/install.
If that install tree is missing, run:
make deps
This fetches the pinned Ghostty commit and builds libghostty-vt with Zig. The Makefile currently requires zig on PATH with a compatible version.
Common checks:
go test ./...
go build -o ./bin/patterm ./cmd/patterm
Harness Testing
The harness is the preferred way to test patterm end-to-end without a human watching a terminal.
It starts a real patterm child process in a PTY, feeds its output through the same internal/vt emulator used for child panes, and talks to the child patterm process over its per-PID MCP Unix socket. Scenarios are JSON files under:
internal/harness/scenarios/
Useful harness commands:
go test ./internal/harness/...
go test -race ./internal/harness/...
go test -count=10 ./internal/harness/...
Run one scenario through the CLI:
go build -o ./bin/patterm ./cmd/patterm
./bin/patterm debug-harness --scenario internal/harness/scenarios/spawn_process_via_palette.json
Harness scenarios create hermetic XDG/config/data/runtime directories, write scenario-local presets and fake scripts, and set PATTERM_HARNESS=1. They must not read or write the user's real patterm config.
Failure artifacts are written under:
internal/harness/.artifacts/
That directory is gitignored. Artifacts include rendered grid text, raw PTY bytes, serialized VT state, MCP snapshots, the resolved environment, and an annotated scenario.
Harness Environment Notes
The harness and patterm MCP server create Unix sockets and spawn PTYs. In restricted sandboxes this can fail with errors such as:
listen unix ... setsockopt: operation not permitted
When that happens, rerun the harness tests or debug-harness command in an environment that permits Unix sockets and PTYs.
When testing a specific binary, set:
PATTERM_BIN=/absolute/path/to/patterm go test ./internal/harness/...
Without PATTERM_BIN, harness tests build the current checkout once into a temp location and test that binary.
Development Notes
- Prefer existing package boundaries. MCP protocol shapes live in
internal/mcp; runtime behavior usually belongs ininternal/app. - Keep terminal rendering changes covered by focused app tests or a harness scenario.
- Do not let child PTY output own host chrome. The app owns tab bar, sidebar, status line, and palette.
- Command-preset trust must be seeded before starting patterm in tests because the app opens the trust store during startup.
- If a scenario needs external CLIs such as
claude,codex, oropencode, gate it behind an explicit opt-in environment variable. CI scenarios should use fake scripts/presets.