traa.sh logo

traa.sh

Agent-compatible GPU terminal

Drive sessions headlessly with traash agent — query pane text, send input, wait for command completion, and subscribe to events over a JSON mux API. Optional OpenGL GUI, tmux-style mux, Lua themes, and plugins when you need them.

Download

Latest release

traa.sh v0.2.0

Relocatable tarballs — extract and run ./bin/traash. Includes the agent CLI, encrypted mux sessions, headless server, and bundled Lua assets. No system install required.

Also on GitHub Releases · prefer to compile? Build from source

# quick start after download
tar xzf traash-0.2.0-*.tar.gz
cd traash-0.2.0-*
./bin/traash --server --create dev
./bin/traash agent state dev

For automation

Built for agents

External scripts and AI agents attach to a running mux host — no GUI, no ANSI parsing. State is JSON; idle detection uses shell OSC 133; cwd and title come from OSC 7/0.

Quick start: traash --server --create devtraash agent state deveval "$(traash shell-init bash)" in your shell rc → traash agent send + traash agent wait. Read-only attach can query and subscribe but cannot send input.
traash --server --create dev &
traash agent state dev
traash agent send dev --pane 1 --literal $'make\n'
traash agent wait dev --pane 1 --timeout 30000
traash agent subscribe dev --emit-output

Full agent API reference

Map

Guides

01 — Config

User configuration

Defaults load from lua/defaults/config.lua, then merge with ~/.config/traash/config.lua. Settings writes the same file.

Load order: built-in defaults → user config.lua → optional leader / keys applied onto keymap defaults (new actions keep shipping binds if an old save omits them).
-- ~/.config/traash/config.lua
config = {
  theme = "tokyo-night",
  status_bar = "pills",
  default_layout = "",  -- e.g. "dev"; empty = single pane
  font = "Hack Nerd Font Mono",
  font_size = 14,
  text_rendering = "natural", -- natural | legacy | linear
  opacity = 1.0,
  cursor_style = 1,  -- 0 block, 1 beam, 2 underline
  scrollback = 5000,
  plugins = {
    "git-status", "cwd-short", "battery",
    "ssh-hint", "notify-on-bell",
  },
  leader = { key = 66, mods = 1 },
  keys = {
    { action = "split_v", key = 53, mods = 2, prefix = 1 },
  },
}
return config
FieldTypeNotes
themestringTheme id without path
status_barstringpills, tmux, minimal, powerline, dev, compact, centered
default_layoutstringApplied on startup unless attaching to an existing session
fontstringFontconfig family; Settings lists monospace faces
font_sizenumber8–48 px before content-scale
text_renderingstringnatural (default), legacy, or experimental linear; compare modes
opacitynumber0.3–1.0
cursor_styleint0 block · 1 beam · 2 underline
scrollbackintHistory lines
pluginsstring[]Max 16 ids under plugins/examples/<id>/
leadertable{ key, mods } — ctrl=1 shift=2 alt=4 super=8
keystable[]{ action, key, mods, prefix }

Action names

split_hsplit_vpane_next pane_leftpane_downpane_up pane_rightzoomnew_window next_windowprev_windowgoto_window detach reload_configcommand_palettetheme_cycle status_cyclefont_increasefont_decrease democopy_mode copypastesearch settingsshortcutslayout_picker overview quit

