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.
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. - IDE Integration — open file, selection, and diagnostics from your editor.