Three Ways to Talk to Claude Code

Three Ways to Talk to Claude Code

Part 1 — Foundations Chapter 2 of 4
Listen to this article
Read aloud in your browser

Overview

This chapter covers:

  • The three input channels, separated by when they are parsed and whether the model ever sees them
  • Why two of the three cost no tokens at all — and the mistake that gives that saving away
  • CLI arguments: print mode as a shell filter, the flags worth memorising, and the pair that debugs your configuration
  • Slash commands and sigils — @ to pass a file in, ! to run your own shell, and the change that made ! stop being free
  • Editing, queueing and dictating at the prompt

The three channels

Claude Code takes input through three channels. They differ in when they are parsed and whether the model ever sees them.

ChannelParsedReaches the modelExample
CLI argumentsBy the shell, before the process startsNoclaude --model opus --add-dir ../api
Slash commandsBy Claude Code, at the start of a lineMostly no/context
SigilsBy Claude Code, inside the promptDependsexplain @src/auth.ts
flowchart TB
    subgraph T["Shell — before the process exists"]
        A["claude --model opus --add-dir ../api"]
    end
    subgraph S["Session — start of an input line"]
        B["/context   /compact   /doctor"]
    end
    subgraph P["Prompt — inside the text"]
        C["explain @src/auth.js and check !git log"]
    end
    T --> S --> P

Two of the three cost nothing. Channels 1 and 2 are handled locally — no model call, no latency, no tokens. Asking Claude in prose to do something a slash command already does is the most common avoidable expense.

Channel 1 — CLI arguments

These configure the session before it exists, so they control things no in-session command can: the starting permission mode, which directories are in scope, the system prompt.

The invocation forms

claude                          # interactive session
claude "fix the login bug"      # interactive, with a first prompt
claude -p "explain this file"   # print mode: one answer on stdout, then exit
claude -c                       # continue the last conversation here
claude -r                       # resume: interactive picker

Print mode (-p) is the one worth internalising. No REPL, no UI — it reads stdin and writes stdout, which makes Claude Code a shell filter:

cat error.log | claude -p "what went wrong?"
git diff main --name-only | claude -p "review these for security issues"

Every CI integration in Chapter 16 is built on that one property.

The flags you will actually reach for

FlagEffect
--model <alias>sonnet, opus, haiku, fable, or a full model ID
--permission-mode <mode>Where the session starts — Chapter 3
--add-dir <path>…Additional directories Claude may read and edit
--append-system-prompt "<text>"Add to the system prompt instead of replacing it
--output-format jsonStructured output, for scripting -p runs
--safe-modeStart with all customisations disabled
--bareSkip auto-discovery of hooks, skills, MCP, CLAUDE.md, everything

--safe-mode and --bare are the debugging pair: if odd behaviour disappears under either, the cause is your configuration rather than Claude Code. Chapter 22 uses both.

There are roughly forty more flags — session naming and forking, fallback model chains, turn and budget caps, settings-source control. The CLI reference is the complete list, and it stays current in a way a chapter cannot.

Not every invocation starts a session

claude doctor, claude update, claude mcp, claude plugin, claude auth, claude setup-token and a few others are subcommands that do a job and exit. claude doctor and claude setup-token — diagnostics, and a long-lived token for CI — are the two you are most likely to need first.

Channel 2 — slash commands

A / at the start of a line opens the command menu. Typing / and reading the list is the intended discovery mechanism — it shows everything currently available, including your own skills and plugin commands. What follows is the subset in routine use, not a catalogue.

CommandPurpose
/contextWhat is consuming the context window, as a grid
/clearNew conversation, empty context
/compactSummarise the conversation to reclaim space
/rewindRoll code and conversation back to a checkpoint
/resumeReturn to an earlier conversation
/doctorSetup checkup, with proposed fixes
/permissionsAllow, ask and deny rules
/model, /effortModel and reasoning depth
/memory, /initEdit CLAUDE.md; generate a starting one
/planEnter plan mode
/cost, /usageSpend

Beyond these sit the extension points (/hooks, /agents, /mcp, /plugin — Chapters 11 to 17) and the workflow commands (/code-review, /security-review, /batch, /subtask, /goal, /loop, /background), each covered where it belongs. The slash command reference lists all of them, and Chapter 12 covers writing your own.

Channel 3 — sigils

Characters interpreted inside the input line itself.

SigilPositionEffect
/Start of lineCommand menu
!Start of lineShell mode
@AnywhereFile reference
?Empty inputToggle the shortcut panel

@ — file references

