Interactive Commands
All commands are typed at the TUI prompt, prefixed with /. A slash word that matches nothing (/nonsense) is not sent to the model: cast says Unknown command /nonsense and suggests the nearest commands. Text that only starts with a slash, such as a path (/tmp/shot.png what is this?), is still a normal message.
New to the screen? The Terminal Screen is the tour: what is on it, how to type, scroll and choose, and how to fit it to a phone.
Running a Shell Command: !
A line that starts with ! is run as a shell command by you, not sent to the model: !git status, !npm test, !ls src. It works in the terminal, in the web composer and over cast run ({"type":"shell","command":"git status"}), and there is no model turn.
- Where. In the session's working folder (a worktree the session moved into counts).
- What you see. The command as you typed it, then what it printed, in the thread.
- What the model sees. The command and its output are added to the conversation as a message that says you ran it, so your next message can refer to it ("fix what that printed") and the model does not think it ran it itself. It stays in the saved session and survives a restart.
- Same gates as the
bashtool. In plan mode only read-only commands run; anything that could write is refused with the reason, and nothing is added to the conversation. A command that matches a dangerous pattern (rm -rf,sudo, force-push, ...) asks first, in the same confirmation the agent's commands use; in a mode that never asks (bypass) it runs. Output is cut at the same limits as thebashtool's and a command stops at its timeout. - Not while a turn is running. The turn works on its own copy of the conversation, so the command waits: stop it first (
Esc Esc,/abort) or wait. !!. A message that should start with a!goes to the model with two:!!important: fix itsends!important: fix it. A lone!says how to use this.- A failing command is shown (with its exit code) and added like any other; the person asked, so the model should know it failed.
- Attached to a daemon, the daemon runs it, in its own working folder for the session, and the result arrives on every screen attached to that session.
Session Management
| Command | Description |
|---|---|
/new | Start a new session (autosaves current if non-empty) |
/continue | Resume the most recent session (like cast -c, but mid-session) |
/fork | Branch into a new session: the whole current context, the conversation before one of your messages, or (web UI, /fork after <seq>) through one of the agent's answers |
/worktree <name> | Switch current session into an isolated git worktree (list, remove <name>) |
/sessions | Session picker: the sessions of the directory you are in, with Show all sessions one row down (and Only this directory to come back); ←, → or Tab flip between the two views. Type-to-filter search (message text, project path, id) stays inside the scope you are in; switch or delete. A session with no messages is not listed |
/clear | Clear conversation context (and save the cleared state) |
/compact | Force context compaction now (auto-triggers near the limit) |
/dream | Verify the recent project trajectory and consolidate durable project memory |
/distill | Verify repeated work and package high-confidence workflows as a skill or persona |
/rewind | Rewind to before a chosen message: the files, the conversation, or both (any turn, not only the last) |
/undo [--force] | Undo the last turn: put the files back as they were before it and remove your last message and everything after it, from the conversation and from the saved history |
/copy | Copy last assistant response to clipboard |
/current | Show all status bar data (even disabled segments) |
/quit, /exit | Save and exit |
/undo takes back the last turn: the files and the conversation together. Cast takes a checkpoint of the working directory when each turn starts, and /undo restores the newest one, then removes your message that started the turn and everything after it. It stays gone after a page reload or a restart. Run it again to step back another turn. It is refused while the agent is running (use /abort first) and does nothing if there is no checkpoint.
What is restored depends on the folder:
| Folder | What comes back |
|---|---|
| A Git repository | Every tracked and untracked file, as of the start of the turn, without touching your Git index. Files git ignores (.env, build output) that the agent changed with edit or write, and files it wrote outside the session's folder, are restored too. Each checkpoint is pinned by a ref under refs/cast/checkpoints/, so git gc cannot collect it, and the ref is released when the checkpoint is restored or the session is deleted. |
Not a repository, and small (up to 3000 files and 50MB; dependency and build folders like node_modules and dist are not counted) | Everything, including what shell commands changed, created or deleted. Cast commits the folder each turn to a hidden repository under ~/.cast/shadow/, which is deleted with the session. node_modules, dist and similar folders are left alone. Sandbox sessions are this case. |
Not a repository, and bigger, the home directory, or / | Only the files the agent changed with edit and write. /undo says that changes made by shell commands are not undone. |
Removing files created during the turn also removes any you created in that window: the restore cannot tell them apart, and they cannot be brought back. When there are such files, /undo names them and asks before proceeding. In the web UI a dialog lists them; over the API /undo refuses and asks you to re-run as /undo --force, which skips the question.
In the web UI a typed /undo opens a dialog that says which message goes, how the files are restored, and what will be deleted, then asks before doing anything. GET /api/v1/sessions/{id}/undo returns the same preview for your own client. To go back further than the last turn, use /rewind.
Rewind
/rewind takes any turn back, not only the last. Every turn records a snapshot of the folder when it starts and the message it started with, so you pick a message and what goes back:
| Choice | What happens |
|---|---|
| Files and conversation | The files go back as they were before that message, and the message and everything after it (every later turn) is removed from the conversation and the saved history. Later turns' snapshots are dropped with them. |
| Files only | The files go back; the conversation and every snapshot stay, so you can rewind the files forward to a later turn again. |
| Conversation only | The message and everything after it is removed; the files stay as they are. |
The files part restores the same way /undo does (see the table above), including its warning about files created since: they are named and you are asked first (--force skips the question). A message that compaction has taken out of the conversation the model sees can only be rewound for the files. Sessions from before this feature recorded no snapshots per message; they have /undo only.
In the TUI, /rewind shows a picker of your messages (newest first) and then of what goes back. In the web UI every such message has a Rewind button under its label (hover it; always visible on touch screens) that opens the same choice in a dialog. The command takes /rewind <message seq> [both|conversation|code] [--force], and over the API GET /api/v1/sessions/{id}/rewind-points lists the messages, GET .../rewind?userSeq= previews, and POST .../rewind does it.
/fork leaves the original session unchanged and starts an independent new session. It asks where from: the whole session (the context currently sent to the model), or before any message you sent (the original conversation up to there, including what compaction had summarized). In the web UI you can also fork through an answer that ends a turn (Fork from here under it), which keeps that answer; the TUI picker has a row for it too. Forking from an earlier point asks whether the fork gets its own copy of the files as they were then (a worktree or a snapshot copy); see Sessions. It does not copy checkpoints or pending pickers, or create a Git worktree: both sessions use the same working directory unless you switch one with /worktree.
The / palette lists the actions. A bare / opens with the commands most reached for (help, new, sessions, compact, review), then built-in commands A to Z, your skills, MCP prompts; with letters typed, what starts with them comes first. A subcommand and a short name (/s) are named in the description of their command, not listed as rows. The commands that only change a setting are left out of it because /settings opens each one; typed in full they work as before, for example /model gpt-x or /turn-cap 800.
Model and Provider
| Command | Description |
|---|---|
/model | Open model picker (shows current model) |
/model <name> | Switch to a specific model (validated) |
/agents | This session's sub-agents (also while a turn runs): watch one live, or stop a running one |
/subagent-model | Open model picker for sub-agents |
/subagent-model <name> | Switch sub-agent model |
/subagent-model-provider [name|off] | Show/change the saved provider used for the sub-agent model |
/plan-model [name|off] | Show/change the model used in plan mode |
/plan-model-provider [name|off] | Show/change the saved provider used for the plan model |
/reasoning | Change reasoning level (opens picker if model supports it) |
/reasoning-display (/rd) | Toggle reasoning blocks in the transcript. Off by default since reasoning models stream a lot of auxiliary thinking that clutters the chat |
/reasoning-format | Select the reasoning request protocol for the active provider |
/provider | Open provider picker (switch, add, or delete providers) |
/provider add | Add a new provider (name → URL → key wizard) |
/provider delete | Delete a provider |
/provider <name> | Switch to a named provider |
Persona
| Command | Description |
|---|---|
/persona | Open persona picker |
/persona <name> | Switch to a specific persona |
See Personas for the full list.
Skills and MCP
| Command | Description |
|---|---|
/skills | Toggle skills on/off (multi-select). Also: list, enable/disable, uninstall, sources (turn whole sources on/off), help |
/skills-sh | skills.sh: search / list-available / install / uninstall universal skills |
/skill:<name> [args] | Force-load and run a skill by name |
/mcp | Toggle MCP servers on/off. Also: list, logs, auth, logout, enable/disable, uninstall, help |
/hooks | List lifecycle hooks; also enable/disable <id> and help |
/reload | Re-scan skills, rules, MCP servers, personas, and context files for cwd |
Bare /skills / /mcp = multi-select toggle. list is read-only. uninstall always confirms (picker or typed). See Skills and MCP.
Hot-reload vs /reload
You never need to quit cast or start a new session for these changes. The current chat continues.
| Change | Apply how |
|---|---|
/skills / /mcp toggle, enable / disable | Automatic (hot-reload) |
/skills uninstall, /mcp uninstall | Automatic |
New/edited files on disk: skills, mcp.json, rules, personas, context files (including npx skills add) | /reload refreshes the current resource catalog; persona overrides created in chat are picked up automatically on the next user message |
/reload only re-scans cwd resources. It does not reset the conversation.
Rules
| Command | Description |
|---|---|
/rules | List loaded rules with their apply mode, globs, and scope |
/scratchpad | Show this session's scratchpad folder (see Sessions) and its biggest files; /scratchpad clear empties it |
/rule:<name> | Invoke a rule by name (loads its full content into context) |
See Rules for rule types and creation.
Plan Mode
| Command | Description |
|---|---|
/plan | Enter plan mode (explore and plan only, no code changes) |
/build | Exit plan mode, restore full toolset |
/plan-model [name|off] | Show/change the model used while plan mode is active |
See Plan Mode for the full workflow.
Autonomous and Self-Verification
| Command | Description |
|---|---|
/goal <description> | Work autonomously toward a goal until it's done (bounded, never-ask) |
/review | Ask the agent to review and verify its own work |
/init [focus] | Write or refresh AGENTS.md from what the repository shows (a turn; needs an idle session) |
/commit [hint] | Commit the current changes with a message that fits the repository (a turn; needs an idle session) |
/code-review [range] [-- path…] | Review a diff: scope, groups and language rules computed before the model sees it |
/goal [N] <description> sets a goal for the session and starts working on it without stopping to ask. The goal is saved and stays in the agent's prompt until it's closed, so it survives compaction and later turns.
- Closing it. The agent closes the goal with its
goal_updatetool once every requirement is checked. The first "complete" is always sent back for one more check against the objective. The second goes to an independent reader, which sees the objective, the agent's evidence and the latest tool results, and can turn it down once, naming the gap. "Blocked" only sticks after three reports in one stretch of work (your reply starts the count over), or at once for a safety or policy line. - Keeping going. Where a turn would normally end, an open goal continues it, up to 5 continuations. A pass that changed nothing gets a nudge to change approach; a second one in a row stops the drive and leaves the goal open for your reply. When the continuations run out, the agent sums up what's done and what's left.
- Budget. A leading number (
/goal 10 …, or--steps N) sets the iteration budget of the turn it starts, 25 model calls by default. Hitting it ends that turn and leaves the goal open: your next message carries on with it. Each model call can carry several tool calls, so the budget counts LLM turns, not tools. - Interruptions. Esc or a provider failure pauses the goal; the next turn picks it up and first re-checks what's on disk. In plan mode the goal doesn't push the turn on: the plan waits for your approval, and the goal drives again once you build.
- Managing it.
/goal statusshows it,/goal edit <text>changes the objective (also while it is paused after an interruption),/goal cleardrops it. All three work while a turn runs, in the terminal and in the web composer, and take effect on the agent's next step; starting a goal needs an idle session, and says when it replaces one that was still open. Deleting the session deletes its goal. Over the API,goal: trueor a step count on a chat message does the same as/goal.
Use it for start-to-finish tasks: "fix the tests", "set up the project and make the first commit", "implement X and verify it runs". Works in the TUI and the web composer. The status bar's goal segment (on by default; /statusbar toggles it) shows goal active, paused, blocked or out of budget, and is silent once the goal is done or cleared.
/code-review [range] [-- path…] reviews a change rather than the session. What must not go wrong is computed first, in code: which files are in scope (staged, unstaged and untracked against HEAD, or any git range you pass), which are filtered as generated, vendored or binary (each named with its reason so nothing looks silently missed), how they group into review units (a large file alone; a test with its implementation; otherwise by directory, capped), and which language rules apply. Only the judging is left to the model.
Findings go through a review_report tool that checks each one against the file: a line that doesn't hold is moved to where the quoted code actually is, and a finding whose code is nowhere in the file, or whose file is outside the scope, is dropped before you ever read it. A finding on a line the change didn't touch is kept and flagged as context.
/code-review # working tree vs HEAD
/code-review main..feature # a branch's changes
/code-review HEAD~3..HEAD -- src/ # narrow a large change to one subtreeRules live in prompts/review-rules/: one document per language, loaded only for the languages actually in the diff, plus a shared default whose two standing orders are precision over recall (a false positive costs the trust you need for the next finding) and don't duplicate the toolchain (whatever the linter, formatter, compiler or test run already says is not a review comment). Add your own by dropping a file in that directory.
/review asks the agent to verify its own most recent work: identify what changed (git diff / touched files), find and run the project's test and lint commands, and report honestly what was verified and what remains open. It never claims a check it didn't actually run.
Steering
Just type. A plain message sent while the agent is running is steered into the running turn. No command needed, in the TUI and the web UI alike. /steer stays for when you want to be explicit (and for scripts).
These commands work while the agent is running:
| Command | Short | Description |
|---|---|---|
/steer <message> | /s | Inject a message into the running turn |
/queue <message> | /q | Queue a message for after the current turn |
/queue-reset | /qr | Clear the message queue |
/btw <question> | Ask a question on the side: answered from the conversation, kept out of it | |
/queue-remove <n> | Remove the queued message numbered n (the number in the Queued list) | |
/running-input [steer|queue] | What a plain message does while a turn runs: steer it (default) or queue it | |
/abort, /stop | Stop current agent run |
/btw asks the model something without touching the work. It sends the conversation so far, with your question, to the model with no tools, and shows the answer as a notice (btw: ...) in the terminal and the web UI. Neither the question nor the answer joins the conversation: it is not saved, not summarised by a compaction, and the model's next turn knows nothing of it. Use it for "what did that flag do again?" or "which file did you change?" in the middle of a long task, without steering it or paying for a new turn of the agent.
- While a turn runs it works too, and it also hears what that turn has said and done so far (its text and tool calls, newest last), which the saved conversation does not hold until the turn ends. Typing the question as an ordinary message would steer the work instead;
/btwnever does. - The model answers from what is in the conversation. It is told to say so when the answer is not there instead of guessing; it cannot read files or run anything for this. Ask for that as a message.
- Cost. It is billed like any request (a provider that caches prefixes serves the conversation from its cache, since it is sent as the turns send it). Idle, the tokens join the session's usage; during a turn they go to the usage dashboard only. A conversation that fills the model's window is refused with a pointer to
/compact. - Over
cast runsend it as acommandaction ({"type":"command","name":"btw","args":" what changed?"}); the answer comes back as a notice. Not available over ACP.
/init and /commit are turns like /review: they send a prompt, and the agent does the work with its own tools, so the usual permission prompts apply. /init reads the tracked files, runs the cheap commands it is about to write down, and keeps the file to a page; text after the command narrows it (/init monorepo, packages/*). /commit reads the diff and git log, follows the repository's message style, stages explicit paths only (never git add -A), leaves out anything that looks like a secret and says so, makes one commit per unrelated concern, and does not push or amend; text after it is a hint (/commit only the parser). The thread shows the command you typed, not the prompt.
/steer interrupts the current turn with new context: the message is injected immediately into the conversation, and the agent sees it on the next tool-call iteration. Useful for correcting course mid-execution.
/queue saves a message to run after the agent finishes its current turn. The message becomes a new turn automatically. The queue lives in the daemon and every client shows the same list: a message queued in the terminal is in the web page's Queued list, and the reverse, also after a reload. /queue-remove <n> (a cross beside each entry in the web UI) drops one entry, /queue-reset clears all; a stopped run takes its queue with it and says which messages were not sent. What cast queues itself (a finished background task) is not listed.
If nothing is running, both /steer and /queue submit the message as a normal prompt.
/abort stops the current run and clears both the steering and follow-up queues: anything queued before the abort is discarded.
Both steering and follow-up messages reset the doom loop counter: repeating a failing command after user guidance is treated as a new attempt, not a loop.
Context and Usage
Token usage and context size are shown automatically in the TUI status bar (prompt tokens in, completion tokens out, prompt-cache hit %, cost, context percentage, tokens/second, and sub-agent tokens).
Use /statusbar to toggle individual segments on/off and reorder them (useful on narrow terminals where the full bar overflows). Segments can be moved between the left and right sides of the bar with ←/→, and reordered within each side with j/k. Default: persona, mode, model (left) and elapsed (right); enable others via /statusbar.
| Command | Description |
|---|---|
/current | All status bar data: model, context, tokens in/out with cache %, cost, sub-agent tokens, repo, session |
/cost | What this session has spent: tokens, cache share, subagent share, the provider's price when it reports one, and a line per kind of request (main, subagent, compaction, /btw) from telemetry |
/cost-cap <USD>, /cost-cap off | Set or clear a provider-reported spend threshold for this session. Calls stop after the reported spend reaches the threshold; an unknown price stops the next call while the cap is on. |
/export | Save the conversation as Markdown in ~/.cast/exports/ (system prompts left out, tool results cut at 2,000 characters), and print the path |
/doctor | Check what makes cast fail without saying why: Node version, the provider answers and serves the session's model, git, ripgrep, the sessions database, each MCP server |
/context | The AGENTS.md / CLAUDE.md files loaded for this directory, with their size, plus any file that could not be read |
Configuration
| Command | Description |
|---|---|
/settings | The settings screen. Toggles (web tools, reasoning, memory, notifications), the permission mode and the theme change where they stand: Space or Enter flips a toggle, ← → cycles a choice, and the value is saved at once. Rows that are a flow of their own (model, provider, persona, status bar, skills, MCP, turn cap, keys) open their picker on Enter and return to the screen after it. Esc closes. The /theme, /permissions and /web commands use the same setters. Works while a turn is running. Front ends without the screen show the same rows as a plain list |
/permissions | Open permission mode picker |
/permissions default | Switch to gated mode (confirm dangerous commands) |
/permissions bypass | Switch to bypass mode (no confirmation) |
/web | Toggle web tools (web_search, web_fetch) on/off |
/web-search-provider | Switch the web_search backend between DuckDuckGo (free, rate-limited), Tavily (API key, 1000 free/month), and Brave Search (API key) |
/web-fetch-provider | Switch web_fetch between Jina Reader and direct local fetch |
/statusbar | Toggle and reorder status bar segments (multi-select picker) |
/header | Choose and order the parts of the top row (CAST(1) * version by default; the persona, model and folder can be added): space shows or hides a part, j/k reorders. On a narrow screen parts drop from the end, whole, so the folder goes first. Also under Appearance in /settings |
/theme | Open theme picker |
/theme <id> | Switch to a specific theme |
/turn-cap [N|reset] | Show/set the per-turn iteration safety cap (default 500, 10–10000); applies on the next agent call. Also configurable via maxTurnIterations in settings.json and Settings → Bash |
Utility
| Command | Description |
|---|---|
/repo | Show cwd, git branch, dirty state, remote, and HEAD |
/keys | List all keybindings |
/lsp | Show the language servers cast is running, and why others aren't |
/help | Show the command list |
/ssh | Manage SSH hosts: list, add, remove (persists to ~/.cast/ssh.json) |
Keybindings
| Action | Keys |
|---|---|
| Previous / next prompt | ↑ / ↓ (moves within a multi-line draft first; moves the selection while the command palette is open) |
| Cursor left/right | ← / → (or Ctrl+B / Ctrl+F) |
| Word left/right | Alt+← / Alt+→ (or Ctrl+← / Ctrl+→) |
| Line start/end | Home / End (or Ctrl+A / Ctrl+E) |
| Delete char | Backspace / Delete |
| Delete word | Ctrl+W / Alt+Backspace |
| Delete to line start | Ctrl+U |
| Delete to line end | Ctrl+K |
| Submit | Enter |
| Line break | Shift+Enter (Alt+Enter too when no turn is running), or end the line with \ and press Enter, which works on any terminal |
| While a turn runs: send the message into it / after it | Enter steers, Alt+Enter queues (swapped by /running-input) |
| Stop turn (2×) | Esc |
| Clear the input | Ctrl+L |
| Exit (2× to confirm) | Ctrl+C |
| Quit at once | Ctrl+Q |
| Attach image | Ctrl+G |
Edit the prompt in $VISUAL / $EDITOR | Ctrl+X |
| Complete a command, or a file path | Tab |
Esc stops the current turn while generating (twice within 2s); Ctrl+L clears the input in any state.
@ at the start of a word opens a fuzzy picker of project files (from git ls-files in a repository, so .gitignore holds; rg --files or a directory walk elsewhere). ↑/↓ choose, Tab or Enter insert @path, Esc closes it for that word. The model reads the file itself when it needs it. The web composer has the same picker.
Tab completes a slash command in the palette, and a path-shaped token anywhere else (one containing /, or starting with ~). Ambiguous ones list what is left to choose from. Tab in ordinary prose does nothing.
Line breaks: Shift+Enter and Alt+Enter need a terminal that reports modified Enter (the Kitty keyboard protocol or modifyOtherKeys); everywhere else, end the line with a backslash and press Enter.
A long draft wraps at the terminal's edge, on word boundaries. The composer draws at most three rows and follows the cursor, with ↑/↓ in the prompt column where the draft continues past them. ↑/↓ move between rows, wrapped ones included.
Ctrl+C: press twice within 2s to exit. Does not stop a turn. Use Esc for that.
Ctrl+Q: exits at once, with no second press, in any state (while a turn runs, with a question open). The session is saved on the way out, the same as /quit, and the resume line is printed. It is the input.quit action: rebind it, or unbind it with [] if you would rather keep only the confirmed Ctrl+C. (Ctrl+D is not used: in the composer it deletes the character under the cursor.)
Ctrl+X opens the draft in $VISUAL, or $EDITOR when that is unset, like git commit does. The TUI steps aside while the editor runs; save and quit to bring the text back into the composer, still unsent. A GUI editor needs its wait flag (code --wait). A non-zero exit, such as :cq in vim, leaves the draft as it was.
Scrolling. The screen keeps its own place in the conversation, so nothing that arrives while you read moves you. The wheel or trackpad, PageUp / PageDown, Home / End (top and bottom of the conversation) and Ctrl+↑ / Ctrl+↓ (previous / next prompt) scroll it; a ↓ newest label appears while you are away from the end, and clicking it jumps back. PageUp at the very top loads older turns of a resumed session. Ctrl+Shift+F searches the conversation. Dragging with the mouse selects text and copies it on release; where that gets in the way of the terminal's own selection (Shift+drag usually gives it back), start with CAST_NO_MOUSE=1 and scroll by keyboard.
Rebinding keys: keybindings in ~/.cast/settings.json maps an action id to one key or a list, replacing that action's defaults; [] unbinds it. /keys shows the keys in effect.
{ "keybindings": { "input.externalEditor": "ctrl+o", "editor.clearBuffer": ["ctrl+l", "alt+l"] } }Action ids are the ones in `keybindings.ts`, for example input.submit, input.attachImage, editor.deleteWordBackward.
During a Running Agent
While a turn runs, Enter steers a plain message into it (no command needed) and Alt+Enter (Option+Enter) queues it for after the turn; in the web UI the same keys. /running-input queue (or Settings, "Enter while a turn runs") swaps the two: Enter queues, Alt+Enter steers; /running-input steer goes back. /steer and /queue do their own thing in either mode, and an attachment cannot ride either. Idle, Alt+Enter is a line break as before; while a turn runs it is the queue key, and Shift+Enter or a trailing \ is the line break. Besides that, these commands are accepted while the agent is executing:
/steer//s: inject context/btw: ask on the side, without steering/queue//q: queue follow-up/queue-reset//qr: clear queue/abort//stop: stop the run
All other input is rejected with a notice. Use Esc to stop the current turn (clears input when idle).