Files
patterm/CLAUDE.md

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-vt emulators 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, including mcp-stdio and debug-harness subcommands.
  • internal/app: TUI/session state, palette, child lifecycle, rendering, MCP tool host.
  • internal/pty: thin wrapper around github.com/creack/pty.
  • internal/vt: libghostty-vt backed 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 in internal/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, or opencode, gate it behind an explicit opt-in environment variable. CI scenarios should use fake scripts/presets.