status_cycle and demo have no default chord (command palette). copy_mode is reserved (prefix [) and currently has no runtime handler.

Rendering

Accurate colors, text you can tune

The renderer supports the full 256-color palette and RGB colors. Default foreground and background colors follow your theme, while explicit ANSI colors keep their own palette entries.

Available in source builds: these rendering updates are newer than the v0.2.0 downloads above. Build from source to try them.

Open Preferences → Appearance → Font → Text rendering with Ctrl-Shift-, to compare modes. Apply updates the running terminal; Save also writes your choice to config.lua.

ModeBehavior
naturalDefault. Preserves FreeType’s glyph coverage for smooth text edges.
legacyRestores the previous sharpening curve for comparison.
linearExperimental blending in linear light. Requires an sRGB framebuffer and full opacity; otherwise it uses Natural rendering.

Text weight varies with your font, theme, and display. Terminal glyphs and Preferences fonts are rasterized at the framebuffer’s scale. Fractional font sizes are retained when saved, and long tab titles are shortened to fit.

Tabs, menus, Preferences, selections, and search highlights use the active theme. Both dark and light themes can customize these colors in a theme file.

02 — Layouts

Saved session layouts

Lookup: ~/.config/traash/layouts/<name>.lua then lua/layouts/<name>.lua (user names override bundled).

Picker: Ctrl-Shift-L (action layout_picker). Enter applies · s saves · Del deletes a user layout · Esc closes. Apply recreates tabs/panes with fresh shells — geometry only. default_layout is skipped when using --attach.
singleh-split v-splitdev
layout = {
  name = "dev",
  windows = {
    {
      name = "1",
      active = 1,
      panes = {
        { x = 0, y = 0, w = 1, h = 0.5 },
        { x = 0, y = 0.5, w = 1, h = 0.5 },
      },
    },
  },
}
return layout

03 — Themes

Color themes

Lookup: ~/.config/traash/themes/<name>.lua then lua/themes/<name>.lua.

tokyo-nightcatppuccin-mocha draculagruvbox-dark nordone-dark solarized-darksolarized-light rose-pinegithub-dark traash-dark

Required shape

Return a table of hex #RRGGBB colors. Missing keys fall back. ansi[0..15] defines the theme’s ANSI palette; indices 16–231 use the standard color cube and 232–255 use the grayscale ramp.

Live reload

Enable autoreload-theme, or call traash.reload_theme() from a plugin.

foreground and background set the terminal defaults. selection_fg and selection_bg control selected text. Existing tab, pane, and status colors also style the surrounding interface.

Optional fieldDefault
ui_surface, ui_hover, ui_mutedDerived from the theme’s background and foreground for controls, hover states, and secondary text.
search_fg, search_bgThe selection colors.
search_current_bgansi[3].
search_current_fgBlack or white, chosen for contrast with the current-match background.

04 — Status bars

Status bar styles

pillspowerlineminimal tmuxdevcompact centered

pills, minimal, powerline, dev, and tmux read plugin chips from ctx.seg.*. compact and centered ignore plugin segments.

ctx fieldMeaning
sessionAttached mux session name
windowActive window id
titleActive pane title (OSC 0/2)
cwdOSC-7 cwd when set
hostHostname
timeHH:MM local
seg.*Plugin segment strings

06 — Encrypted sessions

Dual-password access

Optional encrypted sessions store layout + terminal screen on disk at ~/.local/share/traash/sessions/<name>.tsn. Two passwords control access: write (read + type) and read-only (view only).

Host / client: traash --server [--bind ADDR:PORT] runs a persistent mux host. GUI --attach becomes a client when the Unix socket is already up. See getting started → encrypted sessions.
FlagRole
--create NAME --encryptCreate encrypted snapshot; prompt for both passwords
--attach NAMEUnlock with either password; role follows the password
--read-onlyForce observer mode even if you know the write password
--host / --portAttach over TCP (no TLS in v1)
--password-fd FDPassword from fd instead of tty (never argv)

Read-only clients show a status-bar badge. The server blocks PTY input and mutating mux actions for them. Copy, scroll, and local overlays still work.

07 — Lua plugins

Plugin API for coding agents

For terminal automation, use the Agent API and llms.txt. For Lua customization, see the plugin guide — do not invent host APIs.

Invariant: Plugins cannot draw UI. Use segments, hooks, notify, clipboard override, or run_action. Desktop notifications are transient (3.5s) and replace the previous traa.sh notification. on_bell fires only while the window is unfocused.

Do

Ship files under lua/ or ~/.config/traash/. Keep segment work cheap (~2 Hz). Restart after plugin code changes.

Do not

Assume a user plugin directory, plugin hot-reload, sandboxing, or that reload_config reloads plugins.