Repository navigation
Contributing
Build TUIOS from source, run the tests, and send a pull request.
Contributions are welcome: bug reports, fixes, tests and documentation. This page covers building from source, the checks CI runs, and how to send a change.
The tuios repository has an AGENTS.md with a package map and the test commands. Read it before a larger change.
You need Go 1.26.6 or later (the version in go.mod), Git, and a Nerd Font to see the icons. --ascii-only works without one.
git clone https://github.com/Gaurav-Gosain/tuios
cd tuios
go build -o tuios ./cmd/tuios
go build -o tuios-web ./cmd/tuios-web
./tuios --standalone --debug--standalone runs TUIOS without the daemon, which is simpler while you work on the UI. Without it, TUIOS starts or reuses a daemon from the same binary.
The default build uses the pure Go terminal emulator and needs no C toolchain. The libghostty-vt backend uses cgo and needs Zig 0.16 or later:
./scripts/ghostty-lib.sh
PKG_CONFIG_PATH="$PWD/.ghostty-vt/native/pkgconfig" go build -tags ghostty ./cmd/tuios./scripts/install.sh builds and installs the pure Go emulator by default; ./scripts/install.sh ghostty builds the libghostty-vt backend. See docs/ghostty-vt.md in the repository for details.
With Nix:
nix develop # development shell
nix build # build the package
nix run # build and runCI runs these on every pull request and every push to main. Run the first set before you push:
gofmt -l . # must print nothing
go vet ./...
go build ./...
go test ./... -count=1 -timeout 20mCI also checks that go.mod is tidy in both the root module and e2e/tui, and runs go test -race ./... every night.
Two more workflows run on every pull request:
-
Lint (
.github/workflows/lint.yml):golangci-lintv2 with the repository's.golangci.yml(the standard linters plusgosec),govulncheck ./..., andgo vet ./...withGOOSset todarwin,windows,freebsdandopenbsd. Rungolangci-lint run ./...locally. A finding that is wrong for one line gets a//nolintcomment with its reason on that line. -
Binary size (
.github/workflows/binary-size.yml):scripts/binary-size.shbuilds tuios the way the release does (CGO_ENABLED=0,-trimpath,-ldflags "-s -w") for linux/amd64 and darwin/arm64 and fails when a binary is over its budget. Run the script locally to see the size and the room left. To raise a budget, measure the new size on the Go versiongo.modnames and say in the commit what grew and why.
The full suite is slow and uses every core. To leave the machine usable while it runs:
nice -n 10 go test ./... -timeout 20mgo test ./... from the root does not run these:
| Suite | Command | Covers |
|---|---|---|
| End-to-end TUI | cd e2e/tui && TUIOS_E2E=1 go test -count=1 -timeout 40m . |
A real tuios in a real PTY, checked on screen. A separate Go module. Set TUIOS_E2E_BIN to a built binary, or the suite builds one |
| Control plane | go test -tags e2e ./e2e/... |
Real daemons driven through the CLI |
| Go libraries (Added in v0.10.0) | go test ./vt/... ./swatch/... ./progstatus/... |
tuios.dev/vt, tuios.dev/swatch and tuios.dev/progstatus. Each is a Go module of its own, so ./... from the root stops at it |
| ghostty backend | PKG_CONFIG_PATH="$PWD/.ghostty-vt/native/pkgconfig" go test -tags ghostty -count=1 -short ./vt/ ./internal/session/ ./internal/terminal/ ./internal/app/ ./internal/input/ ./cmd/tuios/ |
The libghostty-vt emulator and the packages whose tests link it. go build -tags ghostty ./... alone runs none of these tests |
| Differential | go test -tags differential ./vt/ -run TestDifferential |
The emulator against tmux. Needs tmux
|
| Browser | cd clienttests && npm install && npm test |
tuios-web in the system Chromium, with Playwright |
Warning
Without TUIOS_E2E=1 the end-to-end suite skips every test and reports success. Always pass -count=1 too: a cached result can survive a change of binary. Run this suite if you change rendering, input handling or the daemon protocol.
The repository prefers end-to-end tests: a real tuios binary against real daemons, in e2e/tui. The rules, from its AGENTS.md:
- Write the test first, not after the code. If you must test a part in isolation, first write down the ways it can fail.
- A test that claims to cover a bug must fail on a build with the fix removed.
e2e/tui/NEGATIVE_CONTROLS.mdrecords those runs. - An end-to-end test should leave an artifact you can check again, such as a screenshot or a capture.
- A unit test stays only when it catches a real bug the end-to-end suite misses: emulator conformance, fuzz targets, wire compatibility, security boundaries, deterministic race regressions and performance budgets.
For emulator changes, add a case to the conformance corpus in vt/, the tuios.dev/vt module. Unit tests that stay live in *_test.go next to the code, use t.Run subtests, and name benchmarks Benchmark*.
- Follow Effective Go and run
gofmt. - Every package has a package comment, and exported names have doc comments.
- Wrap errors with context:
fmt.Errorf("failed to load config: %w", err). - Keep functions small and testable.
-
Fork the repository and create a branch:
git checkout -b fix/close-last-window
-
Make the change, with tests. Update the docs if behavior changes.
-
Commit with a conventional commit prefix:
Prefix Use for feat:A new feature fix:A bug fix docs:Documentation refactor:A change that does not alter behavior test:Tests chore:Maintenance git commit -m "fix: panic when closing the last window" -
Push and open a pull request. The template asks what changed, why, and how you tested it. Include a screenshot or recording for UI changes, and link the related issue.
-
Address review comments. Keep commits focused, and rebase on
mainif asked.
Open an issue on GitHub. The bug template asks for:
- the TUIOS version (
tuios --version), - your platform and how you installed TUIOS,
- steps to reproduce, and what you expected,
- logs, if you have them (
tuios logsfor the daemon,tuios --debugfor the client).
Use Discussions for questions and ideas. Issues labeled good first issue are a good place to start.
Note
Security issues
Do not open a public issue for a vulnerability. Email the maintainer as described in SECURITY.md.
- Architecture: How the code is organized
- Library Usage: Embed TUIOS in your own program
- Introduction
- Getting Started
- Learn tuios, hands on
- Keybindings
- Hints
- Finding a Pane
- Links
- TUIOS vs Others
Windows and Layout
Sessions and Machines
Agents
- Agents
- Inbox and Review
- Agent Messaging
- Program Status
- Worktrees
- Checkpoints
- Ship
- Push Notifications
- Turn Off Agent Features
Scripting
Recording
Reference