mirror of
https://github.com/l0ng-ai/tty7.git
synced 2026-11-06 08:15:35 +00:00
A machine's screen now lists, under its own workspaces, every machine its tty7 holds an SSH link to, with that machine's workspaces. Panes there open, take input and get new tabs like local ones. "Needs you" gathers panes from all of them. - The gateway routes through the local server over links it already holds, the same way `tty7 -m <machine>` does. It never dials a down link, because that would guess at credentials the phone does not have. A down link shows as "Link down", with a note to reconnect it on the desktop. - Protocol, additive: `Tree.remotes`, and an optional `machine` (the link key) on `Open::Pane` and `Open::NewTab`. A local pane is asked for exactly as before, so older gateways still understand it. - Rebuilding a route target from a link key moves from the CLI into tty7-core as `RouteInfo::target` / `RouteInfo::host`, so the CLI and the gateway share one rule. The CLI now calls it.
tty7 mobile
Watch and drive your desktop's tty7 panes and agents from a phone.
phone (Tauri: WebView + Rust) ──iroh──▶ tty7-gateway ──local sockets──▶ tty7 server
xterm.js ◀─ raw bytes ─ tty7-mobile-client (crates/tty7-gateway)
- Transport: iroh. The phone dials the desktop by public key. Connections hole-punch to a direct path when the network allows and fall back to a relay when it doesn't. Either way they're end-to-end encrypted. No port forwarding, no VPN.
- Protocol:
crates/tty7-mobile-proto. The phone never speaks the daemon's own protocols. The gateway exposes a small vocabulary: pair, a live tree of workspaces, tabs, panes and agent status, and one stream per open pane. - Panes are observed, not attached. A phone never resizes a pane or takes it away from
the desktop window showing it. Keystrokes go in beside the observer (
SendInput). The terminal keeps the desktop's size, and the app shrinks the font to fit the width. - Auth: pairing with a one-time code, valid 10 minutes, single use. After that the
gateway admits only the phone keys on its device list (
<config dir>/mobile/devices.json).
Run it
On the desktop, next to a running tty7:
cargo run -p tty7-gateway -- serve # keep this running
cargo run -p tty7-gateway -- pair # prints a QR code + a tty7pair:… code
cargo run -p tty7-gateway -- devices # paired phones; `revoke <name>` removes one
The app on the desktop (fastest loop)
Tauri builds the same app for macOS, which is the quickest way to work on the UI:
cd mobile
npm install
npm run tauri dev
Paste the tty7pair: code and tap Pair.
iOS
Needs the full Xcode, not just the Command Line Tools, plus an Apple developer account to run on a device.
rustup target add aarch64-apple-ios aarch64-apple-ios-sim
cd mobile
npm run tauri ios init # once: generates src-tauri/gen/apple
npm run tauri ios dev # simulator, or pick a connected device
Android
Needs Android Studio's SDK and NDK, with ANDROID_HOME and NDK_HOME set.
rustup target add aarch64-linux-android armv7-linux-androideabi x86_64-linux-android
cd mobile
npm run tauri android init
npm run tauri android dev
Without a phone
crates/tty7-mobile-client/examples/probe.rs is a phone in a shell. It pairs, prints the
tree, and times keystroke echo on a pane:
cargo run -p tty7-mobile-client --example probe -- pair '<code>'
cargo run -p tty7-mobile-client --example probe -- tree
cargo run -p tty7-mobile-client --example probe -- type 1 'echo hi'
Not done yet
- QR scanning. The app takes a pasted code for now. Next step is
tauri-plugin-barcode-scanneron mobile. - Push notifications when an agent starts waiting. The gateway sees the status change, but APNs/FCM delivery needs a small native plugin and a push relay.
- Keychain / Keystore for the phone's key. It lives in the app's private data directory today.
- Remote machines. The gateway serves the local machine's panes. Panes the desktop reaches over SSH aren't exposed yet.
- Take over. Attaching a pane at the phone's size, for when the desktop isn't in use.
- A self-hosted iroh relay for production, instead of n0's public ones.