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.
Build
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 ghostty backend by default. 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 runChecks
CI runs these on every pull request. Run them 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. There is no golangci-lint config. If you run a linter locally, keep unrelated lint fixes out of your pull request.
The full suite is slow and uses every core. To leave the machine usable while it runs:
nice -n 10 go test ./... -timeout 20mOther test suites
go 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 ./... | A real tuios in a real PTY, checked on screen. A separate Go module |
| Control plane | go test -tags e2e ./e2e/... | Real daemons driven through the CLI |
| ghostty backend | PKG_CONFIG_PATH="$PWD/.ghostty-vt/native/pkgconfig" go test -tags ghostty -count=1 -short ./internal/vt/ ./internal/session/ ./internal/terminal/ | The libghostty-vt emulator |
| Differential | go test -tags differential ./internal/vt/ -run TestDifferential | The emulator against tmux. Needs tmux |
| Browser | cd clienttests && npm install && npm test | tuios-web in the system Chromium, with Playwright |
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.
Writing tests
- Put tests in
*_test.gonext to the code. - Prefer table-driven tests with
t.Runsubtests. - Name benchmarks
Benchmark*. - For emulator changes, add a case to the conformance corpus in
internal/vt/. The repository'sAGENTS.mdexplains how it works.
func TestFeature(t *testing.T) {
tests := []struct {
name string
in string
want string
}{
{"empty", "", ""},
{"word", "abc", "ABC"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := Feature(tt.in); got != tt.want {
t.Errorf("Feature(%q) = %q, want %q", tt.in, got, tt.want)
}
})
}
}Code style
- 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.
Pull requests
-
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.
Reporting issues
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.
Security issues
Do not open a public issue for a vulnerability. Email the maintainer as described in SECURITY.md.