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:

┌────────────────────────────────┐ READ src/auth.ts │ ← the feed: EDIT src/auth.ts +12 -3 │ what the agent BASH pnpm test │ is doing │ │ │ ✓ Added the retry guard. ← its reply ├────────────────────────────────┤ TODOS 2/4 │ ← ctrl+x to manage ├────────────────────────────────┤ > fix the login redirect │ ← you type here ├────────────────────────────────┤ In auth.ts opus-5 default │ ← file · model · mode └────────────────────────────────┘

Three characters change what the input does. That's most of the surface.

Type thisYou get
/ at the startThe slash command menu — every built-in, custom, skill, and mod command
! at the startBash mode: the line runs as a shell command and its output joins the session
@ anywhereFile-path autocomplete; the mentioned file becomes context

And five keys you'll use every session:

KeyDoes
shift+tabCycle permission mode: default → auto-accept → plan → default
escStop what's running
esc escRewind to a previous checkpoint (same as /rewind)
ctrl+oShow or hide full tool output
ctrl+gOpen the current prompt in $EDITOR
Note

Run /hotkeys in a session to see every shortcut Command Code recognizes right now, including your own overrides. Run /help for the short list.

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.

Full referenceSlash Commands

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:

  1. A --model flag passed at launch — in effect until you make an explicit /model pick or switch conversations with /resume, either of which clears it.
  2. The model you picked with /model this session, or the model adopted when you resume a conversation.
  3. 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 --model on 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 --model or picked one with /model this 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 models

Every 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: defaultauto-acceptplan → back to default. Launched with --yolo, bypass joins as a fourth rung (planbypassdefault).

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).

Note

alt+m does the same thing as shift+tab. It exists for Windows terminals where Shift-Tab doesn't come through.

Complete guidePermissions

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:

{ "collapsePastedText": false }

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.

Note

Legacy location: an older input.collapsePastedText key in the settings.json family is still honored as a fallback. It is only consulted when config.json has no collapsePastedText value, so config.json always wins. Prefer config.json for new setups.

Command Code opens files with the $EDITOR environment variable — used by ctrl+g, /skills, and plan review's ctrl+g.

macOS/Linux (bash)

# Add to ~/.bashrc and reload echo 'export EDITOR="code"' >> ~/.bashrc source ~/.bashrc

macOS (zsh)

# Add to ~/.zshrc and reload echo 'export EDITOR="code"' >> ~/.zshrc source ~/.zshrc

Windows (PowerShell)

# Set permanently (restart terminal after) setx EDITOR "code"

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 (az), a digit (09), 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:

{ "app.tools.expand": "ctrl+t", "tui.editor.cursorUp": ["up", "ctrl+p"] }

Bring your muscle memory

Emacs motions alongside the defaults:

{ "tui.editor.cursorUp": ["up", "ctrl+p"], "tui.editor.cursorDown": ["down", "ctrl+n"], "tui.editor.cursorLeft": ["left", "ctrl+b"], "tui.editor.cursorRight": ["right", "ctrl+f"], "tui.editor.cursorWordLeft": ["alt+left", "alt+b"], "tui.editor.cursorWordRight": ["alt+right", "alt+f"], "tui.editor.cursorLineStart": ["home", "ctrl+a"], "tui.editor.cursorLineEnd": ["end", "ctrl+e"] }

Vim's home-row motions with Option held down:

{ "tui.editor.cursorUp": ["up", "alt+k"], "tui.editor.cursorDown": ["down", "alt+j"], "tui.editor.cursorLeft": ["left", "alt+h"], "tui.editor.cursorRight": ["right", "alt+l"], "tui.editor.cursorWordLeft": ["alt+left", "alt+b"], "tui.editor.cursorWordRight": ["alt+right", "alt+w"] }

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 cursorUp or expandTools. 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

ActionDefaultWhat it does
tui.editor.cursorLeftleftMove left one character
tui.editor.cursorRightrightMove right one character
tui.editor.cursorUpupMove up one line
tui.editor.cursorDowndownMove down one line
tui.editor.cursorWordLeftalt+left, ctrl+left, alt+bJump back a word
tui.editor.cursorWordRightalt+right, ctrl+right, alt+fJump forward a word
tui.editor.cursorLineStarthome, ctrl+aGo to the start of the line
tui.editor.cursorLineEndend, ctrl+eGo to the end of the line

Editing text

ActionDefaultWhat it does
tui.editor.deleteCharBackwardbackspaceDelete the character behind the cursor
tui.editor.deleteCharForwarddeleteDelete the character ahead of the cursor
tui.editor.deleteWordBackwardctrl+w, alt+backspaceDelete the word behind the cursor
tui.editor.deleteToLineStartctrl+uClear back to the start of the line
tui.editor.deleteToLineEndctrl+kClear forward to the end of the line

Composing a message

ActionDefaultWhat it does
tui.input.newLineshift+enter, ctrl+jAdd a line break instead of sending
tui.input.submitenterSend your message

Working with the session

ActionDefaultWhat it does
app.permission.cycleshift+tab, alt+mCycle permission mode (alt+m is the Windows fallback)
app.tools.expandctrl+oShow or hide full tool output
app.model.selectalt+pOpen the quick model switcher (option+p on macOS)
app.todos.togglectrl+xOpen the session todo manager (the /todos overlay); press again to close
app.editor.externalctrl+gHand the prompt to your editor ($EDITOR)
app.input.stashctrl+sSet the current prompt aside; press again to restore
app.interruptescapeStop what's running
app.clipboard.pasteImagectrl+vPaste 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.

ActionDefaultWhat it does
app.tree.foldOrPrevBranchalt+left, shift+tab, ctrl+leftFold the selected branch, or jump to the previous branch point
app.tree.unfoldOrNextBranchalt+right, tab, ctrl+rightUnfold the selected branch, or jump to the next branch point
app.tree.labelshift+lEdit the selected entry's label
app.tree.labelTimeshift+tToggle label timestamps
app.tree.filter.defaultctrl+dBack to the default view
app.tree.filter.noToolsctrl+tToggle hiding tool rows
app.tree.filter.userOnlyctrl+uToggle user messages only
app.tree.filter.labeledOnlyctrl+lToggle labeled entries only
app.tree.filter.allctrl+aToggle showing every entry
app.tree.filter.cyclectrl+oCycle forward through the filter modes
app.tree.filter.cycleBackshift+ctrl+oCycle backward through the filter modes
Note

Remapping is live today for everything under Moving the cursor, the word- and line-deletion actions, the whole /tree navigator group, and app.permission.cycle, app.tools.expand, app.model.select, and app.todos.toggle. The rest are listed so you can see the whole keymap — Command Code still honors their default keys, and custom bindings for them are on the way. Plain backspace stays fixed on purpose, so terminals that report Backspace as a "delete" key keep behaving correctly.

Fixed shortcuts

Two shortcuts are part of a specific screen rather than the keybinding registry, so they can't be remapped:

KeyWhereWhat it does
ctrl+e (ctrl+y in VS Code-family terminals)On a permission promptExplain 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+yWith the transcript onToggle 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.