# cordless v0.6: Going CLI-First — Run It, Scan the QR, You're Paired

> Source: <https://dev.to/naveenneog/cordless-v06-going-cli-first-run-it-scan-the-qr-youre-paired-4lmo>
> Published: 2026-07-11 17:17:06+00:00

TL;DR—[cordless]manages your remote terminal / coding-agent (Claude Code, Codex) sessions and puts them on your phone.v0.6makes itCLI-first: run`cordless`

and it opens a full-screen terminaldashboardwhose starting screen shows alive pairing QR— scan it, done. No separate`cordless pair`

, no GUI to babysit. And it now ships asone self-contained binary(its own Node runtimeand`node-pty`

baked in), so there's nothing to install first. Designed in a running debate withGPT-5.6 Sol, built withGitHub Copilot CLI.

Every version so far treated cordless as "a daemon plus a phone app." Then the owner said something that reframed the whole thing:

"cordless should be a **CLI first. Look at the design of a terminal app and get the features from that. I want an installer that starts cordless as a proper terminal with a QR to pair on its starting screen — right now I run`cordless pair`

separately and pair the desktop and mobile apps independently, which defeats the purpose."

That's a redesign, not a tweak. So I opened a long debate with Sol and rebuilt the front door.

Run `cordless`

with no arguments and you get the screen on that card: a brand banner, daemon + Tailscale status, your session list, and — front and center — a **single-use pairing QR with a countdown**. Scan it with the phone app and you're paired. Press `p`

for a fresh code. No second command, no separate terminal.

Borrowing from modern terminal apps (Warp, Windows Terminal, iTerm2) — but deliberately *not* rebuilding one — the dashboard is a focused TUI: `↑/↓`

selects a session, `Enter`

attaches, `n`

starts a shell / Claude / Codex, `x`

kills, `d`

manages paired devices, `q`

leaves. It's a **thin client of a persistent daemon**: quitting the dashboard (or closing the terminal) never stops your sessions or the phone connection — the daemon keeps owning the PTYs. Sol was firm on that boundary, and it's the right one.

`Enter`

(or `cordless attach <id>`

) streams a session **straight into your host terminal** — no xterm.js, no second renderer. Raw keystrokes go to the PTY, resize events forward, and the detach chord is `Ctrl-] d`

. It's a tiny tmux-like attach that reuses the exact replay/snapshot protocol the phone uses. The host terminal *is* the renderer; cordless just pipes bytes.

The old `cordless pair`

minted a secret by writing a file directly. Sol flagged that: two processes minting into the same store invites races and inconsistent limits. So in v0.6 there's **one** authenticated `pairing.create`

over the WebSocket, and it can only be called by a **loopback-scoped credential from a real loopback socket** — the local machine's owner, never a remote phone. It's single-use, 256-bit, five-minute TTL, rate-limited, and capped. Both the dashboard and `cordless pair`

call the same path. A stolen phone token can't enroll new devices; only *you*, at the machine, can.

The biggest ask hiding in "an installer that just works" is: **don't make me install Node first.** So v0.6 ships a self-contained executable built with **Node's Single Executable Application** support:

`esbuild`

bundles the whole CLI into one file (with `node-pty`

marked external).`cordless.exe`

.`node-pty`

and the built web client ship `resources/`

, and a small loader resolves the native module from there.The trick that made it painless: `node-pty`

ships **node-api prebuilds**, which are ABI-stable across Node versions — so there's no fragile per-version native rebuild. The result is a ~45 MB download that runs the dashboard, spawns real PTYs, and serves the web client for your phone, all with **zero prerequisites**. CI builds and **smoke-tests** it (start → spawn a PTY → stop) on Windows and Linux; macOS is built the same way but still has a runner-specific `node-pty`

spawn quirk I'm chasing, so it's flagged as pending for now.

The same loop as the whole project — me on **GitHub Copilot CLI**, **Sol** as the design partner — but this time the pivot leaned hard on Sol's judgment: run the daemon in-process or as a persistent service? (service). How interactive should the TUI be for v0.6? (dashboard + minimal attach, not a pane framework). `pkg`

or Node SEA? (SEA, with node-pty external). Keeping the conversation **stateful** meant Sol weighed each answer against every prior decision instead of re-litigating them. Ten test suites — protocol E2E, security headers, loopback-scope enforcement, daemon-owned pairing, the CLI client, dashboard rendering, and restore-across-restart — stay green on every push.

The onboarding is finally one motion: **install cordless, run it, scan the QR.** No Node, no `npm install -g`

, no separate pairing step, no GUI to keep open. It reads like a real terminal tool because it *is* one — and the phone still gets the same live sessions. Turning a "daemon + app" into "a command you run" is exactly the kind of course-correction that only lands when you actually live with the thing.

*Part of the #AI4Good series. Built one day at a time. — @naveenneog*