@path passes the file’s contents straight in:

Why do tokens expire early in @src/auth/middleware.ts?

Path completion works as you type. Against describing the file in prose, this removes a search round trip and removes the chance of Claude opening the wrong file.

! — shell mode

A leading ! runs the rest of the line in your shell. Claude does not choose it, approve it, or interpret it:

!npm test
!git status

The output lands in the transcript. Tab completes from previous ! commands in the project, Ctrl+B backgrounds a long-running one, and Esc on an empty prompt exits shell mode.

Two things about ! that catch people out:

It is no longer free. Older material says shell mode consumes no tokens. That was true when output entered context silently. Since v2.1.186 Claude responds to the output automatically, at the cost of a normal prompt. Set respondToBashCommands: false in settings.json to get the silent behaviour back.

It runs outside the Bash sandbox. In a regular interactive session, sandboxing governs commands Claude runs, not commands you run. Background sessions in strict sandbox mode are the exception.

The difference between the two ways to run your test suite is one model round trip and one permission check:

sequenceDiagram
    participant You
    participant CC as Claude Code
    participant Sh as Shell
    participant LLM
    You->>CC: !npm test
    CC->>Sh: npm test
    Sh-->>CC: 2 failing, 14 passing
    Note over CC: Enters transcript.
No tool call, no permission check. CC->>LLM: transcript including output LLM-->>You: analysis of the failures

Use ! when the command is already decided. Use natural language when choosing the command is part of the task.

A note on #

Older documentation lists # as a memory prefix. It is no longer documented. Say it plainly instead — auto memory captures it:

remember that we use pnpm, not npm

Chapter 7 covers what gets stored and where.

Sort nine inputs

Where does this go? 0 / 0
—

Pick a channel.

Working the prompt

The input line is a readline-style editor. The bindings that earn their keep on day one:

KeyEffect
EscInterrupt Claude, or close a dialog
Esc EscClear the draft, or open rewind
Ctrl+OToggle the transcript viewer
Ctrl+RReverse-search command history
Ctrl+GOpen the prompt in $EDITOR
Ctrl+VPaste an image from the clipboard
Shift+TabCycle permission modes
? on empty inputShow every other shortcut

Line editing follows readline (Ctrl+A, Ctrl+E, Ctrl+K, Ctrl+W, Alt+B/Alt+F), and a full vim mode is available. For a newline rather than a send: \ then Enter, or Option+Enter, or Shift+Enter, or Ctrl+J. If Shift+Enter does nothing, that is your terminal, not Claude Code — the terminal configuration guide has per-terminal settings, and bindings are customisable in ~/.claude/keybindings.json.

Queueing

Pressing Enter while Claude is mid-turn does not interrupt. The message queues above the input box and is sent when the turn ends. Combined with Chapter 1’s interrupt semantics, there are three ways to redirect work in flight:

ActionEffect
EscCancel the running tool call now
Type + Enter mid-toolRead once that tool call finishes, before the next action is chosen
Type + Enter while generatingQueued, sent at end of turn

Voice dictation

/voice transcribes speech into the prompt, so you can mix speaking and typing in one message. Hold mode (the default) is push-to-talk on Space; tap mode starts and stops on a tap, with no warm-up delay. Persist your preference rather than toggling each session:

{ "voice": { "enabled": true, "mode": "tap" } }

Transcription costs no tokens and does not count toward /usage. It needs a Claude.ai account (not an API key, Bedrock, Google Cloud or Foundry) and a local microphone, so it does not work over SSH or on the web. Twenty languages, following the same language setting as Claude’s responses.

Picking a channel

Three questions, in order:

  1. Does the session exist yet? No → CLI argument.
  2. Is this Claude Code’s job or Claude’s? Claude Code’s → slash command.
  3. Is the exact command or path already decided? Yes → ! or @.

Summary

  • Three channels, separated by when they are parsed: CLI arguments before the process starts, slash commands at the start of a line, sigils inside the prompt. Only sigils mix with prose.
  • Channels 1 and 2 are local and free. Prose for a job a slash command does costs a round trip and returns a worse answer.
  • claude -p reads stdin and writes stdout — that is what makes it a shell filter and a CI step.
  • @path passes file contents directly; !cmd runs in your shell, outside the sandbox, and since v2.1.186 is not free.
  • Enter mid-turn queues rather than interrupts. Esc is the interrupt.
  • Type / and read the menu; the CLI and slash command references are the exhaustive lists.

Chapter 3 covers the six permission modes and the classifier that decides what runs without asking.