# Even Terminal

`even-terminal` is designed to be used with the Even App.

> Building glasses-native apps instead of mirroring your laptop? See [@evenrealities/even_hub_sdk](https://www.npmjs.com/package/@evenrealities/even_hub_sdk).

Supports macOS, Linux, Windows.

---

## Requirements

- **Node.js 18+** — check with `node --version`. Install from [nodejs.org](https://nodejs.org), or `brew install node` (macOS), or your distro's package manager (Linux).
- An **Even Realities G2** + **R1 ring**, paired through the Even app (iOS/Android).
- Optional but recommended: a [Tailscale](https://tailscale.com) account signed in on both your laptop and phone — gives you a stable private network without needing the public-tunnel providers below.

---

## Install

```bash
npm install -g @evenrealities/even-terminal
```

Verify the install:

```bash
even-terminal --version
```

Update to the latest release:

```bash
npm install -g @evenrealities/even-terminal@latest
```

---

## Quick Start

```bash
even-terminal
```

By default the server starts on `http://localhost:3456`.

Useful startup options:

```bash
even-terminal --cwd /path/to/project
even-terminal --port 8080
even-terminal --token mytoken123
even-terminal --name my-laptop
even-terminal --provider codex
even-terminal --expose pinggy
even-terminal --expose bore
even-terminal --expose ngrok
```

---

## How it works

even-terminal runs a local HTTP server on `:3456` (configurable via `--port`), spawns your AI agent (Claude Code or Codex) as a child process, captures its streaming output, renders it onto the G2's 576×288 canvas, and translates R1 ring gestures back into keyboard events for the agent.

The Even app connects to your laptop over your chosen transport. By default it binds to your detected LAN address (same Wi-Fi). Pass `--tailscale` to bind on your Tailscale tailnet instead (stable across networks, end-to-end WireGuard), `-i <interface>` to pin a specific network interface, or `--expose pinggy` / `--expose bore` / `--expose ngrok` to open a temporary public tunnel.

```
                       ┌──────────────────┐
                       │   your laptop    │
   [ claude / codex ] ─│   even-terminal  │
                       │   :3456          │
                       └────────┬─────────┘
                                │
                ┌───────────────┴───────────────┐
                │   transport (pick one)        │
                │   default: LAN (same Wi-Fi)   │
                │   --tailscale                 │
                │   --expose pinggy             │
                │   --expose bore               │
                │   --expose ngrok              │
                └───────────────┬───────────────┘
                                │
                       ┌────────┴─────────┐
                       │     Even app     │
                       └──┬────────────┬──┘
                       (display)     (input)
                       BLE ↓          ↑ BLE
                     ┌────┴────┐  ┌────┴────┐
                     │   G2    │  │   R1    │
                     │ 576×288 │  │  ring   │
                     └─────────┘  └─────────┘
```

The agent is *your* binary running on *your* laptop. even-terminal is a renderer + input bridge, not a runtime.

---

## CLI

```text
even-terminal [command] [options]

Commands:
  even-terminal start
  even-terminal complete <shell>

Local network options:
  --tailscale
  -i, --interface, --if <name>

Quick public expose options:
  --expose <provider>   Quick public expose provider (`pinggy`, `bore`, `ngrok`)

Options:
  -p, --port <n>
  -t, --token <str>
  -n, --name <str>
  -d, --cwd <path>
  --provider <name>   claude, codex (default: claude)
  --log-file [path]
  --verbose
  -h, --help
  -v, --version

Examples:
  even-terminal
  even-terminal -p 8080
  even-terminal -t mytoken123
  even-terminal --expose pinggy
  even-terminal --expose ngrok
```

Quick public expose helpers are intended for simple temporary sharing, not long-term use.
For stable setups, prefer a proper network path such as Tailscale or a production tunnel configuration.

Current quick expose providers:

### pinggy

No install required — uses your system's SSH client. Just pass `--expose pinggy`.

Behind the scenes:

```bash
ssh -p 443 -R0:localhost:<port> a.pinggy.io
```

Pinggy is a hosted SSH-tunnel service; the public URL appears in your terminal once the tunnel is up.

### bore

Self-hostable, written in Rust. GitHub: [ekzhang/bore](https://github.com/ekzhang/bore).

Install:

- **macOS:** `brew install bore-cli` *(or)* `cargo install bore-cli`
- **Linux:** `cargo install bore-cli` *(or)* download a prebuilt binary from [releases](https://github.com/ekzhang/bore/releases) and put `bore` on your `$PATH`
- **Windows:** download `bore-vX.Y.Z-x86_64-pc-windows-msvc.zip` from [releases](https://github.com/ekzhang/bore/releases), extract `bore.exe`, add its folder to your `PATH`

Verify with `bore --version`. Then `--expose bore` runs:

```bash
bore local <port> --to bore.pub
```

### ngrok

Hosted tunnel service, free tier available. Site: [ngrok.com](https://ngrok.com).

Install:

- **macOS:** `brew install ngrok/ngrok/ngrok`
- **Linux:** see the apt/yum repos at [ngrok.com/download](https://ngrok.com/download) — or download the tarball, extract, and put `ngrok` on your `$PATH`
- **Windows:** download the zip from [ngrok.com/download](https://ngrok.com/download), extract `ngrok.exe`, add its folder to your `PATH`

One-time setup — sign up at [ngrok.com](https://ngrok.com), copy your authtoken from the dashboard, then:

```bash
ngrok config add-authtoken <your-token>
```

Verify with `ngrok --version`. Then `--expose ngrok` runs:

```bash
ngrok http <port>
```

Shell completion (example usage):

```text
even-terminal complete zsh
even-terminal complete bash
even-terminal complete fish
even-terminal complete powershell
```

Each form prints the completion script for that shell.


## Flow

1. Start the server with `even-terminal`. It prints a connection URL, a token, and a QR code in the terminal.
2. Open the Even app on your phone and scan the QR code — or paste the URL and token manually if scanning isn't convenient.
3. Your G2 glasses and R1 ring connect via BLE through the Even app. The agent's output streams onto the glasses, and ring gestures route back to the agent as keyboard events.


## Providers

The server can drive all supported providers concurrently; `--provider <name>`
just chooses the **default**. Each provider wraps its own CLI — make sure the
binary is installed and authenticated beforehand.

| Provider   | Required CLI    | Auth                           | Override path env  |
|------------|-----------------|--------------------------------|--------------------|
| `claude`   | `claude`        | `claude login` (Claude Code)   | n/a                |
| `codex`    | `codex`         | `codex` first-run wizard       | n/a                |

---

## Common problems

| **Symptom**                                               | **Cause**                                               | **Fix**                                                                                  |
|-----------------------------------------------------------|---------------------------------------------------------|------------------------------------------------------------------------------------------|
| Phone app shows "Server unreachable"                      | Laptop and phone on different transports                | Match: both on Tailscale (`--tailscale`) or both on the same Wi-Fi                       |
| `EADDRINUSE :3456`                                        | Another even-terminal already running                   | `lsof -i :3456` → kill old one, or pass `--port <other>`                                 |
| `command not found: claude` or `codex`                   | Agent binary not on `$PATH`                             | Install per the Providers table; verify with `which claude` / `which codex`              |
| `--expose pinggy` hangs                                   | Pinggy edge timing out                                  | Switch to `--expose bore`, `--expose ngrok`, or Tailscale                                |
| Token rotates every restart                               | Not passing `--token`                                   | `even-terminal --token my-fixed-token`                                                   |
| Output truncated mid-stream                               | Agent printed something the 576×288 layout can't render | Re-run with `--verbose --log-file ./debug.log` and open an issue with the offending line |

For anything else: `even-terminal --verbose --log-file ./debug.log`, reproduce, attach the log to an email to software@evenrealities.com .

---

## Changelog

### 0.8.1

- optimize codex session history performance for large session (windows)
- add `--expose ngrok` support (need to sign in elsewhere first)

### 0.8.0

- codex now only starts a background process when necessary

### 0.7.9

- add debug timing for codex history api
- fix middle deny behavior in multiple permission requests

### 0.7.8

- add update check api

### 0.7.7

- improve codex support with `even-terminal codex` wrapper which can sync
messages between codex cli and glasses
- internal refactoring

---

## License

MIT
