Usage

Core command usage for `exec`, `ask`, `chat`, flags, examples, and agent selection.

On this page

exec turns a plain-English task into an interactive list of commands, with an explanation for each option:

bash
term-llm exec "list files"

Use ↑/↓ to highlight a command, i for detailed information, and Enter to execute your selection. Choose “something else…” to refine your request and get new suggestions, or Esc to cancel. Suggestions depend on your request and shell; review the command before running it.

By default, selecting a command runs it. --print-only changes that last step to printing the selected command instead; it is an optional mode, not the main exec workflow.

Use term-llm chat for a persistent session.

bash
term-llm chat

Using Agents#

Use the @agent prefix or --agent flag to select an agent:

bash
term-llm ask @reviewer "review this code"     # use reviewer agent
term-llm chat @codebase                        # explore a repository
term-llm loop @web-researcher --done-file ...  # use web-researcher agent in loop
term-llm ask @shell "find the 3 biggest files"

See Agents for more details on creating and managing agents.

Using Skills#

Skills inject task-specific context into any command without changing the model or provider:

bash
term-llm ask --skills git "how to squash commits"   # use git skill
term-llm chat --skills git,docker                   # combine multiple skills
term-llm edit --skills refactoring -f main.go "refactor this"
term-llm exec --skills devops "set up a cron job"

Use --skills all to load every available skill, or --skills none to suppress defaults.

Manage skills with the skills subcommand:

bash
term-llm skills                    # list all skills
term-llm skills new my-skill       # create a new skill
term-llm skills show git           # inspect a skill
term-llm skills browse             # browse available skills

See Skills for the full guide on creating, sharing, and extending skills with custom tools.

Chat Keyboard Shortcuts#

Key Action
Enter Send message
! command Run a shell command directly in the session directory; stream output, then ask the model to respond
Ctrl+J or Alt+Enter Insert newline
Ctrl+C Copy selection; cancel active response/tool/shell; press twice when idle to quit
Ctrl+K Clear conversation
Ctrl+S Toggle web search
Ctrl+P Command palette
Ctrl+T MCP server picker
Ctrl+L Switch model
Ctrl+N New session
Ctrl+F Attach file
Ctrl+O Conversation inspector
Esc Cancel streaming or a running ! shell command
Left click Move cursor in chat input
Shift+drag Select/copy chat output text in terminal

Type ! as the first composer character to enter shell mode, for example ! git status. The remainder runs through your configured $SHELL in the session’s effective directory (including a bound worktree) without tool approval, because it is an explicit direct user action. Combined stdout/stderr streams live; Esc or Ctrl+C cancels the process. term-llm keeps up to 64 KiB of output, records the command, directory, output, and exit status in the session, and automatically starts a model response even when the command fails. Pasting text that starts with ! into an empty composer also enters shell mode. Type a partial earlier ! command and press Tab to complete it from the current session; Up/Down history recalls shell commands without their captured output.

/shell remains available when you want an interactive terminal handoff rather than a captured command turn.

TUI attachments#

In term-llm chat, Ctrl+F or /file <path> attaches a local text file to the next message. Globs are supported by /file, and /file clear removes pending file attachments. The TUI reads file contents into the prompt as text, rejects binary files, and accepts text files up to 20 MB. Embedded file contents are wrapped in explicit begin/end markers so the model can tell where each attachment starts and ends. Very large text files can still exceed a model’s context window or cost more tokens.

Pasting an image from the clipboard attaches it as an image when the terminal/clipboard integration exposes image data. Pasted images use the same 20 MB decoded limit as web/API uploads.

Project and agent @ mentions#

In the TUI composer, type @ to search permitted agents and files or directories in the active project or worktree. Web chat currently searches project files and directories only. Press Enter or Tab to insert a result as editable text. File results follow worktree switches; project-local agent discovery uses the process startup directory because the session’s agent registry and runner are created there.

File syntax remains @path/to/file, @"path with spaces", or @file.go#L10-20 for a line range. Bare @name is always file/text syntax. Selecting or typing an agent uses the explicit @agent:codebase form (or @agent:"name with spaces" when needed). @agent: searches agents only, while path-like queries such as @internal/ search files only.

