Skip to content

About

A small, hackable browser terminal for your coding agents. OpenCode, Codex, DeepSeek Harness. Your machine. Your tmux sessions.

Topics

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

Agent Perch: tmux, with a window seat

A small, hackable browser terminal for your coding agents.
OpenCode, Codex, DeepSeek Harness, Pi. Your machine. Your tmux sessions.

SINGLE-USER PREVIEW   LINUX + TMUX   LOCAL ENGLISH SPEECH   MIT

First run · Local speech · The manual · What's verified · Contribute

For checking on the agent from the couch, without bringing the entire laptop to the couch.

Perch puts your tmux sessions in a browser. Attach to something already running, or give it a directory and start an agent there. Type, paste, switch sessions, close the tab. The tab can leave. The agent keeps working. An exited agent or a reboot is different; Perch does not restart the work.

Perch's session manager with isolated demo sessions, search, and confirmed kill controls

Warning

No built-in login. Anyone who can reach Perch can control your terminals. Keep it on localhost or behind private HTTPS and access control. Tailscale Serve, not Funnel. Run it as your normal user, never root. Security details.

Run It

You need Linux, Bun 1.3.10+, and tmux 3.3+. Install and authenticate whichever agent CLI you want to launch. Existing tmux sessions work without installing another agent.

Nix users can use nix build / nix run from the checkout; see the pinned package and external state. Versioned releases provide a prebuilt runtime archive.

From the checkout:

bun install --frozen-lockfile
bun run build
bun run start

Open http://localhost:4310/. All four agents launch as native CLIs. No separate OpenCode API server, database integration, or session metadata to set up.

New session takes a path, not a pre-registered project. /work/app, ~/src/app, and relative paths all work. Check the box to create a missing directory. Leave the name blank to use the directory name. No repository scaffolding or surprise git init.

Want it running after you log out? Stop the foreground server, then use the systemd installer. One service, an existing .env left alone, and no agent server installed behind your back.

For another device, follow the private HTTPS setup. Use a browser tab or install from your browser's menu. The host must remain reachable; Perch does not maintain an offline copy of the app.

What You Get

OpenCode Codex DeepSeek Harness
Native terminal in the browser Yes Yes Yes
Start in any accessible directory Yes Yes Yes
Starting prompt from the form Yes Yes Enter it in the TUI
Turn-finished / attention indicators Native events Native notifications Native events
Compact / continue, approval controls Use the TUI Use the TUI Use the TUI
Dictation and image paste Yes Not yet Not yet

Pi also launches as a native TUI with literal starting prompts, optional lifecycle indicators, and non-submitting image file references (not automatic image attachments). Pi setup and limits.

Session search, pins, physical keyboards, mobile touch keys, and supported clipboard text writes work across the terminal layer. Ctrl+Alt+S opens the switcher. Your agent's approval controls stay in its own TUI; Perch doesn't turn them off.

On phones, copy and paste icons sit beside the microphone, with arrows and Enter on their own row on narrow screens. Copy opens a selectable snapshot of the visible terminal. Paste opens an editable clipboard preview and waits for confirmation without pressing Enter. Native Copy/Paste menus remain available if the browser blocks clipboard access. Clipboard controls.

The red X beside each session opens a confirmation before killing it. Closing a browser tab still leaves the agent running; confirming Kill session does not.

New OpenCode/Codex/DSH sessions, and Pi sessions with PI_ATTENTION=1, have native attention indicators that stay unread until Mark seen. OpenCode and DSH expose lifecycle events; Codex notifications produce generic Needs attention indicators. Observation does not require an open viewer. Existing uninstrumented agents are left alone. No status is not a claim that an agent is idle. Details and limits.

The compact, flat UI uses a locally served Proggy Clean font, with larger touch controls on phones. The terminal keeps its own readable, adjustable font. No web-font CDN.

Backend setup covers authentication and executable paths. DeepSeek uses dsh-tui, not an imaginary deepseek command.

Desktop and pocket-sized terminals

These captures use the current UI with isolated, inert fixtures. No provider calls or real conversations.

