Documentation v0.3.2
Earshot / Using Earshot

CLI reference

Every command, flag, interactive command, and exit code.

Reviewed for 0.3.2 · Latest documentation

Synopsis#

earshot [flags]                   start the interactive TUI
earshot -p "<prompt>" [flags]     one headless turn
earshot models [filter] [flags]   list the model catalog
earshot auth <login|list|logout>  manage credentials
earshot mcp <list|trust|untrust>  manage MCP servers
earshot extensions <list|trust|untrust>  manage in-process extensions
earshot acp [flags]               serve editor clients over ACP v1 on stdio
earshot doctor                    diagnose the local setup
earshot update [--check]          update earshot to the latest release

Global flags#

FlagDescription
--version, -vPrint the version and exit
--help, -hPrint help and exit
--model &lt;ref&gt;Model for this run, as provider/model or a bare model id
--no-onboardingSkip first-run onboarding; missing credentials exit 3 like before

earshot -p#

Runs a single non-interactive turn and prints the response.

earshot -p "explain the provider registry"
earshot -p "hello" --model openrouter/anthropic/claude-opus-5
earshot -p "hello" --output-format json
FlagValuesDefault
--model &lt;ref&gt;any earshot models referenceanthropic/claude-opus-5
--output-format &lt;fmt&gt;text, json, stream-jsontext
--image &lt;path-or-url&gt;PNG, JPEG, GIF or WebP path, or HTTPS URLnone
--max-cost &lt;usd&gt;session ceiling, e.g. 2.50 or $2.50; 0 removes onenone
--curiosity &lt;level&gt;low, normal, highnormal

Output formats

  • text — response text streamed to stdout as it arrives
  • json — one result object at the end
  • stream-json — newline-delimited records as they arrive, ending with the same result object

Both JSON formats are a versioned contract; see Headless output for the schema and what earshot.v1 promises. json@v1 pins it explicitly.

Ctrl-C aborts the request; partial output is kept.

--max-cost is checked before each model call, not after the spend. Headless has no one to ask, so reaching the ceiling stops the turn and exits 3 — distinct from 1 so a script can tell "ran out of budget" from "failed". Interactive prompts to stop, double the ceiling, or remove it. Both read maxCostUsd from settings when the flag is absent.

--curiosity moves how readily the agent stops to ask: low decides and states the assumption, high asks whenever a second reading is plausible. It never turns asking off and never makes it free — see Listening.

--image attaches one image to the prompt. Local files are capped at 20 MB and encoded into the append-only transcript; HTTPS URLs stay references for the provider adapter. A model without the vision capability is rejected before a request is made. The same flag attaches to an initial interactive TUI prompt.

earshot auth#

earshot auth list                              # where each provider's credentials come from
earshot auth login openrouter                  # PKCE sign-in in a browser
earshot auth login groq --api-key gsk_...      # store a key
earshot auth logout groq                       # forget the stored one

logout removes what is in auth.json. An environment variable still applies afterwards, and it says so.

earshot mcp#

earshot mcp list             # configured servers; starts nothing
earshot mcp trust helper     # let a project-scope server start
earshot mcp untrust helper

See Extending earshot for why a project-scope server needs trusting and a global one does not.

Past 25 MCP tools, their schemas are no longer sent with every request. The model gets a tool_search tool and finds them by what it wants to do; a surfaced tool stays listed for the rest of the session and is gated exactly as a listed one is.

earshot extensions#

earshot extensions list      # modules found; imports nothing untrusted
earshot extensions trust jira
earshot extensions untrust jira

In-process TypeScript or JavaScript modules that contribute tools, from .earshot/extensions/ or the config directory. See Extending earshot — an extension is not sandboxed, so a project one is inert until trusted.

earshot acp#

Runs the stable ACP v1 server used by Zed and other ACP-capable editors:

earshot acp --model anthropic/claude-opus-5

It is a stdio protocol command, not an interactive terminal command. The model, API key and permission-mode flags become defaults for sessions the editor opens. See Editor integration with ACP for the supported protocol surface and the reproducible Zed, JetBrains and Neovim QA checklists.

earshot models#

Lists the model catalog with context windows, pricing and capabilities.

earshot models              # everything
earshot models opus         # filter by id, provider or name
earshot models --json       # machine-readable
earshot models --refresh    # fetch live from models.dev first
FlagDescription
--jsonEmit the full Model objects instead of a table
--refreshFetch a fresh catalog from models.dev rather than the snapshot

Output columns: model reference, context window, price (USD per million tokens, input/output), and capability tags (reasoning, vision, no-tools).

Filtering is a case-insensitive substring match against the model id, the provider id and the display name.

earshot doctor#

Runs local diagnostics without contacting a model provider or printing secrets. It checks the earshot and Node versions, platform, Git, Bash (Git Bash on Windows), writable config/data locations, settings JSON, and POSIX auth-file permissions. PASS and WARN checks exit 0; any FAIL exits 1.

earshot update#

Updates earshot in place, whichever way it was installed.

earshot update            # check, confirm, update
earshot update --check    # report only; exit 4 if an update is available
earshot update --yes      # skip the confirmation

It works out how the running earshot got here before it does anything. A standalone binary is a Bun --compile executable, so its entry module lives in Bun's $bunfs virtual filesystem rather than on disk — that path is the signal. process.versions.bun is not, since it is equally set when running from a source checkout under Bun, and the executable's filename is not, since it is whatever it was renamed to.