Mentioned text files are read when the message is submitted and appear in the conversation’s [with: ...] annotation. Directories attach a non-recursive name listing. An explicit file mention authorizes that bounded read, which remains confined to the active project or worktree; missing, escaped, binary, oversized, or otherwise unreadable paths do not block sending.

An explicit @agent:name asks the active model to call its already-authorized spawn_agent tool once for that agent; selecting a result does not launch anything directly. The agent must still be registered, allowed by the current session/tool filter and whitelist, below the depth limit, and resolvable by the live runner. Invalid or stale explicit agent mentions block that submission and leave the draft and attachments intact. This delegation syntax is separate from /handover @name, which switches conversation context, and from term-llm chat @name, which chooses the startup agent.

Set TERM_LLM_AT_MENTIONS=0 to disable @ autocomplete and submit-time textual file/agent mention semantics in the TUI. The serve/web composer and one-shot ask surface do not currently provide agent-delegation mentions; use spawn_agent through their normal tool flow instead.

Chat Slash Commands#

Command Description
/help Show help
/clear Clear conversation
/model Show current model
/search Toggle web search
/fast Toggle fast/priority service tier for supported OpenAI/ChatGPT models
/mcp Manage MCP servers
/goal Set, edit, pause, resume, clear, or show the persistent session goal
/side <question> Ask a private, tool-less one-turn question without interrupting or changing the main conversation
/commit [intent] Review, stage, draft, and create a Git commit in the active checkout
/share [new] [raw] [public|unlisted|private] Share the complete session through the configured provider; raw explicitly opts into privacy-sensitive raw reasoning
/quit Exit chat

When web search is enabled, the chat status line shows web; when fast service tier is enabled, it shows fast.

In the web UI, typing / opens an alphabetized command menu. /compact manually compresses the active conversation context without adding a user message; /commit opens the native Git workflow; /goal, /mcp, and /model open their existing controls; /new starts a fresh conversation; and /side opens a side question.

Native Git commits#

If changes are already staged, /commit immediately asks Commit everything or Commit staged. If nothing is staged, plain /commit stages everything; explicit natural-language scope intent may instead propose a reviewed subset.

/commit [intent] works in both terminal chat and the Web UI. It always uses the active session checkout, including a session-bound linked worktree. Existing staged content is never silently widened or replaced: choose Commit staged to preserve the index exactly, Commit everything to run git add -A, or Follow request to ask the configured commit agent for a whole-file proposal. Partially staged files are identified because committing their staged portion, staging their complete working copy, and selecting/excluding the whole file have different results.

With an empty index, plain /commit visibly stages all tracked, deleted, renamed, and non-ignored untracked changes. Intent such as mention issue #482 may resolve to the same all-changes flow. Narrowing intent such as only the checkbox changes produces checked included paths and unchecked excluded paths for adjustment before the index changes. If included and excluded concerns share a file, the planner must return needs manual rather than pretending whole-file selection can separate them.

The message agent drafts from git diff --cached only. Its result is editable; generation can be retried or skipped, and a manual message remains available when the agent/provider fails. Confirmed staging persists if the dialog is cancelled. Immediately before committing, the host rechecks checkout identity, born/unborn HEAD, operation state, and the exact index tree. Normal hooks and signing run non-interactively; failures keep the message and refreshed status. Merge, cherry-pick, revert, rebase, sequencer, conflict, empty-index, stale-review, and index-lock states are blocked with guidance. A started commit is drained to a verified result rather than killed on Esc or browser disconnect.

In the Web UI, the completed commit dialog offers Push and Make PR alongside Done. Push starts immediately with one click; Make PR opens the PR editor. Push publishes only the reviewed commit and its branch history, without force-pushing, tags, other branches, or uncommitted changes. The destination uses the branch’s push remote, remote.pushDefault, tracking remote, or an unambiguous default remote; ambiguous or multi-URL destinations require configuring Git first.

