@termiq/cli
v3.48.0
Published
Run Claude Code, Gemini CLI, or any shell over SSH/CI and control it from your phone — push on done/waiting/error, answer Y/n from the notification. End-to-end encrypted.
Maintainers
Readme
@termiq/cli
Run Claude Code, Gemini CLI, Cursor, or any shell over SSH or in CI — then walk away. TermIQ streams the session to your phone at termiq.io, pushes you the moment it finishes or stops to ask, and lets you answer Y/n right from the notification. Your machine does the work; your phone keeps you in control.
End-to-end encrypted — the TermIQ server is a blind relay that streams your output, never stores it.
Why the CLI
The headless half of a long-running task is exactly where you can't sit and watch — a remote box over SSH, a CI runner, an unattended host. Start the work, leave, and let TermIQ tell you when it needs you:
- Push the moment it matters — get notified when a task completes, is waiting for a confirmation, or an AI agent fails, even with your phone in your pocket.
- Answer from the notification — approve a
Y/nprompt without opening anything; the answer goes straight to the terminal. - Reliable input — what you type from your phone reaches the terminal in order, even on a flaky mobile connection.
- Real-time sync — output streams to your phone with sub-second latency and reconnects on its own when the network changes.
- End-to-end encryption — terminal content is encrypted on your devices (XSalsa20-Poly1305); the server relays encrypted bytes it can't read. Streamed, never stored.
Works with Claude Code, Gemini CLI, Cursor, and any other terminal program — TermIQ mirrors whatever runs in the shell, so there's nothing AI-specific to configure.
Install
Requires Node.js 18+ and a free TermIQ account.
npm i -g @termiq/cliThe installed binary is termiq.
Usage
termiq # Start: spawn a shell + connect to termiq.io
termiq login # Authenticate via browser (Device Code Flow)
termiq login --token KEY # Authenticate with an API key
termiq logout # Clear stored credentials
termiq status # Show current authentication state
termiq --help # Show helptermiq spawns a new shell in your current terminal and connects it to termiq.io. Open termiq.io on your phone to watch and drive the session live. End the shell with exit or Ctrl+D to disconnect. (Running termiq inside an existing session is blocked so you don't nest by accident — pass --force to override.)
Headless / CI / SSH
For unattended hosts and pipelines, authenticate with an API key. Create one at termiq.io/settings/api-keys (keys are prefixed tiq_), then either log in with it:
termiq login --token tiq_your_api_key…or provide it through the environment — equivalent to --token, and convenient for CI:
export TERMIQ_TOKEN=tiq_your_api_key
termiqCheck the connection with termiq status; sign out with termiq logout.
Flags
| Flag | Description |
|-------------------|---------------------------------------------------------------------|
| --server URL | Override the server URL (default: https://termiq.io) |
| --token KEY | API key for headless login |
| --watch, -w | Enable the file watcher (off by default; respects .gitignore) |
| --statusline | Show a tmux-style status bar in the local terminal (off by default) |
| --verbose, -v | Verbose logging to stderr |
| --log-level L | Log verbosity: silent | error | warn | info | debug |
| --log-to-file | Write logs to ~/.termiq/logs/cli.log |
| --force | Start even when already inside a TermIQ session (nested run) |
| --multi-viewer | Latest-wins geometry: the pty follows whoever typed or resized last, and other viewers mirror it. Off by default (the size is the smallest viewer's). Persists in config.json |
| --push-prompt-text | No effect, still accepted so existing scripts keep working: notifications never carry the prompt's text — see Notifications and privacy |
| --no-signal-waiting | Ignore the agent's own "waiting" signal. On by default: Codex and Gemini announce that they are waiting in the window title, so you still get notified even when TermIQ's own parsing misses the prompt (you get a plain input box rather than buttons). Persists in config.json |
| --version, -V | Print version and exit |
On your phone
Open termiq.io in your mobile browser, sign in with the same account, and add it to your home screen to install the PWA and enable push (iOS 16.4+ / Android). Set Quiet Hours to silence notifications overnight. With --watch on, the app also shows which files your session touched (respecting .gitignore), so you can follow along without opening an editor.
Notifications and privacy
When an agent stops and asks something, the notification tells you that a terminal is waiting — not what it asked. The question and its buttons reach your phone over the encrypted channel and are readable only by your own devices; the server relays ciphertext and cannot open it.
Notifications never carry the question, whatever the settings: the server puts
no terminal text into them. --push-prompt-text, which used to put the question
in the notification body, no longer has any effect; the CLI still accepts it so
that existing scripts keep working.
When an agent fails
You get a notification when an AI agent (Claude Code, Codex, Gemini CLI,
Copilot, Cursor Agent, Aider and others) exits with an error, and when the
shell itself is killed, by the out-of-memory killer for example. Stopping an
agent with Ctrl+C, a clean exit, a failing command that is not an agent (a
build, grep, git) and the shell staying open after the agent are not
failures. The notification says only that the task failed, never the error. One
failure gives one notification, and a terminal gives at most one a minute.
Only the shell knows how a command inside it ended, so termiq starts bash and
zsh with a small hook that reports the exit code and the program name of each
command to the CLI, in a sequence your terminal ignores. Each hook signs its
reports with a random value only its shell knows, so text that merely passes
through the terminal, a file you cat or the output of a remote host, cannot
fake a failed agent. The hook only adds itself: your ~/.bashrc or .zshrc
load as usual and are never changed, and its file lives in a private temporary
directory while the shell runs. Other shells, and every shell on Windows, start
as before; there a failed agent is noticed only if your own shell integration
reports command ends (OSC 133). Set TERMIQ_SHELL_INTEGRATION=0 to start bash
and zsh without the hook.
When the buttons don't appear
Agents change their interfaces, and a redesign can leave our parsing behind — it has happened. Codex and Gemini also state plainly in the window title that they are waiting for you, and TermIQ reads that as a second opinion: if the prompt was missed, you still get the notification and a plain input box to answer by hand. Claude has no such signal, so nothing changes there.
Turn it off with --no-signal-waiting if it ever starts firing when nothing is
actually waiting.
Configuration
Configuration and credentials live in ~/.termiq/:
config.json— server URL, agent name, and the opt-in flags abovecredentials— authentication tokens (stored withchmod 0600)logs/cli.log— log file (written when--log-to-fileis set)
Command-line flags override values from config.json.
Plan
Free forever — 1 agent and 2 terminals, no credit card required.
