This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
gotmuxcc is a Go library that provides a drop-in replacement for gotmux. It mirrors gotmux's public API but internally uses a persistent tmux control-mode (tmux -C) connection instead of spawning a new tmux process per command. Module path: github.com/atomicstack/gotmuxcc.
There is a context/ directory containing project-specific context files (todo.md, done.md, scratchpad.md, context.md). Read these at the start of any session for current project state and pending work. Update todo.md and done.md when completing work items.
The tmux source code is available at /Users/matt/git_tree/tmux for reference when working on control-mode protocol details.
Every new version of gotmuxcc released to GitHub must be pulled in by its consumers. The primary (and currently only) consumer is tmux-popup-control — I own both projects, so there's no coordination needed beyond bumping the dependency there.
Whenever you cut/tag/release a new version (e.g. git tag vX.Y.Z && git push --tags, or otherwise publishing a version consumers resolve via go get),
print a coloured reminder to the terminal so it doesn't get missed, e.g.:
printf '\033[1;33m⚠ reminder: bump gotmuxcc in tmux-popup-control — run `make update-gotmuxcc` there\033[0m\n'tmux-popup-control has a make update-gotmuxcc target for the bump; use that
rather than invoking go get / go mod tidy directly. Keep the reminder text
lowercase.
Whenever a new tag is pushed, always cut a matching GitHub release for it —
a tag alone is not enough. Consumers resolve versions via go get, but a
tag-only version has no human-readable changelog, so every vX.Y.Z tag must
have a corresponding gh release published. Do not leave tags without a
release; if you notice tags that are ahead of the latest release, back-fill
releases for them.
Each release body must contain a summary of the improvements and fixes in that
version. Derive it from the tag message and the commits in the range
vPREV..vX.Y.Z (git log --no-merges vPREV..vX.Y.Z). Follow the existing
release notes style: a short title line describing the theme, grouped
sections (e.g. fixes / tests / caveats), reference the relevant commit hashes,
and end with the go get github.com/atomicstack/gotmuxcc@vX.Y.Z upgrade
snippet. Keep the prose lowercase per the general rules. Do not hard-wrap
the release-notes prose — GitHub renders it as markdown, so each paragraph and
list item must be a single unbroken line; hard wraps cause the text to wrap
early on GitHub. Create the release with gh release create vX.Y.Z --title vX.Y.Z --notes-file <file>.
make unit # Fast unit tests (no tmux required)
make integration # Full suite including integration tests (requires tmux)
make cover # Generate coverage report to coverage.out
make clean # Remove local .gocache and .gomodcache
# Run a single test
go test ./gotmuxcc -run TestName
go test ./internal/control -run TestName
# Integration tests require the env var:
GOTMUXCC_INTEGRATION=1 go test -tags integration ./...The Makefile pins GOCACHE and GOMODCACHE to local directories (.gocache/, .gomodcache/) for sandbox compatibility. The test scripts in scripts/ do the same.
-
Public API (
gotmuxcc/) —Tmuxstruct is the entry point. Methods onTmux,Session,Window, andPanemirror the gotmux API. Created viaNewTmux(socketPath)orDefaultTmux(). -
Query Builder (
gotmuxcc/query.go) — Fluent builder that assembles tmux commands with format-variable (#{...}) substitution; each value is length-prefixed (#{n:var}:#{var}, netstring style) so replies decode unambiguously whatever the values contain. Parses multi-field responses back intoqueryResultmaps. -
Router (
gotmuxcc/router.go) — Concurrency-safe command dispatcher. Tracks pending/inflight commands, parses%begin/%end/%errorcontrol-mode frames, correlates responses, and hands async%-prefixed events to a sink. Runs a read loop goroutine and a transport-done observer. The sink is the notification hub ingotmuxcc/notifications.go, which fans events out toNotifications()subscribers with per-subscriber buffers and overflow accounting;gotmuxcc/reconnect.goredials while subscribers exist. -
Control Bridge (
gotmuxcc/control_bridge.go) — Wires thecontrolTransportinterface to the concreteinternal/control.Transport. Opens the connection withtmux -C -N attach-session: there is no discovery step, and-Nmeans the client can never start a server. -
Control Transport (
internal/control/transport.go) — Launchestmux -Cas a subprocess, manages stdin/stdout/stderr pipes, and exposes a line-oriented channel interface (Send,Lines,Done,Close).
controlTransport(defined ingotmuxcc/tmux.go) — abstraction over the tmux pipe; satisfied byinternal/control.Transportin production and by fake/recording transports in tests.Dialer/DialerFunc— factory forcontrolTransport; injectable viaWithDialer()constructor option for testing.
- Unit tests use fake control transports (recording/simple fakes) that validate issued commands without invoking tmux. These live alongside source files as
*_test.go. - Integration tests (guarded by
GOTMUXCC_INTEGRATION=1and//go:build integration) spin up isolated tmux servers with temporary sockets. They create temp directories under the repo root (.testtmp/) so filesystem writes stay in-sandbox. - Test helpers live in
internal/testutil/.
Set GOTMUXCC_TRACE=1 (or component names like router,transport) to enable debug logging. Trace output goes to gotmuxcc_trace.log in the repo root (override with GOTMUXCC_TRACE_FILE).
gotmuxcc/types.go— All public struct definitions (Session, Window, Pane, Client, Server, option types)gotmuxcc/variables.go— tmux format variable name constantsgotmuxcc/helpers.go— Shared parsing utilities (atoi, isOne, parseList, etc.)gotmuxcc/options.go— Option get/set/delete helpers across session/window/pane scopesdocs/api_inventory.md— Tracks one-to-one API compatibility with gotmux