Make PR lets you edit the head branch, base, title, description, and draft status. It pushes first and uses authenticated gh to create a PR in the push repository, or returns an existing open PR for the same head/base. On the default branch it suggests a new remote PR branch; this does not switch or reset your local branch. If you have already pushed the commit to the base branch, there may be nothing left to propose. Fork-to-upstream PRs are not configured by this dialog; use gh directly for that workflow. Publishing runs in the background with reconnectable operation IDs. Push/PR errors never undo the local commit, and partial push success is shown separately from PR creation failure.

Side questions#

/side <question> opens an overlay over the current TUI or web conversation and sends immediately. /side alone opens or reopens the overlay with its dedicated Ask a follow-up… composer focused. The main answer keeps running and remains visible. Each send is an independent one-turn provider request with no local tools, MCP, search, approvals, attachments, model picker, slash commands, queue, or subagents. It forks from the current completed provider boundary, including complete tool-call/result cycles already produced during the active main turn while excluding the pending assistant response. Existing cache anchors are preserved so the shared main prefix remains cacheable. Up to 20 successful side exchanges are kept only in the active runtime’s memory. Side questions are never added to the transcript, resume state, exports, search index, compaction input, title input, or session message count.

Side exchanges appear chronologically in one compact scrollable transcript, using the same user-message and Markdown assistant styling as the main conversation without redundant role labels. After an answer completes, the pinned single-line side composer accepts a follow-up with Enter. While answering, the composer is unavailable and Esc cancels only the side request while leaving the overlay open. When idle, Esc first clears a non-empty side draft, then closes the overlay when the draft is empty. In the TUI, PageUp/PageDown or Ctrl+Up/Ctrl+Down scroll the transcript, mouse drag selects visible overlay text, Ctrl+C closes the overlay unless text is selected (in which case it copies the selection), and Ctrl+X twice clears history. In the web overlay, text uses native browser selection and the close button cancels an active side request before closing. Main composer draft, session, transcript position, and main cancellation remain independent.

Side history is intentionally lost on a new/cleared/resumed session, runtime eviction, or process/server restart. Promotion or merging a side answer into the main transcript is not supported; copy it or restate the conclusion in the main conversation.

Persistent goals#

Use /goal in chat when you want the agent to keep pursuing a durable objective across automatic continuations:

text
/goal set finish the migration and verify every test
/goal set --budget 50000 finish the migration and verify every test
/goal edit finish the migration, update docs, and verify every test
/goal pause
/goal resume
/goal clear

An active goal is stored with the session, so it survives reloads and can continue from the TUI, web UI, or other runner-backed surfaces. While a goal is active, term-llm injects goal-steering prompts between turns and exposes get_goal/update_goal tools to the model. The model should call update_goal only when the objective is genuinely complete or strictly blocked; otherwise the runner continues until the goal is paused, completed, blocked, cancelled, or its optional token budget is exhausted. The status line shows a goal chip with token usage when a goal is present.

Changing sessions, compacting, handing over, or switching models pauses the current goal so the next turn does not unexpectedly continue old work.

Flags#

Flag Short Description
--provider Override provider, optionally with model (e.g., openai:gpt-5.2)
--file -f File(s) to include as context (supports globs, line ranges, ‘clipboard’)
--auto-pick -a Auto-execute the best suggestion without prompting (exec only)
--agent -a Use a specific agent (ask/chat only; see also @agent syntax)
--skills Skills mode: all, none, or comma-separated names
--max N -n N Limit to N options in the selection UI
--search -s Enable web search and page reading (see Search for providers)
--native-search Use provider’s native search (override config)
--no-native-search Force external search tools instead of native
--print-only -p Print the command instead of executing it
--debug -d Show provider debug information
--debug-raw Emit raw debug logs with timestamps (tool calls/results, raw requests)
--json Emit JSONL event stream on stdout, one event per line (ask only; see below)
--system-message -m Custom system message/instructions
--stats Show session statistics (time, tokens, tool calls)
--no-session Disable session persistence for this command
--session-db Override sessions database path (supports :memory:)
--max-turns Max agentic turns for tool execution (default: 50 for ask/exec, 200 for chat)
Tool concurrency When a model emits many parallel tool calls in one turn, term-llm runs at most 20 tool calls concurrently and queues the rest for that turn.
--approval Approval mode for this run: prompt, guardian-reviewed auto, or yolo
--auto Compatibility alias for --approval auto
--yolo Compatibility alias for --approval yolo; bypasses approval prompts

Note: The -a short flag has different meanings:

  • In exec: -a is --auto-pick (auto-execute best suggestion)
  • In ask/chat: -a is --agent (use a specific agent)

Examples#

bash
term-llm exec "list files by size"              # interactive selection
term-llm exec "compress folder" --auto-pick     # auto-execute best
term-llm exec "find large files" -n 3           # show max 3 options
term-llm exec "install latest node" -s          # with web search
term-llm exec "disk usage" -p                   # print only
term-llm exec --provider zen "git status"       # use specific provider
term-llm exec --provider openai:gpt-5.2 "list"   # provider with specific model
term-llm exec --debug-raw "list files"          # raw debug logs with timestamps
term-llm exec --provider ollama:llama3.2 "list" # use local Ollama model
term-llm exec --provider lmstudio:deepseek "list"  # use LM Studio model
term-llm ask --provider openai:gpt-5.2-xhigh "complex question"  # max reasoning
term-llm exec --provider openai:gpt-5.2-low "quick task"         # faster/cheaper

# With file context
term-llm exec -f error.log "find the cause"     # analyze a file
term-llm exec -f "*.go" "run tests for these"   # glob pattern
git diff | term-llm exec "commit message"       # pipe stdin

# Ask a question
term-llm ask "What is the difference between TCP and UDP?"
term-llm ask "latest node.js version" -s        # with web search
term-llm ask --provider zen "explain docker"    # use specific provider
term-llm ask -f code.go "explain this code"     # with file context
term-llm ask -f code.go:50-100 "explain this function"  # specific lines
term-llm ask -f clipboard "what is this?"       # from clipboard
cat README.md | term-llm ask "summarize this"   # pipe stdin
term-llm ask --debug-raw "latest zig release"   # raw debug logs with timestamps
term-llm ask --json "explain git rebase" | jq -c .   # JSONL event stream

# Edit files
term-llm edit "add error handling" -f main.go
term-llm edit "refactor loop" -f utils.go:20-40  # only lines 20-40
term-llm edit "add tests" -f "*.go" --dry-run    # preview changes
term-llm edit "use the API" -f main.go -c api/client.go  # with context

# Generate images
term-llm image "a sunset over mountains"
term-llm image "logo design" --provider flux    # use specific provider
term-llm image "make it purple" -i photo.png    # edit existing image

# Generate videos (Venice AI)
term-llm video "a corgi surfing at sunset"
term-llm video "make Romeo blink" -i romeo.png
term-llm video "astronaut on mars" --quote-only

JSON event stream (ask --json)#

term-llm ask --json emits a newline-delimited JSON (JSONL) event stream on stdout, one event per line, for scripting and automation. It implies --text (no rich terminal rendering) and is incompatible with --debug-raw. Human progress and warnings stay on stderr.

Every event shares an envelope:

json
{"type": "text.delta", "seq": 3, "ts": "2026-04-19T10:30:00.123456789Z", "text": "Hello"}

Event types, in typical order:

Type Payload
session.started session_id, provider, model, agent, tools, mcp, yolo, search, resuming
text.delta text, one chunk of streamed response
tool.started call_id, name, info, args (raw JSON or null)
tool.completed call_id, name, info, success
usage input_tokens, output_tokens, cached_input_tokens, cache_write_tokens
phase phase
retry attempt, max, wait_seconds
image path
diff path, old, new, line
progressive.result exit_reason, finalized, plus optional session_id/sequence/reason/message/progress/final_response/fallback_text (only with --progressive)
error message
stats duration_ms, llm_ms, tool_ms, token counts, tool_calls, llm_calls
done tokens

The last two events are always stats then done, even on context cancellation or errors. seq starts at 0 and strictly increments.

Search documentation

Search commands, flags, workflows, and concepts.