Installed with npm. Compares against the npm registry and, on a global npm install, offers to run:

earshot 0.2.0  ->  0.3.1   (installed with npm, globally)

  npm install -g @raegent/earshot@latest

run it now? [y/N]

If the package sits in a bun, pnpm, yarn or Volta tree instead, that manager's command is printed and nothing is run — npm install -g over one of those does not replace the install, it adds a second copy at another prefix and leaves PATH order to decide which one wins. A project-local install is printed too, not run.

Standalone binary. Downloads the release asset matching this host, verifies it against the SHA256SUMS published with every release, and only then puts it in place. A mismatch replaces nothing.

earshot 0.2.0  ->  0.3.1   (standalone binary)
  /Users/you/.local/bin/earshot   earshot-darwin-arm64

download earshot-darwin-arm64 and replace it? [y/N] y
  downloading… verifying SHA256… replacing…
updated to 0.3.1

The download lands in the target's own directory, not the temp directory, so the final step is a same-filesystem rename rather than a copy across devices. On POSIX that rename is atomic and the running process keeps executing from the inode it already opened. On Windows a running .exe cannot be deleted or overwritten, but it can be renamed on the same volume, so the running image is moved to earshot.exe.old-&lt;pid&gt; and the new one takes its place; deleting that leftover fails while the process lives, and the next earshot update sweeps it.

Assets are fetched through the GitHub asset API rather than the releases/download/… browser URL, because that URL ignores a bearer token and answers 404 for a private repository. While this repository is private, a binary update needs a token: set GITHUB_TOKEN (or GH_TOKEN, or EARSHOT_GITHUB_TOKEN) to one that can read the repository. Without it every release URL returns 404, and earshot update says so rather than repeating the status. The npm path needs no token — that package is public.

A symlinked binary is resolved first, so the file is replaced rather than the link. Running from a source checkout is not updatable and exits 2 — use git. Without a TTY to answer the prompt, it reports and changes nothing.

Model references#

provider/model is unambiguous and always works:

--model anthropic/claude-opus-5
--model openrouter/anthropic/claude-opus-5

A bare model id resolves against the first provider offering it, in registration order — convenient, but pin the provider in scripts, since the same model is often served by several.

In-session commands#

Typed at the prompt during an interactive session.

CommandEffect
/helpList the commands you can type
/model [ref]Show the model in use, or switch to another for the rest of the session
/mode &lt;plan|ask|accept-edits|auto|yolo&gt;Change the permission mode
/plan &lt;task&gt;Draft a plan in plan mode and write it to a file
/plan editOpen the plan in $VISUAL/$EDITOR, or print its path
/plan approvePin the plan as the file now reads for the rest of the run
/plan showRead the plan back
/plan clearUnpin the plan
/compactSummarise the session so far and free up the context window
/contextShow what is in the context window and what compaction has dropped
/cost [usd]Show what this session has spent, or set the budget ceiling; 0 removes it
/todoShow the agent's current todo list
/permissionsShow the permission mode and the rules in force
/initWrite an AGENTS.md describing this project
/skillsList discovered skills and user-defined commands
/memoryList remembered preferences, each with the sentence it came from
/memory forget &lt;id&gt;Delete one remembered preference
/treeList this session's prompts, numbered
/rewind &lt;n&gt;Go back to the state before prompt n; nothing is deleted
/fork &lt;n&gt;Branch from prompt n into a new transcript
/undoRevert the last tool batch's file changes; again to step back further
/exitQuit
/&lt;name&gt;Run a user-defined command from .earshot/commands/&lt;name&gt;.md

This table is checked against the command registry in packages/tui/src/commands.ts by packages/tui/test/commands.test.ts, which is also what the in-session / menu reads: a command cannot be documented without being dispatchable, or dispatchable without appearing in both.

/model switches for the rest of the session, resolving the reference through the same registry and credential order the CLI uses; a reference with no credentials is reported and the session stays on the model it had.

/cost with an amount is the same ceiling as --max-cost, and 0 removes it the same way. /compact runs the compaction that would otherwise happen at 80% of the window — it appends a summary and never rewrites history, exactly as the automatic one does.

Typing / opens that menu and each further keystroke filters it. / move the selection, tab completes the highlighted command into the line without running it, enter runs it, and esc closes the menu — esc interrupts a turn only when the menu is not open.

Two keystrokes are bound rather than typed: when a prompt contains a correction ("use bun, not npm"), ctrl+r remembers it for this project and ctrl+g everywhere. Nothing is remembered unless you press one.

Exit codes#

Meaningful, so CI can branch on them:

CodeMeaning
0Success
1Request failed, provider/network error, or step limit
2Invalid usage, model reference, image, or output format
3Missing credentials, or session budget reached
4Update available for update --check; missing shell during headless startup
130Interrupted headless run

Environment variables#

VariableEffect
EARSHOT_CONFIG_DIROverride the config directory (default ~/.config/earshot, %APPDATA%\earshot on Windows)
EARSHOT_DATA_DIROverride the data directory (sessions)
EARSHOT_GITHUB_TOKEN, GITHUB_TOKEN, GH_TOKENRead access for earshot update's binary path, in that order of preference. Required while the repository is private
OLLAMA_HOSTOllama base URL (default http://127.0.0.1:11434)
provider keysSee Providers
Something unclear?Suggest a correction on GitHub ↗