The desktop terminal The mobile terminal with compact clipboard icons and a fully visible navigation-key row

Talk to It

The optional speech-to-text model runs on the device holding the microphone. On your phone, that means your phone, not the server or a transcription API.

We use Moonshine v2 Medium English, a 245M-parameter model with 8-bit quantized weights, through Moonshine's multithreaded WASM/CPU runtime in a browser worker. This is the accuracy-first option, not the smallest download. There is no cloud fallback, WebGPU requirement, or browser Web Speech service.

microphone --> Moonshine in your browser --> OpenCode prompt
               audio stays here             review, then Enter

To enable it, run these on the host:

bun run voice:prepare
bun run build

Preparation downloads the pinned English model from Moonshine and copies the pinned runtime into locally served assets. The browser fetches roughly 304 MiB of model/runtime files from your host on first use; model files are cached. All runtime URLs are same-origin. Recorded audio is never uploaded by Perch. The server supplies the cross-origin-isolation headers required by threaded WASM; a reverse proxy must preserve them.

First use remembers speech in this browser. On later visits, Perch prepares it in the background without opening the microphone. Turn off Settings > Prepare speech on startup to keep loading manual; dictating won't override that choice. Reloading still requires model initialization, but subsequent dictation reuses the warm model.

Tip

Prepare once, dictate repeatedly. Startup is the expensive part. Use Settings > Prepare speech before your first recording. Measured cold/warm timings are smoke-test results, not a phone-performance promise.

Dictation currently pastes into OpenCode only, without submitting. The text goes to the host at that point; if you submit it, it can go to the agent's model provider. Local transcription does not make the rest of the agent local.

Recordings stop at 60 seconds. Transcription is English-only, regardless of browser language. Check the transcript, especially code identifiers and file paths. How capture and cancellation work.

Mess With It

Perch is meant to be a small tool you can understand and change. The basic path is:

browser / xterm.js  <-- WebSocket -->  Bun / PTY  <-->  tmux  <-->  agent

tmux owns the sessions. Perch launches a CLI and forwards terminal input/output; the agent owns everything else. No conversation discovery, compaction engine, or operation journal. Native viewer notifications replace pane polling; one server-owned loop reconciles attention observers. The manager and switcher share one session list.

If you want to change... Start here
The UI, dialogs, or colors src/App.tsx, src/style.css
Session refreshes and mutations src/sessions.ts
Terminal rendering, selection, and text paste src/Terminal.tsx
Routes, PTYs, and session creation server/index.ts
Agent commands and recognition server/backends.ts
Native status and attention server/agent-status.ts, integrations/
Viewer notifications and clipboard server/clipboard.ts
tmux and directory handling server/tmux.ts
Microphone capture / local inference src/voice.ts, src/voice.worker.ts
Speech model and downloaded files scripts/prepare-voice.ts
bun run check
bun test --no-env-file
bun run build

Tests use disposable directories and separate tmux sockets. For interactive development, do the same: use a different port, TMUX_SOCKET, and STATE_DIR. Your actual work is a poor test fixture. Development setup / Contributing.

Minimal scope, not zero bytes. xterm, React, and the optional speech runtime still have weight. Speech loads on demand or at startup after you enable it; its runtime and model assets are copied into the build only after voice:prepare. We haven't measured idle memory or battery use, so there is no heroic performance claim here.

The Small Print

Early software, used on a real host. Linux ARM64 and x86-64 have been checked; native Windows/macOS servers have not. Browser emulation is not the same as testing every phone. Sessions survive a disconnected browser, not a host reboot or an exited agent. Test results and limits.

License

MIT. Fork it, change it, give the bird a different hat. Keep the copyright and license notice.

Third-party libraries and speech assets retain their own licenses. Release checklist.

Proggy Clean is by Tristan Grimmer, distributed under its MIT notice.

Built with Bun, tmux, xterm.js, React, Lucide, and Moonshine. The bird is not load-bearing.

About

A small, hackable browser terminal for your coding agents. OpenCode, Codex, DeepSeek Harness. Your machine. Your tmux sessions.

Topics

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages