Collie
Your terminal AI agents, herded from your phone: a Tailscale-served PWA that surfaces which agent needs input and lets you answer on the go.
Privilege surface is tightly scoped: loopback-only bind, identity header from tailscale serve, device pairing as write credential (least_privilege 3). The security model plainly states 'arbitrary keystrokes = remote shell' and forbids funnel; data flow is diagrammed (data_flow_transparency 3); upgrading docs cover rollback (rollback 3). Deductions: per-write user confirmation detail only indirect; sensitive pane content (secrets, env vars) protected only at the boundary, and the unpaired default world leaves writes ungated per handlers.ts comments; dependency security shows frozen lockfiles and a 7-day cooldown but no audit/vuln scanning (dependency_security 2); single-author attribution with unverified publisher (source_attribution 2).
CI enforces version consistency, lint, typecheck, unit tests, browser e2e; releases gate on green CI (self_consistency 3). Failure messaging is detailed in release scripts and fixtures cover error codes, but runtime bridge error paths are only partially visible (failure_messages 2). Bun/nix flake pinning helps but upstream Bun risk is unmitigated (dependency_availability 2).
Audience precisely defined, single-user/tailnet assumption explicit, experimental boundaries (tmux/zellij/Windows) honestly labelled (audience 3, boundaries 3). Trigger semantics clear: needs-input ordering, block-on-input push (trigger_precision 3). Three platforms plus five deployment variants, but Windows support is half-broken (no launcher, community Task Scheduler) — environment_fit 2.
Documentation architecture (11 docs pages plus root specs), install notes, naming (verbs implemented once in cli/), demo/examples, known limitations ('read this first' security section), MIT LICENSE, CHANGELOG-driven releases with hook-enforced version gates all earn 3. Weak spot: maintenance responsibility — single maintainer, no governance, community-maintained Windows lifecycle config explicitly unsupported (1).
Output is a mobile-usable UI with tappable prompts, keys pad, voice input, and a no-install demo (output_usability 3). Clear marginal value over the Termux+SSH workflow (marginal_value 3). Cost: requires a tailnet, Bun, crew complexity, curl|sh installer, and non-trivial ops — cost_benefit 2.
Nearly every claim points at a specific file, test, or ADR (claim_traceability 3). Releases ship sha256 manifests with sidecars and binary self-checks of embedded docs; however this static review cannot corroborate external claims (e.g. the Herdr socket API) across sources, and demo-vs-real behaviour is unverified (cross_source_corroboration 2, fact_inference_separation 2 — facts and design rationale are interleaved but reasonably labelled).
- The project exposes remote-shell-grade capability by design: anyone with the URL can run arbitrary commands with your full user privileges. Restrict access to the tailnet, set COLLIE_TRUSTED_USER, and never tailscale funnel it.
- Writes are ungated until device pairing is enabled (per handlers.ts comments); pair a device immediately after first deployment.
- Pane output can contain source code, secrets, and environment variables; Collie performs no content-level redaction.
- Installation uses a curl | sh pattern; although sha256 is verified, review the script before running it.
- tmux/zellij and Windows support are experimental with very narrow testing; treat Herdr as the production target.
- Publisher is unverified and the project appears single-maintainer; long-term maintenance and security response capacity are uncertain.
What does this agent do, and when should you use it?
Collie is a mobile web interface for terminal-based AI agents, served over a Tailscale tailnet, connecting to one multiplexer per instance: Herdr (the primary supported target in 1.0), tmux, or zellij (both experimental). Architecturally it is a small supervised Bun bridge bound to loopback, fronted by a static React Router + Vite PWA; the browser polls /api/snapshot, and actions like replies and control keys are plain HTTP POSTs to /api/pane/:id/{reply,keys} that an adapter types into a real terminal pane. It exists because driving a TUI through Termux and SSH on a touchscreen is clumsy — Collie instead ranks agents awaiting input at the top of a dashboard, turns agent prompts like AskUserQuestion into tappable buttons, and provides a keypad for Esc, Ctrl+C, and arrow keys. It adds voice input, file attachments, Web Push notifications when an agent blocks, output search beyond scrollback, and a Pack protocol that aggregates several machines behind one URL with operator-triggered failover. It is deliberately single-user on one tailnet, and because it is remote shell access by design, its security model leans on tailscale serve identity injection and device pairing.
Collie runs a supervised Bun bridge on your host that picks one multiplexer adapter per install (bridge/mux/<name>/ — Herdr dials a Unix socket; tmux and zellij shell out to their CLIs), takes one snapshot per tick, and exposes a small JSON API. The browser loads the static PWA from web/dist and polls /api/snapshot; replies and keys POST to /api/pane/:id/{reply,keys} and are typed into a live terminal pane. The dashboard orders by pending user input; agents blocking on input trigger Web Push notifications. It supports per-agent quick actions and slash commands, one-tap replies from quick-replies.toml, voice dictation, image attachments from the camera roll plus markdown/text/code files, output search and full conversation history, device pairing tokens as the write credential, Herdr session switching from the web UI, and Packs that put several machines' Collies behind one URL. The default ingress is tailscale serve, which injects Tailscale-User-Login; you set COLLIE_TRUSTED_USER to your tailnet login.
- A developer running AI agents like Claude in tmux or Herdr panes who wants to resume sessions from a phone and answer AskUserQuestion-style permission prompts away from the desk
- An operator managing agents across several machines who wants one URL aggregating every Collie via a Pack, with failover to a standby when the lead fails
- A user who wants push notifications the moment an agent blocks on input, then replies via soft keyboard or voice dictation while commuting
- Anyone who needs to send Esc, Ctrl+C, or arrow-key chords to a terminal without fighting an on-screen terminal emulator
- Sending screenshots from the camera roll or log/code files to a running agent without returning to the computer
- A self-hosting enthusiast who wants no cloud accounts and keeps all traffic inside their own tailnet
What are this agent's strengths and limitations?
- Purpose-built mobile interaction: needs-input agents float to the top, agent prompts become tappable buttons, and a dedicated keys pad eliminates TUI chord gymnastics on a touchscreen
- Self-hosted with no cloud dependencies: the PWA runs locally on loopback, with layered defenses from tailscale serve identity injection plus per-device pairing tokens as the write credential
- The Pack protocol puts several machines' Collies behind one URL with operator-triggered failover to a standby
- Output search and full conversation history beyond terminal scrollback, plus voice input, file attachments, and six UI languages
- Single-user by design with no multi-tenant authentication — unsuitable for shared or public access; anyone with the URL can execute arbitrary commands with your full user privileges
- Strong Tailscale coupling on the default path: the happy path requires tailscale serve, which is unavailable on Windows, forcing Variant C reverse-proxy deployment with extra configuration (COLLIE_PUBLIC_HOSTS, COLLIE_MULTI_SESSION=off)
- tmux and zellij support is explicitly experimental in 1.0, tested by a single operator on one machine; Herdr is the only primary target
- Adoption adds a runtime and ops footprint: a Bun bridge process, a supervised service (restart bridge changes with systemctl --user restart collie), and git-hook-enforced versioning for contributors
How do you install or deploy this agent?
Run the one-line installer on the host (not your phone). It requires curl, tar, and a sha256 utility; no compiler toolchain and no sudo:
curl -fsSL https://colliepwa.dev/install.sh | shThe script downloads the latest release for your platform, verifies the sha256 checksum, installs the files, and puts collie on your PATH, then prints the remaining manual steps: seed a config, then run collie start. On first run, collie start detects Herdr, tmux, and zellij and prompts for your choice. Building from source is covered in docs/install.md.
How do you use this agent?
- Ensure your phone and host share a Tailscale tailnet with tailscale serve as the default ingress; set [email protected] in your .env. 2. Run collie start; the first run auto-detects your multiplexer. 3. Open the MagicDNS URL on your phone to see the dashboard ordered by agents needing input. 4. Tap an agent, type a reply, or use the keys pad for Esc/Ctrl+C/arrows; long-press pane pills or tab chips to rename or close them. 5. Configure slash commands and quick-replies.toml one-tap replies, and optionally enable voice input and Web Push. Never use tailscale funnel — it would expose Collie to the public internet.
How does this agent compare with similar options?
The README directly contrasts Collie with the usual Termux-to-SSH route of attaching to a terminal multiplexer session from a phone: driving a TUI through on-screen controls means fiddly special keys, awkward Ctrl/Esc/arrow chords, and text input that fights the soft keyboard. Collie replaces the terminal-shoehorned-onto-a-touchscreen approach with a native mobile interface.