T Termo
native standalone app / JSON-RPC daemon / macOS · Linux · Windows
Swavan plugin · termo

The terminal that's also your editor.

Termo is a native workspace with a real integrated terminal: a file explorer, tabbed editor, split panes, file preview, and a reusable scripts & snippets library — installed as a standalone app and shared with the Swavan host over JSON-RPC.

3 platforms — macOS, Linux, Windows
14 built-in chrome themes
1 binary: GUI app + RPC daemon
01 / bootstrap

Install & launch

Termo installs with a single command — no swavan CLI required. The installer auto-detects your OS and architecture, verifies the signed download, and wires up both the GUI app and an on-PATH termo command. Re-run it any time to update.

macOS & Linux
curl -fsSL https://raw.githubusercontent.com/swavan/plugins/main/install-termo.sh | sh
Windows PowerShell
irm https://raw.githubusercontent.com/swavan/plugins/main/install-termo.ps1 | iex
Via the swavan CLI
swavan plugin install termo
swavan launch termo
Launch & open
termo                  # current directory
termo ~/code/project   # root at a folder
termo ./notes.md       # file in the editor
Update
# re-run the installer, or via the CLI:
swavan plugin update termo
Remove
swavan plugin uninstall termo

Installing termo also adds an app launcher (macOS ~/Applications/Termo.app, a Linux .desktop entry, or a Windows Start-Menu shortcut) and a termo command next to the swavan binary. Both update on swavan plugin update and are removed on uninstall.

02 / the workspace

One window, everything in reach

A single shell: workspace bar, file explorer, tabbed editor, integrated terminal, and a status bar — rendered natively.

Panes

Recursive splits

Split the content area horizontally or vertically into a tree of panes. Every leaf is a unified tab group that mixes editor files and terminals; drag a tab to another pane to move or re-split it.

Terminal

A real PTY shell

Each terminal hosts your $SHELL in a pseudo-terminal with full xterm-256color, scrollback, mouse selection, copy/paste, and even Sixel inline graphics. Drop a file onto a terminal to type its quoted path.

Explorer

Lazy file tree

Browse, create, rename, copy, move, and delete files from the sidebar with drag-and-drop and a right-click menu. Sync to Terminal re-roots the tree at the focused shell's live working directory.

Editor

Tabbed editing

Open files in editable tabs with selection, undo/redo, and save. Each split editor scrolls independently; rendering is virtualized so large files stay fast.

Preview

Inline file preview

Images and SVGs render in-pane; PDFs and HTML open in your OS default app via a preview card. Text-based kinds toggle between rendered preview and source.

Library

Scripts, snippets & notes

Keep reusable command snippets, runnable scripts, and Markdown notes in the explorer accordion. Scripts carry a danger flag plus a heuristic destructive-command check, with a confirmation gate before running.

Themes

14 chrome themes

Neutral Dark / Midnight / Light, Evergreen, and five hue families each in light and dark. The terminal's base palette follows the active theme. Switch from the status-bar pill or Settings → Appearance.

Glyphs

Emoji, symbols & icon fonts

Monochrome fallback fonts cover emoji, dingbats, technical symbols, and the Private-Use areas where terminal icon glyphs live — so TUIs render without tofu. Drop a font onto the window to swap the grid font live.

Highlighting

Optional syntax addon

Syntax highlighting is a runtime-loaded addon, kept out of the core to stay lean. With none installed, rendering is identical plain text at zero cost. Toggle it in Settings → Appearance.

03 / keyboard

Shortcuts

Editor shortcuts use Cmd on macOS, Ctrl elsewhere. The app chords marked — sidebar, new terminal, and terminal copy/paste — use Cmd on macOS but Ctrl+Shift on Linux & Windows, leaving Ctrl-C as SIGINT in the terminal.

Toggle the sidebar Cmd B
Open a terminal in the focused pane Cmd J
Copy / paste (terminal) Cmd C / V
Save the active fileCmd S
Undo / redoCmd Z / ⇧Z
Select allCmd A
Cut / copy / paste (editor)Cmd X·C·V
Rename a terminal / workspace tabDouble-click

More controls live in the chrome: the workspace-bar gear opens Settings (Appearance · Shortcuts · Scripts), the status bar has Explorer-toggle, New-Terminal, and theme-cycle pills, and every pane has its own add / split-vertical / split-horizontal buttons.

04 / command line

Manage the library headlessly

Termo is GUI-first, but the same binary manages scripts, snippets, and notes from the shell — no window opens. Changes show up in the GUI after a refresh, and vice versa.

Open
termo                  # GUI at the cwd
termo <dir>             # root at a folder
termo <file>            # file in the editor
termo open <path>       # force path parse
Scripts
termo --script --append <name> "..."
termo --script --edit   <name> "..."
termo --script --remove <name> -y
termo --script <name> exec   # danger → -y
Snippets
termo --snippet --create <name> "..."
termo --snippet <name> exec   # run in $SHELL
Notes
termo --note --create <name> "..."
termo --note --append <name> "..."
termo --note --edit   <name> "..."
termo --note --remove <name> -y   # not runnable

File names are validated (no path separators or ..), so a CLI caller can't escape the library directories. --remove refuses without -y/--yes, and running a script flagged dangerous — manually or by the destructive-pattern heuristic — also requires -y, mirroring the GUI's confirmation dialog.

05 / integration

JSON-RPC daemon

Run with --socket, termo exposes its scripts & snippets library to the Swavan host (or any client) over NDJSON JSON-RPC 2.0 — a Unix socket on macOS/Linux, a named pipe on Windows. The GUI and daemon never share a process.

Methods
status
library.list      # ?kind = snippet|script
library.get       # { kind, name }
library.write     # mode: create|overwrite|append
library.remove
library.run       # no danger gate — check first
library.set_meta  # scripts: danger / info
Example session (NDJSON)
→ {"id":1,"method":"status"}
← {"jsonrpc":"2.0","id":1,"result":{"name":"termo",…}}
→ {"id":2,"method":"library.run",
   "params":{"kind":"snippet","name":"hi.sh"}}
← {"jsonrpc":"2.0","id":2,"result":
   {"exit_code":0,"stdout":"hi\n","stderr":""}}

library.run has no danger gate — a consumer should read danger / auto_danger from library.list and confirm before invoking it. The full wire contract — message shapes, error codes, and every field — ships with the plugin as docs/daemon-protocol.md.