termic.dev
Documentation menu

Termic CLI: drive Termic from any shell

Create tasks, prompt agents, wait for them to finish and read results with the termic command. Includes scripting with JSON output and exit codes, and letting agents dispatch work to other agents.


Termic ships a termic command that drives the running app from any shell. Anything you do by clicking — create a task, prompt an agent, wait for it to go quiet, check a diff, archive it — has a verb, so the same workflow fits in a script, a Makefile target, or another agent’s hands.

The app itself is the daemon. Every command talks to the running Termic over a local socket and fails fast when it cannot, so a command never silently half-works.

Getting the command

The CLI is enabled by default and installs itself on first launch. Termic automatically drops the command into ~/.local/bin/termic in the background, without a prompt. If that directory is not on your PATH, Settings → Termic CLI offers Install system-wide, which symlinks into /usr/local/bin instead and asks for your password.

Check it works:

termic --version
termic list

If termic list reports that the app is not running, launch Termic and try again, or pass --no-launch to make that an explicit failure instead of auto-launching.

Your first commands

Run these from inside a repo you have registered as a project. Most verbs resolve the task from your current directory, so you can usually leave the name out.

# Create a task, start its agent, and give it something to do
termic new fix-auth -p "fix the login redirect"

# See everything that is running
termic list

# Block until that agent stops
termic wait fix-auth

# Prompt an agent that is already running
termic send fix-auth -p "now add a regression test"

# Where does its worktree live?
cd "$(termic path fix-auth)"

new returns as soon as the agent spawns. Add --wait to block until the prompt is confirmed delivered and that turn settles.

Targeting a task

Most verbs take an optional task name. When you omit it, the task is resolved from your working directory.

FormMeaning
termic statusThe task your shell is currently inside
termic status fix-authBy name
termic status myrepo/fix-authQualified, when two projects share a name
termic status --project myrepo fix-authSame, explicitly
termic status --tab 2One tab inside the task, by index, id, or title

A selector that matches nothing is a typed error naming the candidates, rather than a silent default. Tasks can hold several tabs, so send, logs, wait and friends all accept --tab to aim at one.

Getting results out

This is the part worth reading twice, because it surprises people: the agent’s terminal output is not readable from the CLI. logs and result can peek at a running agent, but they are not a reliable machine-readable channel.

For anything scripted, ask for a file in the prompt and read it afterwards:

termic new audit -p "review the auth module; write your findings to RESULT.md" \
  --sandbox enforce --wait
cat "$(termic path audit)/RESULT.md"

Two details that make unattended runs actually work:

  • Pass --sandbox enforce or --yolo. Otherwise the agent stops to ask for permission and your script waits forever. Permission prompts self-approve inside the cage.
  • --wait exiting 0 means the agent stopped, not that the work is correct. Settle detection is a heuristic. Check the artifact, not the exit code alone.

Letting agents drive other agents

Every task’s terminal is handed TERMIC_CLI, TERMIC_TASK_ID and a short TERMIC_CLI_HELP in its environment. An agent working inside Termic can therefore discover the CLI with no setup and dispatch work to other tasks: fan a job out across several agents, wait on them, and read back what they produced, without you brokering it.

# From inside an agent's own terminal
"$TERMIC_CLI" new schema-check --sandbox enforce --wait \
  -p "check the migrations for destructive changes; write to RESULT.md"
cat "$("$TERMIC_CLI" path schema-check)/RESULT.md"

Two guardrails apply here:

  • Agents running in an enforced sandbox never get access. The control socket is outside the cage, so a caged agent that tries gets an explicit “control plane unavailable” refusal rather than a hang.
  • The auth token is deliberately never placed in any child’s environment, so an agent cannot stash it and hand a caged sibling a way in.

Have the agent rename its own task once it knows what it is really working on, so your sidebar stays readable:

"$TERMIC_CLI" rename "fix the login redirect"

Scripting: JSON and exit codes

Every verb takes --json (one object on stdout) or --output-format stream-json (NDJSON events ending in exactly one result line). Fields only ever grow, so parsing is safe across upgrades.

termic list --json | jq -r '.tasks[] | select(.state == "idle") | .name'

Branch on the exit code rather than scraping text:

CodeMeaning
0Success. With --wait, the agent settled
1Error: bad task or project name, ambiguity, server failure
2Usage error
3The agent stopped but is asking for input
4Termic is not running (with --no-launch)
5The CLI is disabled in Settings
6Refused
7--timeout expired
8Connection lost
9The prompt was never delivered

Exit 3 is the one worth handling explicitly: the agent is alive and blocked on a question, which is very different from failing.

termic help --json prints the entire command surface machine-readably, which is the fastest way for a script or an agent to learn what is available on the version actually installed.

A shell is not the only thing outside Termic that might want to start a task. A termic:// URL opens a pre-filled New Task dialog:

termic://new?project=web&worktree=1&name=fix-login&p=Fix%20the%20login%20bug
ParameterWhat it sets
projectWhich project the task belongs to
worktree1 for a worktree task, otherwise the main checkout
nameThe task name, which also fills the branch field
pThe first message, URL-encoded

The link only fills the form. A human still presses Create, and that is the entire security model: any page that can navigate to a URL scheme can hand you a prompt, so nothing is allowed to run on arrival. You read what it wants before it happens.

This is what makes an internal dashboard, a bug tracker or a wiki able to offer “open this in Termic” without either side integrating with the other.

Security

Access is gated by a per-boot token stored in Termic’s data directory with 0600 permissions, so only your own user account can read it. Enabling the CLI does not open a network port and does not widen what another user on the machine can reach.

You can turn it off at any time in Settings → Termic CLI. Turning it off refuses every command immediately, and the command stays installed so re-enabling costs nothing.

Last reviewed: August 10, 2026