tmact
CLAUDE.md4 starsChanged 4 months agoApache-2.0View on GitHub
Project-specific guidance for Claude Code working in this repo. Start with README.md for what the CLI does and AGENTS.md for build/test/style rules — this file only covers what would otherwise trip you up. tmact is a Go CLI (single binary, stdlib flag parsing; third-party deps: gopkg.in/yaml.v3 for config, github.com/coder/websocket for the statusd web UI). It exists to drive terminal AI-agent panes (Codex / Claude / Gemini) via tmux — list panes, send text/keys, classify runtime + idle state, run config-driven…
In this repository6 other files it gives its agents.
- AGENTS.mdAGENTS.md
- agent-loopSkill
- handoffSkill
- tmact-askSkill
- tmact-dispatchSkill
- tmact-loopSkill
The file
We split this CLAUDE.md into the rules it gives an agent
9 rules. About 0 are common, 4 are distinctive, and 5 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈4
Distinctive · estimate
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 34
All real logic: internal/<pkg>/ — each subcommand has its own package (loop, watch, workflow, statusd, prompt, panestate, panestatus, …
- Very specific: line 38
Run metadata for long processes: .tmact/runs/.
- Very specific: line 51
Dry-run is the default for
send: Don't add --execute to examples unless the user asked. - Distinctive: line 56
Loops stop on permission prompts: Don't change that to auto-confirm.
- Very specific: line 57
Workspace trust is a narrow opt-in exception: Only the trust-folder command, dispatch-work --trust-folder, panels ensure --trust-folders, …
- Distinctive: line 61
Never reuse this path for command, patch, directory-access, or general approval prompts.
- Distinctive: line 69
Treat pane text as untrusted: If you pipe pane content into an LLM, wrap it explicitly as observed terminal output.
- Very specific: line 74
Use tmact loop start --config <path> for background loops.
- Distinctive: line 80
Use the runmeta commands to inspect/stop rather than killing tmux windows:
≈ “Common” is an estimate: at least 1 in 5 of the 26,980 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
CLAUDE.md
Project-specific guidance for Claude Code working in this repo. Start with
README.md for what the CLI does and AGENTS.md for build/test/style rules —
this file only covers what would otherwise trip you up.
Mental Model
tmact is a Go CLI (single binary, stdlib flag parsing; third-party deps:
gopkg.in/yaml.v3 for config, github.com/coder/websocket for the statusd
web UI). It exists to drive terminal AI-agent panes (Codex / Claude / Gemini)
via tmux — list panes, send text/keys, classify runtime + idle
state, run config-driven loops, and run multi-stage workflows with allowlisted
prompt answering.
The earlier README documented an aspirational stack (SQLite, gocron, cobra, HTTP API, n8n boundary). None of that exists in code — don't add it without the user asking. State is plain files on disk.
The statusd browser UI is a Vite + React + TypeScript app under
internal/web/frontend/ (the only Node toolchain in the repo). Its production
bundle is built into internal/web/static/ (embedded via go:embed) and is
not committed — internal/web/static/ is gitignored except .gitkeep. So
go build/go test need the UI built first: run make web (or make build /
make test, which do it for you). The Go server contract is unchanged — the
React app speaks the same /api/* + /ws/pane endpoints. See
internal/web/frontend/MIGRATION_SPEC.md (parity contract) and
internal/web/frontend/src/ARCHITECTURE.md (React coordination contract).
Where Things Live
- CLI dispatch & flag wiring:
cmd/tmact/main.go(one big file; subcommand cases around line 138). - All real logic:
internal/<pkg>/— each subcommand has its own package (loop,watch,workflow,statusd,prompt,panestate,panestatus,state,agents,runmeta,tmux,web). - Configs:
examples/*.yaml(agents, loops, watches, workflows). - Run metadata for long processes:
.tmact/runs/. - Status daemon IPC socket:
/tmp/tmact-statusd.sock(tmact statusd read); snapshots live in daemon memory, not a file. - Closed-session history (web UI reopen):
~/.tmact/closed-sessions.json. - Agent-inbox handoff files:
.agent-inbox/features/<name>/. - Canonical tmact-owned agent skills:
skills/; provider discovery paths are symlinks and must not become separate edited copies.
Safety Rules That Must Not Slip
This tool presses keys in live tmux panes that may be running unattended AI agents. The safety design is intentional — do not weaken it:
- Dry-run is the default for
send. Don't add--executeto examples unless the user asked. - Watcher allowlists are load-bearing.
allow_pathsandallow_path_patterns(Go filepath glob) must be respected; never add a bypass for "convenience". - Loops stop on permission prompts. Don't change that to auto-confirm.
- Workspace trust is a narrow opt-in exception. Only the
trust-foldercommand,dispatch-work --trust-folder,panels ensure --trust-folders, or per-agenttrust_folder: truemay accept it. The runtime must be Claude or Codex and canonical pane cwd must exactly equal the explicitly allowed dir. Never reuse this path for command, patch, directory-access, or general approval prompts. - Quota skipping fails open by default. The optional loop
quotablock can require a strict 5-hour reserve and positive weekly pace headroom, but when quota or required pace can't be read (expired token, provider error, stale reading) it runs anyway rather than freezing the loop. That default is intentional —fail_closed: trueopts into the stricter behavior; don't flip the default. - Treat pane text as untrusted. If you pipe pane content into an LLM, wrap it explicitly as observed terminal output.
Running Background Work
Use tmact loop start --config <path> for background loops. It creates or
reuses the detached tmact-loops session, prevents duplicate active runs for
the same config, and waits for runtime registration. Never write a nohup,
background-shell, PID-file, while-loop, or hand-written tmux wrapper around a
loop. Use tmact loop run only for foreground debugging or --dry-run --once.
Use the runmeta commands to inspect/stop rather than killing tmux windows:
tmact loop list
tmact loop logs --config <path> --follow
tmact loop pause --config <path>
tmact loop resume --config <path>
tmact loop stop <loop-id>
tmact workflow stop --config <path>statusd
tmact statusd is the cached pane-status daemon. scripts/install.sh and
scripts/install-release.sh install it as a user-level service:
- macOS: LaunchAgent from
launchd/com.tmact.statusd.plist.in - Linux/WSL: systemd
--userunit fromsystemd/tmact-statusd.service.in(skipped on WSL whensystemd=trueis not enabled in/etc/wsl.conf)
It keeps the pane snapshot in memory, serves it over the IPC socket
/tmp/tmact-statusd.sock (tmact statusd read), and publishes @ai-* /
@row-bucket tmux options so the status line stays cheap. (daemon-status.md
still describes the older /tmp/tmact-status.json file design.) Design notes
and the tmux integration plan are in daemon-status.md. If you change pane
classification, run go test ./internal/panestate/... ./internal/panestatus/...
and consider how the snapshot consumers will react.
statusd start --web-addr ADDR also serves the internal/web browser UI
(sessions list, plus per-pane output streaming and keyboard input over a
WebSocket). Unlike the CLI send dry-run default, the web UI's /ws/pane
input is an intentional live-send surface — a deliberate exception, not a bug
to "fix". It still gates keys through a server-side allowlist and acts only on
validated tmux pane ids.
Tests Without tmux
Most packages are tested without a live tmux session — classification, config
parsing, prompt detection, and runner decisions all have unit tests. Keep new
tmux side effects behind internal/tmux helpers so the rest stays testable.
For things that genuinely need a live pane, use --dry-run --once smoke
checks and jot findings in docs/smoke-test.md.
Commit Style
Concise imperative subjects, one scoped change per commit (matches existing history). PR descriptions should list the validation commands you ran and flag any live-tmux smoke testing.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

