An open API service indexing awesome lists of open source software.

https://github.com/kshivang/bossterm

Pure Kotlin Terminal Emulator. Works with SSH and PTY.
https://github.com/kshivang/bossterm

Last synced: about 1 month ago
JSON representation

Pure Kotlin Terminal Emulator. Works with SSH and PTY.

Awesome Lists containing this project

README

          

BossTerm

# BossTerm

**A blazing-fast terminal you can embed, share to any device, and hand to your AI.**

[![CI](https://github.com/kshivang/BossTerm/actions/workflows/test.yml/badge.svg)](https://github.com/kshivang/BossTerm/actions/workflows/test.yml)
[![Release](https://github.com/kshivang/BossTerm/actions/workflows/release.yml/badge.svg)](https://github.com/kshivang/BossTerm/releases)
[![Download DMG](https://img.shields.io/github/v/release/kshivang/BossTerm?label=Download%20DMG&logo=apple)](https://github.com/kshivang/BossTerm/releases/latest)
[![Maven Central](https://img.shields.io/maven-central/v/com.risaboss/bossterm-core)](https://central.sonatype.com/namespace/com.risaboss)

| ⚑ [**Fast**](#performance) | πŸ“± [**Share**](#session-sharing) | πŸ€– [**MCP for AI**](#bossterm-mcp) | 🧩 [**Embeddable**](#embedding-in-your-app) |
|:--:|:--:|:--:|:--:|
| 1,645 MB/s β€” edges out Alacritty | Watch & control from any device | Expose tabs to Claude Code & co. | Drop it into your Compose app |

A modern terminal emulator built with **Kotlin** and **Compose Desktop** β€” high-performance, deeply customizable, and feature-rich on macOS, Linux, and Windows.

## Performance

BossTerm delivers **industry-leading throughput** for developer workflows. Benchmarked against iTerm2, Terminal.app, and Alacritty (December 2025, **Latency Mode**):

### Raw Throughput @ 50MB (MB/s) - Higher is Better
```
BossTerm β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ 1,645 MB/s βœ“
Alacritty β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ 1,633 MB/s
iTerm2 β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ 1,599 MB/s
Terminal β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ 1,491 MB/s
```

### Raw Throughput @ 1MB (MB/s) - Higher is Better
```
BossTerm β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ 364 MB/s βœ“
iTerm2 β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ 255 MB/s
Terminal β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ 249 MB/s
Alacritty β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ 233 MB/s
```

### Variation Selectors (chars/sec) - Higher is Better
```
BossTerm β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ 1.01M βœ“
iTerm2 β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ 904K
Terminal β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ 879K
Alacritty β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ 829K
```

### htop Simulation (ms) - Lower is Better
```
BossTerm β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ 3.09 ms βœ“
Terminal β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ 3.21 ms
iTerm2 β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ 3.55 ms
Alacritty β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ 3.72 ms
```

| Benchmark | BossTerm vs iTerm2 |
|-----------|-------------------|
| Raw Throughput (1MB) | **+43% faster** |
| Raw Throughput (5MB) | **+24% faster** |
| Raw Throughput (50MB) | **+3% faster** |
| Variation Selectors | **+12% faster** |
| CJK Characters | **+10% faster** |
| Powerline | **+10% faster** |
| htop Simulation | **+13% faster** |
| Git Diff Simulation | **+5% faster** |
| Flags Emoji | **+3% faster** |

> **Full benchmark details:** [benchmark/README.md](benchmark/README.md) | [Detailed Results](benchmark_results/BENCHMARK_SUMMARY.md)

## Installation

### Universal Installer (Recommended)

[![Install Script](https://github.com/kshivang/BossTerm/actions/workflows/test-install.yml/badge.svg)](https://github.com/kshivang/BossTerm/actions/workflows/test-install.yml)

The universal installer automatically detects your platform and installs BossTerm using the best method available.

| Platform | Command |
|----------|---------|
| **macOS / Linux** | `curl -fsSL https://raw.githubusercontent.com/kshivang/BossTerm/master/install.sh \| bash` |
| **Windows (PowerShell)** | `iwr -useb https://raw.githubusercontent.com/kshivang/BossTerm/master/install.ps1 \| iex` |
| **Windows (CMD)** | `curl -fsSL https://raw.githubusercontent.com/kshivang/BossTerm/master/install.bat -o install.bat && install.bat` |

**Features:**
- Auto-detects platform (macOS, Linux, Windows) and architecture (x64, ARM64)
- Uses the best installation method (Homebrew β†’ DMG on macOS, Deb β†’ RPM β†’ Snap β†’ JAR on Linux)
- Installs Java 17+ automatically if needed (Windows)
- Creates CLI launcher (`bossterm` command)
- Supports `--version`, `--uninstall`, `--dry-run`, and `--method` flags

**Common operations:**

```bash
# Install specific version
curl -fsSL https://raw.githubusercontent.com/kshivang/BossTerm/master/install.sh | bash -s -- --version 1.0.80

# Preview without installing
curl -fsSL https://raw.githubusercontent.com/kshivang/BossTerm/master/install.sh | bash -s -- --dry-run

# Force specific method (homebrew, dmg, deb, rpm, snap, jar)
curl -fsSL https://raw.githubusercontent.com/kshivang/BossTerm/master/install.sh | bash -s -- --method dmg

# Uninstall
curl -fsSL https://raw.githubusercontent.com/kshivang/BossTerm/master/install.sh | bash -s -- --uninstall
```

---

### Alternative Installation Methods

macOS (Homebrew)

```bash
brew tap kshivang/bossterm
brew install --cask bossterm
```

macOS (DMG)

Download the latest DMG from [GitHub Releases](https://github.com/kshivang/BossTerm/releases) and drag BossTerm to Applications.

Linux (Debian/Ubuntu)

```bash
# Download the .deb package from GitHub Releases
sudo dpkg -i bossterm_*_amd64.deb
sudo apt-get install -f # Install dependencies if needed
```

Linux (Fedora/RHEL)

```bash
# Download the .rpm package from GitHub Releases
sudo dnf install bossterm-*.x86_64.rpm
```

Linux (Snap)

```bash
sudo snap install bossterm --classic
```

Or download the `.snap` file from [GitHub Releases](https://github.com/kshivang/BossTerm/releases) and install manually:

```bash
sudo snap install bossterm_*.snap --classic --dangerous
```

JAR (Cross-platform)

Requires Java 17+:

```bash
# Download bossterm-*.jar from GitHub Releases
java -jar bossterm-*.jar
```

Build from Source

```bash
git clone https://github.com/kshivang/BossTerm.git
cd BossTerm
./gradlew :bossterm-app:run
```

## Features

- **Native Performance** - Built with Kotlin/Compose Desktop for smooth 60fps rendering
- **Multiple Windows** - Cmd/Ctrl+N opens new window, each with independent tabs
- **Multiple Tabs** - Ctrl+T new tab, Ctrl+W close, Ctrl+Tab switch
- **Split Panes** - Horizontal/vertical splits with Cmd+D / Cmd+Shift+D
- **Themes** - Built-in theme presets (Dracula, Solarized, Nord, etc.) with custom theme support
- **Window Transparency** - Adjustable opacity with background blur effects
- **Background Images** - Custom background images with blur and opacity controls
- **Xterm Emulation** - Full VT100/Xterm compatibility
- **True Color** - Full 256 color and 24-bit true color support
- **Mouse Reporting** - Click, scroll, and drag support for terminal apps (vim, tmux, htop, less, fzf)
- **Full Unicode** - Emoji (πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦), variation selectors (☁️), surrogate pairs, combining characters
- **Nerd Fonts** - Built-in support for powerline symbols and devicons
- **Inline Images** - Display images in terminal via iTerm2's imgcat (OSC 1337)
- **Progress Bar** - Visual progress indicator for long-running commands (OSC 1337)
- **Search** - Ctrl/Cmd+F to search terminal history with regex support
- **Hyperlink Detection** - Auto-detect URLs, file paths, emails with Ctrl+Click to open
- **Copy/Paste** - Standard clipboard + copy-on-select + middle-click paste + OSC 52
- **Context Menu** - Right-click for Copy, Paste, Clear, Select All
- **Drag & Drop** - Drop files onto terminal to paste shell-escaped paths (iTerm2 style)
- **Auto-Scroll Selection** - Drag selection beyond bounds to scroll through history
- **IME Support** - Full Chinese/Japanese/Korean input method support
- **Visual Bell** - Configurable visual flash for BEL character
- **Command Notifications** - System notifications when long commands complete (OSC 133)
- **OSC 7 Support** - Working directory tracking for new tabs
- **Settings UI** - Full GUI settings panel with live preview
- **Debug Tools** - Built-in terminal debugging with Ctrl+Shift+D
- **Welcome Wizard** - First-time setup wizard for shell, tools, and AI assistants
- **Customizable** - JSON-based settings at `~/.bossterm/settings.json`
- **Session Sharing** - Watch or control a tab / window / all windows from any device β€” self-hosted, with a QR code and a mobile-friendly web viewer (LAN, Tailscale, or a zero-config Cloudflare tunnel)
- **Remote Control** - End-to-end encrypted; viewers get typing access on approval, or connect from another BossTerm as a native remote client
- **AI / MCP Server** - Built-in [Model Context Protocol](https://modelcontextprotocol.io) server exposes your terminals to Claude Code, Codex, Gemini CLI, and OpenCode
- **Session Daemon** - tmux-style background process (on by default) keeps your sessions, MCP server, and shares alive after the GUI closes β€” reopen to reattach; starts at login
- **Embeddable** - Drop the terminal into your own Kotlin/Compose Desktop app as a library (`com.risaboss:bossterm-compose`)

## Design

BossTerm's default look is the **Operator** theme β€” part of the shared BOSS **"Operator's Console"** visual language: an amber **signal** (`#F2A93B`) for the live/now moment on a calm **ink** floor (`#0E1217`), with cyan **data** accents and a MesloLGS mono voice. The tab bar and terminal surface both follow the active theme, and you can switch themes/palettes in Settings.

🎨 **[Visual styleguide](docs/design-system.html)** β€” a self-contained HTML reference for the whole design system's colors / type / components (open it in a browser).

## Keyboard Shortcuts

| Shortcut | Action |
|----------|--------|
| Ctrl/Cmd+N | New window |
| Ctrl/Cmd+T | New tab |
| Ctrl/Cmd+W | Close tab/pane |
| Ctrl+Tab | Next tab |
| Ctrl+Shift+Tab | Previous tab |
| Ctrl/Cmd+1-9 | Jump to tab |
| Ctrl/Cmd+D | Split pane vertically |
| Ctrl/Cmd+Shift+D | Split pane horizontally |
| Ctrl/Cmd+Option+Arrow | Navigate between panes |
| Ctrl/Cmd+, | Open settings |
| Ctrl/Cmd+F | Search |
| Ctrl/Cmd+C | Copy |
| Ctrl/Cmd+V | Paste |
| Ctrl+Space | Toggle IME |

## Shell Integration

Enable working directory tracking and command completion notifications:

**Bash** (`~/.bashrc`):
```bash
# OSC 7 (directory tracking) + OSC 133 (command notifications)
__prompt_command() {
local exit_code=$?
echo -ne "\033]133;D;${exit_code}\007" # Command finished
echo -ne "\033]133;A\007" # Prompt starting
echo -ne "\033]7;file://${HOSTNAME}${PWD}\007" # Working directory
}
PROMPT_COMMAND='__prompt_command'
trap 'echo -ne "\033]133;B\007"' DEBUG # Command starting
```

**Zsh** (`~/.zshrc`):
```bash
# OSC 7 (directory tracking) + OSC 133 (command notifications)
precmd() {
local exit_code=$?
print -Pn "\e]133;D;${exit_code}\a" # Command finished
print -Pn "\e]133;A\a" # Prompt starting
print -Pn "\e]7;file://${HOST}${PWD}\a" # Working directory
}
preexec() { print -Pn "\e]133;B\a" } # Command starting
```

This enables:
- New tabs inherit working directory from active tab
- System notifications when commands > 5 seconds complete while window is unfocused

## Project Structure

```
BossTerm/
β”œβ”€β”€ bossterm-core-mpp/ # Core terminal emulation library
β”‚ └── src/jvmMain/kotlin/ai/rever/bossterm/
β”‚ β”œβ”€β”€ core/ # Core utilities and types
β”‚ └── terminal/ # Terminal emulator implementation
β”œβ”€β”€ compose-ui/ # Compose Desktop UI library (embeddable)
β”‚ └── src/desktopMain/kotlin/ai/rever/bossterm/compose/
β”‚ β”œβ”€β”€ ui/ # Main terminal composable (ProperTerminal)
β”‚ β”œβ”€β”€ terminal/ # Terminal data stream handling
β”‚ β”œβ”€β”€ input/ # Mouse/keyboard input handling
β”‚ β”œβ”€β”€ rendering/ # Canvas rendering engine
β”‚ β”œβ”€β”€ tabs/ # Tab management
β”‚ β”œβ”€β”€ window/ # Window management (WindowManager)
β”‚ β”œβ”€β”€ search/ # Search functionality
β”‚ β”œβ”€β”€ debug/ # Debug tools
β”‚ └── settings/ # Settings management
β”œβ”€β”€ bossterm-app/ # Main BossTerm application
β”‚ └── src/desktopMain/kotlin/ai/rever/bossterm/app/
β”‚ └── Main.kt # Application entry point
β”œβ”€β”€ embedded-example/ # Example: single terminal embedding
β”œβ”€β”€ tabbed-example/ # Example: tabbed terminal embedding
└── .github/workflows/ # CI configuration
```

## Configuration

Settings are stored in `~/.bossterm/settings.json`:

```json
{
"fontSize": 14,
"fontName": "JetBrains Mono",
"copyOnSelect": true,
"pasteOnMiddleClick": true,
"scrollbackLines": 10000,
"cursorBlinkRate": 500,
"enableMouseReporting": true,
"performanceMode": "balanced",
"notifyOnCommandComplete": true,
"notifyMinDurationSeconds": 5
}
```

### Performance Modes

BossTerm offers configurable performance optimization via Settings > Performance:

| Mode | Best For |
|------|----------|
| **Balanced** (default) | General use - good balance of responsiveness and throughput |
| **Latency** | SSH, vim, interactive commands - fastest response time |
| **Throughput** | Build logs, large files - maximum data processing speed |

> **Note:** For `fontName`, use a monospace font name installed on your system (e.g., "SF Mono", "Menlo", "JetBrains Mono"). If not set, BossTerm uses the bundled MesloLGS Nerd Font which includes powerline symbols.

## Embedding in Your App

BossTerm provides embeddable terminal libraries for Kotlin Multiplatform projects.

> **Full Documentation**: See [docs/embedding.md](docs/embedding.md) for the complete embedding guide, including custom context menus, focus management, and session persistence.

### Gradle Setup

**Maven Central** (recommended):

[![Maven Central](https://img.shields.io/maven-central/v/com.risaboss/bossterm-core)](https://central.sonatype.com/namespace/com.risaboss)

```kotlin
// build.gradle.kts
repositories {
mavenCentral()
}

dependencies {
// Core terminal emulation engine
implementation("com.risaboss:bossterm-core:")

// Compose Desktop UI component
implementation("com.risaboss:bossterm-compose:")
}
```

**JitPack** (alternative):

[![JitPack](https://jitpack.io/v/kshivang/BossTerm.svg)](https://jitpack.io/#kshivang/BossTerm)

```kotlin
// settings.gradle.kts
dependencyResolutionManagement {
repositories {
maven { url = uri("https://jitpack.io") }
}
}

// build.gradle.kts
dependencies {
implementation("com.github.kshivang.BossTerm:bossterm-core-mpp:")
implementation("com.github.kshivang.BossTerm:compose-ui:")
}
```

**GitHub Packages** (requires authentication):

```kotlin
// settings.gradle.kts
dependencyResolutionManagement {
repositories {
maven {
url = uri("https://maven.pkg.github.com/kshivang/BossTerm")
credentials {
username = System.getenv("GITHUB_ACTOR")
password = System.getenv("GITHUB_TOKEN")
}
}
}
}

// build.gradle.kts
dependencies {
implementation("com.risaboss:bossterm-core:")
implementation("com.risaboss:bossterm-compose:")
}
```

### Usage

```kotlin
import ai.rever.bossterm.compose.EmbeddableTerminal
import ai.rever.bossterm.compose.rememberEmbeddableTerminalState

@Composable
fun MyApp() {
// Basic usage - uses default settings from ~/.bossterm/settings.json
EmbeddableTerminal()

// With custom settings path
EmbeddableTerminal(settingsPath = "/path/to/settings.json")

// With custom font (via settings)
EmbeddableTerminal(settings = TerminalSettings(fontName = "JetBrains Mono"))

// With callbacks
EmbeddableTerminal(
onOutput = { output -> println(output) },
onTitleChange = { title -> window.title = title },
onExit = { code -> println("Shell exited: $code") },
onReady = { println("Terminal ready!") }
)

// Programmatic control
val state = rememberEmbeddableTerminalState()

Button(onClick = { state.write("ls -la\n") }) {
Text("Run ls")
}

// Send control signals (useful for interrupting processes)
Button(onClick = { state.sendCtrlC() }) {
Text("Stop (Ctrl+C)")
}

EmbeddableTerminal(state = state)

// Session preservation across navigation/visibility changes
val persistentState = rememberEmbeddableTerminalState(autoDispose = false)

if (showTerminal) {
EmbeddableTerminal(state = persistentState)
}
// Terminal process keeps running even when hidden!

// Don't forget to dispose when truly done:
DisposableEffect(Unit) {
onDispose { persistentState.dispose() }
}

// Custom PlatformServices - override process spawning, notifications, etc.
// Uses Kotlin's 'by' delegation to wrap defaults while customizing specific services
val customServices = object : PlatformServices by getPlatformServices() {
val defaults = getPlatformServices()
override fun getProcessService() = object : PlatformServices.ProcessService {
private val delegate = defaults.getProcessService()
override suspend fun spawnProcess(config: PlatformServices.ProcessService.ProcessConfig)
: PlatformServices.ProcessService.ProcessHandle? {
println("Spawning: ${config.command}")
return delegate.spawnProcess(config)
}
}
}
EmbeddableTerminal(platformServices = customServices)
}
```

## Session Sharing

Watch β€” or hand over β€” a live terminal to any device, with **no cloud relay and no account**.
BossTerm runs the share server itself; viewers open a link (or scan a QR code) in any browser, or
connect from another BossTerm as a native client.

- **Scope**: share a single **tab** (with its splits), a whole **window**, or **all windows**
(viewers see tabs grouped by window).
- **View or Control**: hand out a read-only **view** link or a **control** link (typing access).
View-only viewers can request control mid-session and you approve from a prompt β€” required for
public links by default, skipped on the LAN.
- **Reach**: LAN out of the box, or a public URL via **Tailscale** (Serve/Funnel) or a zero-config
**Cloudflare** quick tunnel (the default β€” `cloudflared` is fetched automatically, no account).
The tunnel is pre-warmed so the QR is ready the moment you hit Share.
- **Mobile web viewer**: xterm.js-based and touch-tuned β€” soft-keyboard push, an on-screen key bar
(Esc / Tab / Ctrl / arrows + a ⌨ toggle), pinch-zoom, fit-to-screen, and clickable links.
- **Native remote client**: "Add remote" in BossTerm to mirror another machine's shared tabs into
your own window β€” including its **Remote MCP** β€” with control relayed up the chain.
- **End-to-end encrypted**: the session key rides in the URL **fragment** (`#k=…`), which browsers
never send to the server β€” so even a tunnel relay can't read your session. Frames use
per-connection AES-256-GCM, and a short verification code lets both ends confirm the same key.

Enable it under **Settings β†’ Session Sharing** (off by default), then **Share** from a tab's menu.
Defaults: binds the LAN on port `7677`, Cloudflare remote mode, approval required only for public
links.

See **[docs/session-sharing.md](docs/session-sharing.md)** for the full guide β€” scopes,
remote-access setup, the viewer, the native client, the encryption design, and every setting.

## BossTerm MCP

BossTerm ships an in-process [Model Context Protocol](https://modelcontextprotocol.io)
server that exposes the running terminal to MCP-aware clients (Claude Code,
Codex, Gemini CLI, OpenCode). Clients can enumerate tabs, read scrollback,
search output, capture the last completed command, and β€” when write tools
are enabled β€” drive shells, send signals, open new splits, and **run
commands in a visible pane** while still capturing stdout/stderr and exit
code (`run_command` β€” recommended default shell for AI clients).

- **Endpoint**: `http://127.0.0.1:7676/` over Server-Sent Events, configurable
via Settings β†’ BossTerm MCP β†’ Port.
- **Loopback-only**: the server binds `127.0.0.1` and rejects non-loopback
`Host` headers (DNS-rebinding defense). Any local process running as your
user can reach it while it is enabled.
- **Opt-in**: disabled by default. Toggle on under Settings β†’ BossTerm MCP.
- **Remote MCP**: when you [share a session](#session-sharing), the host's MCP can be driven from
the web viewer (an "MCP pill" toggles it and attaches CLIs) or from a native remote client β€”
calls on shared tabs are relayed to the host.

### Turning it on (as a user)

1. Open Settings β†’ **BossTerm MCP** and toggle **Enable BossTerm MCP Server**.
A green "BossTerm MCP on" pill appears in the tab bar.
2. (Optional) Under **Exposed Tools**, untick any built-in tool you don't
want clients to call β€” toggles apply live.
3. Under **Attach to AI CLI**, click the button for each AI CLI you want to
register the endpoint with. Re-attachment is idempotent and happens
silently on subsequent launches.

### Using as Claude Code's default shell

`run_command` is exposed by default and ready for explicit use (e.g. "split and
run X"). To make it Claude Code's *default* shell β€” preferred over its built-in
`Bash` for everything β€” turn on **Settings β†’ BossTerm MCP β†’ "Use `run_command`
as AI clients' default shell"** (off by default). With it on, the server's
initialize-time `instructions` tell Claude Code to prefer `run_command` (a soft
nudge that applies to the next client connection).

For a hard guarantee that also takes effect **instantly**, add the user-global
`PreToolUse` hook described in
[docs/mcp-server.md](docs/mcp-server.md#using-as-claude-codes-default-shell).
BossTerm writes/deletes the `~/.bossterm/mcp.port` marker the moment you flip
the setting, and the hook routes `Bash` calls to `mcp__bossterm__run_command`
whenever the marker is present β€” so toggling the setting turns enforcement on or
off per command, with no Claude restart.

### Embedding it (as a developer)

```kotlin
import ai.rever.bossterm.compose.mcp.BossTermMcpConfig
import ai.rever.bossterm.compose.mcp.BossTermMcpManager
import ai.rever.bossterm.compose.mcp.LocalBossTermMcpConfig
import ai.rever.bossterm.compose.mcp.McpTerminalRegistry
import ai.rever.bossterm.compose.settings.SettingsManager

fun main() {
val mcpConfig = BossTermMcpConfig(serverName = "myapp", serverVersion = "1.0")
val mcpScope = CoroutineScope(SupervisorJob() + Dispatchers.Default)
val mcpManager = BossTermMcpManager(
registry = McpTerminalRegistry,
settingsManager = SettingsManager.instance,
parentScope = mcpScope,
config = mcpConfig
)
mcpManager.start()
Runtime.getRuntime().addShutdownHook(Thread {
mcpManager.stop()
mcpScope.cancel()
})

application {
CompositionLocalProvider(LocalBossTermMcpConfig provides mcpConfig) {
// Each window that uses TabbedTerminalState must also register
// it with McpTerminalRegistry so the server can see its tabs:
//
// DisposableEffect(tabbedState) {
// McpTerminalRegistry.register(tabbedState)
// onDispose { McpTerminalRegistry.unregister(tabbedState) }
// }
//
// Apps built on the single-terminal EmbeddableTerminal can still
// run the MCP server and register custom tools via additionalTools,
// but the tab-scoped built-ins (list_tabs, send_input, etc.) won't
// see any tabs. See docs/mcp-server.md for the full contract.
MyAppWindows()
}
}
}
```

Common knobs on `BossTermMcpConfig`: `toolNamePrefix` to namespace built-in
tools, `allowWriteTools = false` for an observe-only build, `additionalTools`
to register app-specific MCP tools, and `customToolDescriptions` to override
descriptions of individual built-ins. The
[`embedded-example`](embedded-example/) and [`tabbed-example`](tabbed-example/)
modules demonstrate both hooks.

See [docs/mcp-server.md](docs/mcp-server.md) for the full reference β€”
every built-in tool's JSON schema, the `manage_tools` meta-tool, the
`BossTermMcpConfig` field-by-field table, and troubleshooting.

## Session Daemon

A tmux-style background process that **owns your terminal sessions, MCP server, and shares** so they
keep running after you close the GUI β€” reopen BossTerm and it reattaches to the live sessions. **On by
default**; turn it off under Settings β†’ Session Daemon to fall back to the pre-daemon behavior
(in-process MCP/sharing, sessions die with the window), a path that's preserved byte-for-byte.

- **Survives the GUI**: sessions live in the daemon, not the window. Close the app (or all its
windows) and your shells keep running β€” long builds, SSH sessions, and `run_command` agents don't
die. The next launch mirrors them straight back as tabs.
- **Thin-client GUI**: when enabled, each window attaches to the daemon over a loopback WebSocket and
renders its sessions; keystrokes and resizes flow back to the daemon, which owns the PTYs. If the
daemon is unreachable, the GUI falls back to local tabs so you're never stuck.
- **MCP + sharing stay live headless**: the daemon hosts the [MCP server](#bossterm-mcp) and
[session sharing](#session-sharing), so agents and share links keep working with no window open. A
menu-bar / tray icon shows it's running and lets you open the GUI or quit the daemon.
- **Starts at login** (on by default): installs a per-OS login service (launchd LaunchAgent / systemd
user unit / Windows Run key) so the daemon is available even before BossTerm is first opened or after
a reboot. A separate **Start daemon at login** toggle turns this off without disabling the daemon. On
a shared/multi-user host, note the loopback MCP endpoint is then reachable by any process running as
you whenever you're logged in.
- **Secure by construction**: loopback-only, gated by a 256-bit per-launch secret (constant-time
compare, sent in a header β€” never the query string), DNS-rebinding `Host` guards on every server,
owner-only (`0600`) discovery/secret files in a `0700` base dir, and a `FileChannel.tryLock`
single-spawn guard. SESSION-scoped shares are write-isolated to their one session.

Manage it under **Settings β†’ Session Daemon** (toggles take effect after restarting BossTerm). The
daemon never stops when you close the GUI β€” only via **Quit daemon**, or OS logout.

## Technology Stack

- **Kotlin** - Modern JVM language
- **Compose Desktop** - Declarative UI framework
- **Pty4J** - PTY support for local terminal sessions
- **ICU4J** - Unicode/grapheme cluster support

## Command-Line Interface

`install.sh` installs a `bossterm` CLI launcher (and a Python helper +
man page) under `/usr/local/bin/` or `~/.local/bin/`. With no arguments it
launches the GUI; with a positional path it opens that directory.

Beyond launching, the CLI has subcommands that talk to a running BossTerm
through the in-process MCP server:

```bash
bossterm # Launch the GUI
bossterm ~/Projects/foo # Launch in a directory
bossterm new # New window
bossterm new-tab # New tab in the running BossTerm (MCP)
bossterm run npm test # Run a command in a new tab (MCP)
bossterm run --split=h tail -f log # Open a horizontal split and tail (MCP)
bossterm send $'ls\n' # Send to the focused pane (MCP)
bossterm logs --lines 50 # Dump the last 50 scrollback lines (MCP)
bossterm attach claude # Re-register with Claude Code
bossterm mcp status # Inspect MCP enabled/port/state
bossterm mcp on | off # Toggle settings.mcpEnabled
bossterm config # Print path to ~/.bossterm/settings.json
bossterm --help # Full usage
```

Run `man bossterm` after installation for the complete reference.

> **Note on local dev usage:** the repo-root `./bossterm` is a symlink into
> `cli-resources/bossterm`, so `./bossterm --version` works from a clean
> `git clone`. GitHub's "Download ZIP" link does **not** preserve symlinks
> (the file materializes as plain text containing the link target). If
> you've downloaded a zip rather than cloned, run
> `cli-resources/bossterm` directly, or `git clone` the repo.

## Documentation

- [Embedding Guide](docs/embedding.md) - Embed a single terminal with custom context menus
- [Tabbed Terminal Guide](docs/tabbed-terminal.md) - Full-featured tabbed terminal with splits
- [Session Sharing](docs/session-sharing.md) - Watch & control a terminal from any device (web viewer, QR, tunnels, E2E)
- [BossTerm MCP Server](docs/mcp-server.md) - Expose tabs to MCP clients (Claude Code, Codex, Gemini, OpenCode)
- [BossTerm CLI](docs/bossterm.1) - `man bossterm` reference (troff)
- [Onboarding Wizard](docs/onboarding.md) - First-time setup wizard for users
- [Troubleshooting Guide](docs/troubleshooting.md) - Common issues and solutions
- [Release Notes](docs/release-notes/) - Detailed changelog for each version
- [Design System](docs/design-system.html) - "Operator's Console" visual styleguide (self-contained HTML; shared with BossConsole)

## Contributing

Contributions are welcome! Please feel free to submit issues and pull requests.

## License

BossTerm is dual-licensed under:
- [LGPLv3](LICENSE-LGPLv3.txt)
- [Apache 2.0](LICENSE-APACHE-2.0.txt)

You may select either license at your option.

## Authors

**Shivang** β€” shivang@risalabs.ai

## Open Source Origin and History

BossTerm was originally inspired by [JediTerm](https://github.com/JetBrains/jediterm) by JetBrains (authored by Dmitry Trofimov dmitry.trofimov@jetbrains.com and ClΓ©ment Poulain). The initial version of JediTerm was itself a reworked terminal emulator Gritty, which was in its own turn a reworked JCTerm terminal implementation.

BossTerm has since been completely rewritten from the ground up in Kotlin with Compose Desktop β€” no JediTerm, Gritty, or JCTerm code remains. Everything was rewritten from scratch with a new rendering engine, new buffer implementation, and new UI framework. A lot of new features were added including split panes, inline images, AI assistant integration, custom platform services, and high-performance incremental snapshot rendering.

## Acknowledgments

- [JediTerm](https://github.com/JetBrains/jediterm) by JetBrains β€” original inspiration for terminal emulation
- [iTerm2](https://github.com/gnachman/iTerm2) β€” the beloved macOS terminal, inspiration for many UX features
- [Pty4J](https://github.com/JetBrains/pty4j) β€” PTY library for local terminal sessions
- [ICU4J](https://unicode-icu.github.io/icu/userguide/icu4j/) β€” Unicode and grapheme cluster support

## References

- [Terminal protocol description](http://invisible-island.net/xterm/ctlseqs/ctlseqs.html) β€” Xterm control sequences
- [Terminal Character Set Terminology and Mechanics](http://www.columbia.edu/kermit/k95manual/iso2022.html) β€” ISO 2022 character sets
- [VT420 Programmer Reference Manual](http://manx.classiccmp.org/collections/mds-199909/cd3/term/vt420rm2.pdf) β€” DEC terminal reference
- [UTF-8 Demo](http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-demo.txt) β€” Unicode test file
- [Control sequences visualization](http://www.gnu.org/software/teseq/) β€” GNU teseq
- [Terminal protocol tests](http://invisible-island.net/vttest/) β€” vttest suite

---

**Built by [Risa Labs Inc](https://risalabs.ai)**