Interactive Mode
Interactive mode is Command Code running in your terminal: you type, the agent works, you watch it happen. This page covers everything you drive it with — the input modes, the shortcuts, how the model is picked, and the full keybinding reference at the end.
The whole screen, top to bottom:
Three characters change what the input does. That's most of the surface.
| Type this | You get |
|---|---|
/ at the start | The slash command menu — every built-in, custom, skill, and mod command |
! at the start | Bash mode: the line runs as a shell command and its output joins the session |
@ anywhere | File-path autocomplete; the mentioned file becomes context |
And five keys you'll use every session:
| Key | Does |
|---|---|
shift+tab | Cycle permission mode: default → auto-accept → plan → default |
esc | Stop what's running |
esc esc | Rewind to a previous checkpoint (same as /rewind) |
ctrl+o | Show or hide full tool output |
ctrl+g | Open the current prompt in $EDITOR |
Type / at the start of the input to open the command menu. Rows are ranked as you type: a command whose name starts with your query ranks highest, then names containing it, then description matches.
↑/↓ move the selection, Enter runs the selected command, Tab or → inserts it with a trailing space so you can type arguments, Esc closes the menu.
Every one of the 60+ built-in commands with its arguments and aliases, which
are safe to run mid-turn, and how to write your own with $ARGUMENTS
templating.
! runs a shell command directly. The line after ! is executed and both the command and its output are added to the session, so the agent sees what you saw. Use it for the quick check you'd otherwise ask for — !git status, !pnpm test.
@ mentions a file. Typing @ opens path autocomplete; the file you pick is read into context. A mention also pulls in any AGENTS.md files sitting between that file's directory and your project root — see Memory.
/model switches the model for the running session and becomes the default for new sessions: next time you start Command Code, it opens on the model you last chose. Sessions you already have open are not disturbed — each keeps the model it started with, so picking a model in one terminal never switches another mid-conversation.
You can also start on a specific model with --model (-m). That is a session-scoped override: it does not change your saved default, and an explicit /model pick later takes over from it. Unknown ids are rejected up front; run cmd --list-models for every id you can pass (see Available models).
The model your requests use resolves in this order:
- A
--modelflag passed at launch — in effect until you make an explicit/modelpick or switch conversations with/resume, either of which clears it. - The model you picked with
/modelthis session, or the model adopted when you resume a conversation. - The default: the model you last picked with
/model(snapshotted when this session started), then the built-in default.
Resuming a conversation restores its model. Whenever you continue an older conversation, the banner and your outgoing requests both switch to the model that conversation was last using:
- Cold
--resume/--continue(a fresh process): adopts the conversation's saved model. Exception: passing--modelon the same command (cmd --model X -r <id>) wins — you asked to resume and override in one breath. - In-TUI
/resume(switching conversations inside a running session): always adopts the model of the conversation you jump into, even if you launched with--modelor picked one with/modelthis session.
Adopting a model on resume is transient — it changes the model for that session but doesn't rewrite your default, so opening an old conversation won't quietly change what new sessions start on. Only an explicit /model pick updates the default.
Either way the banner and your outgoing requests stay in sync: whichever model the banner shows is the model your requests use.
Full referenceAvailable modelsEvery model id you can pass to -m or /model, grouped by provider, with
context windows and pricing.
shift+tab cycles through the modes rather than toggling two: default → auto-accept → plan → back to default. Launched with --yolo, bypass joins as a fourth rung (plan → bypass → default).
Two modes sit off that cycle. dont-ask is selected from settings or --permission-mode dont-ask; pressing shift+tab from it moves to auto-accept and rejoins the normal cycle. bypass is only reachable by launching with --yolo.
To jump straight to a mode without cycling, use /mode or its shorthands (/mode:default, /mode:auto-accept, /mode:plan).
This page only covers switching modes. The complete guide has what each mode actually allows, allow/ask/deny rule syntax, the decision ladder every tool call runs, safety behaviors, and the full decision table.
When you paste a block over 300 characters, Command Code collapses it into a compact [Text#N] placeholder so the prompt stays readable. The full text is still sent when you submit, and ctrl+g opens the real prompt in your editor.
To insert pasted text inline as raw text instead, set collapsePastedText to false in ~/.commandcode/config.json:
This is a personal preference, so it lives at the top level of config.json alongside theme and compactMode. See Settings & Config. Leave it unset (or true) to keep the default behavior.
Screenshots are context. Copy one and press ctrl+v in the input — the image
is attached and an [Image #1] token appears inline where your cursor was. Keep
typing around it:
On macOS cmd+v works too. Both land in the same place; ctrl+v exists because
several terminals never hand a clipboard image to the process at all, so
Command Code reads the system clipboard itself when it sees that key.
You can also drag an image file into the terminal window. The terminal pastes
its path, Command Code recognizes it as an image, reads it off disk, and attaches
it exactly like a clipboard paste — quoting, escaped spaces, file:// URLs, and
Windows drive or UNC paths are all unwrapped for you.
The [Image #N] token
| Do this | Result |
|---|---|
| Paste an image | Attached, token inserted at the cursor |
| Delete the token text | The image is dropped from the message |
ctrl+c | Clears the input and every pending attachment |
| Submit | Only images whose token survived are sent |
Numbers are reused: delete [Image #1] and the next paste is [Image #1] again,
not [Image #2]. The token renders dim and, where a preview file was written, as
a clickable file:// link — ctrl-click (or cmd-click) it to open the image in
your OS viewer. Previews live in a commandcode-images folder inside your temp
directory and are swept after seven days.
Formats and sizing
.png, .jpg/.jpeg, .gif, .webp, .bmp, and .tiff are all accepted.
Every image is downscaled to a 1200 px maximum dimension (aspect ratio kept, never upscaled) and re-encoded before it is sent — images with transparency stay PNG, everything else becomes JPEG. That is almost always invisible in practice and keeps a screenshot from eating your context window. Anything still over 32 MB is skipped rather than sent.
Every model can read them
You don't have to think about whether the model you picked has vision. If it
reads images natively, it reads them directly; if it doesn't, it calls the
VISION tool — one side-call to a cheap vision-capable model that describes the
image — and answers your prompt without your session ever changing models.
The feature is opt-in: the first time a text-only model needs to read an image,
Command Code asks, and /config → Image vision remembers your answer.
How the vision tool decides to fire, picking the model that does the reading, the three states of the Image vision setting, and what a read can and can't answer.
Command Code is a full-screen terminal application, and your terminal emulator is the runtime it renders into. Running it in the terminal your OS shipped with is the Internet Explorer of 2026 — it technically loads the page, and everything good is somewhere else.
The defaults are the problem: macOS Terminal.app is stuck on a 256-color
palette with no truecolor, no GPU rendering, and a keyboard protocol from the
1980s. Windows' legacy Console Host (conhost.exe) is worse. Both show up as
smeared colors, torn redraws while output streams, sluggish scrollback, and
shortcuts that silently never reach the process.
Use one of these instead:
All four are free, open source, GPU-accelerated, and speak the modern terminal protocols Command Code uses — truecolor, hyperlinks, bracketed paste, and the CSI u keyboard encoding that makes chorded shortcuts land reliably.
Command Code works in the ones you already have too — iTerm2, Windows Terminal,
Hyper, and the VS Code / Cursor / Windsurf integrated terminals are all handled,
including their quirks around paste markers, line endings, and intercepted keys.
Inside a VS Code-family terminal, run /terminal-setup once so shift+enter and
shift+tab reach Command Code instead of the IDE — see
IDE Integration.
Command Code opens files with the $EDITOR environment variable — used by ctrl+g, /skills, and plan review's ctrl+g.
macOS/Linux (bash)
macOS (zsh)
Windows (PowerShell)
Common values: code (VS Code), vim, nano, emacs, subl (Sublime Text).
Every shortcut is set up the way most people expect, but your hands are your own. Overrides live in a single optional file, ~/.commandcode/keybindings.json. Anything you don't mention keeps its default, so you're always adjusting, never starting from scratch.
Edited it mid-session? Run /reload and the changes take effect immediately.
How a shortcut is written
Each shortcut is a modifier and a key joined with + — ctrl+a, alt+left, shift+enter. You can stack modifiers (ctrl+shift+k), and order never matters.
The three modifiers are Control (ctrl / control), Shift (shift), and Option (alt, also written option, opt, or meta).
For the key itself, use a letter (a–z), a digit (0–9), a symbol, or one of the named keys: up, down, left, right, home, end, pageup, pagedown, enter (return), escape (esc), tab, space, backspace, delete, insert. Names are case-insensitive.
Give an action a single shortcut, or a list when more than one should work:
Bring your muscle memory
Emacs motions alongside the defaults:
Vim's home-row motions with Option held down:
Things worth knowing
- Nothing to break. If the file is missing, or a line has a typo, Command Code falls back to the defaults and starts as usual. A single bad entry never takes the rest of your file down with it.
- Coming from an older setup? Earlier configs used shorter names like
cursorUporexpandTools. Command Code recognizes those and maps them to the dotted ids automatically on launch. - Want a key to do nothing? Set the action to an empty list (
[]). - Your terminal is covered. Home, End, and Option-Arrow arrive as different escape sequences across iTerm2, Terminal, Ghostty, Kitty, Alacritty, WezTerm, and VS Code — Command Code matches the defaults below in all of them.
Every bindable action, with its stable id and default keys. Use the id as the key in keybindings.json.
Moving the cursor
| Action | Default | What it does |
|---|---|---|
tui.editor.cursorLeft | left | Move left one character |
tui.editor.cursorRight | right | Move right one character |
tui.editor.cursorUp | up | Move up one line |
tui.editor.cursorDown | down | Move down one line |
tui.editor.cursorWordLeft | alt+left, ctrl+left, alt+b | Jump back a word |
tui.editor.cursorWordRight | alt+right, ctrl+right, alt+f | Jump forward a word |
tui.editor.cursorLineStart | home, ctrl+a | Go to the start of the line |
tui.editor.cursorLineEnd | end, ctrl+e | Go to the end of the line |
Editing text
| Action | Default | What it does |
|---|---|---|
tui.editor.deleteCharBackward | backspace | Delete the character behind the cursor |
tui.editor.deleteCharForward | delete | Delete the character ahead of the cursor |
tui.editor.deleteWordBackward | ctrl+w, alt+backspace | Delete the word behind the cursor |
tui.editor.deleteToLineStart | ctrl+u | Clear back to the start of the line |
tui.editor.deleteToLineEnd | ctrl+k | Clear forward to the end of the line |
Composing a message
| Action | Default | What it does |
|---|---|---|
tui.input.newLine | shift+enter, ctrl+j | Add a line break instead of sending |
tui.input.submit | enter | Send your message |
Working with the session
| Action | Default | What it does |
|---|---|---|
app.permission.cycle | shift+tab, alt+m | Cycle permission mode (alt+m is the Windows fallback) |
app.tools.expand | ctrl+o | Show or hide full tool output |
app.model.select | alt+p | Open the quick model switcher (option+p on macOS) |
app.todos.toggle | ctrl+x | Open the session todo manager (the /todos overlay); press again to close |
app.editor.external | ctrl+g | Hand the prompt to your editor ($EDITOR) |
app.input.stash | ctrl+s | Set the current prompt aside; press again to restore |
app.interrupt | escape | Stop what's running |
app.clipboard.pasteImage | ctrl+v | Paste an image from the clipboard |
The /tree navigator
These apply inside the /tree session browser. Branch jumps default to Option/Alt-arrows and Tab because macOS Mission Control owns ctrl+←/→; the ctrl forms are a compatibility alias for terminals that pass them through.
| Action | Default | What it does |
|---|---|---|
app.tree.foldOrPrevBranch | alt+left, shift+tab, ctrl+left | Fold the selected branch, or jump to the previous branch point |
app.tree.unfoldOrNextBranch | alt+right, tab, ctrl+right | Unfold the selected branch, or jump to the next branch point |
app.tree.label | shift+l | Edit the selected entry's label |
app.tree.labelTime | shift+t | Toggle label timestamps |
app.tree.filter.default | ctrl+d | Back to the default view |
app.tree.filter.noTools | ctrl+t | Toggle hiding tool rows |
app.tree.filter.userOnly | ctrl+u | Toggle user messages only |
app.tree.filter.labeledOnly | ctrl+l | Toggle labeled entries only |
app.tree.filter.all | ctrl+a | Toggle showing every entry |
app.tree.filter.cycle | ctrl+o | Cycle forward through the filter modes |
app.tree.filter.cycleBack | shift+ctrl+o | Cycle backward through the filter modes |
Fixed shortcuts
Two shortcuts are part of a specific screen rather than the keybinding registry, so they can't be remapped:
| Key | Where | What it does |
|---|---|---|
ctrl+e (ctrl+y in VS Code-family terminals) | On a permission prompt | Explain the pending shell command in plain language before you decide. Controlled by On-demand command explanations in /config (General, user scope): on by default (explain only on ctrl+e); off generates every explanation upfront. |
ctrl+e / ctrl+y | With the transcript on | Toggle between the limited and full transcript view. The permission prompt takes priority for these keys while it is offering an explanation. |
Inside a VS Code-based IDE terminal (VS Code, Cursor, Windsurf) the IDE claims ctrl+e, so Command Code uses ctrl+y — see IDE Integration.
- Slash Commands — every command, argument form, and how to write your own.
- Plan Mode — what each permission mode allows.
- Sessions & Checkpoints —
/rewind,/tree,/fork, and session files. - Vision — how every model reads the images you attach.
- IDE Integration — open file, selection, and diagnostics from your editor.
- Windows — the
cmdcalias, the PowerShell tool, and terminal choice on Windows.