Skip to main content
Claude Code Tutorial: From First Command to Custom Workflows

What Claude Code Is: Architecture and Core Distinction

Claude Code is an agentic coding tool that reads your codebase, edits files, and runs commands across a multi-step decision loop. This lesson covers its architecture, the three execution surfaces, and what makes it fundamentally different from a chat assistant or IDE copilot.

Beginner16 minBy ToolDix Editorial

Learning objectives

  • Understand Claude Code's architecture as an agentic harness around a language model
  • Distinguish agent behavior (autonomous multi-step action) from copilot behavior (single-turn suggestion)
  • Identify the three execution surfaces and their tradeoffs
  • Recognize the permission boundary and why it exists

ToolDix original visual

Claude Code Tutorial practice loop
1

Frame

Name the outcome and constraints.

2

Build

Try one bounded workflow.

3

Review

Keep evidence, revise, and share.

The agentic harness: model plus execution environment

Claude Code is not a code generator. It is an agentic harness -- a combination of a language model (Claude), a set of tools that grant the model access to your environment, a permission system that constrains what the model can do, and an orchestration loop that chains multiple actions together until a goal is met.

The model is powerful but passive: it predicts what to do next. The harness is what makes it agentic: it reads your codebase at startup, loads project-specific instructions from CLAUDE.md, manages your terminal and filesystem, tracks context across multiple turns, and executes the model's decisions. Neither piece alone produces an agent. Together, they create autonomous capability within explicit boundaries.

This architecture has three consequences: depth, autonomy, and safety. Claude Code reads your entire project (depth), decides which files to edit and which commands to run without your input on every step (autonomy), and asks for permission at destructive boundaries (safety). A copilot does none of these.

Agent versus copilot: the mechanical difference

A copilot (GitHub Copilot, Cursor, or any IDE suggestion engine) is a single-turn system:

  1. You type or highlight code
  2. The copilot suggests the next line, function, or block
  3. You review the suggestion and accept or reject
  4. Repeat

The human drives; the tool reacts. Every step is visible, but every step is also manual.

A coding agent (Claude Code) is a multi-turn decision loop:

  1. You describe a goal: "Fix the authentication bug"
  2. Claude Code reads your project files (with your permission)
  3. It plans what to change based on the actual code, not training data
  4. It edits files and runs tests to verify changes
  5. If a test fails, it observes the error, forms a hypothesis, and tries again
  6. It repeats until the goal is met or an error occurs

The key difference is not intelligence but autonomous iteration: the agent observes the result of each action and decides the next step without waiting for you to interpret the output and type new instructions.

This makes agents faster on tasks where adaptation matters (debugging, refactoring, testing), because they never wait for feedback or lose context between attempts. It also makes them riskier, which is why the permission model exists.

ToolDix original diagram
Claude Code permission boundary
No approval required
Read files • Run read-only commands (ls, cat, git log) • Run tests • Propose diffs • Reason about results
Approval required
Create/edit files • Delete files • Run state-changing commands (rm, git commit) • Push to repository • Call external APIs

Three surfaces: terminal, desktop, and IDE

Claude Code runs in three places, sharing the same underlying agent and permission boundary:

SurfaceInterfaceExecutionBest for
CLI (terminal)Text-based prompt and response in your shellLocal machine with full environment accessFull-featured workflows; scripting and piping; native shell integration; maximum flexibility
Desktop appGraphical interface with side-by-side diff viewer, file browser, and chat panelLocal machine or cloudVisual diff review; running multiple sessions in parallel with git worktree isolation; desktop UI comfort
IDE extension (VS Code, JetBrains)Panel or sidebar within your editor; @-mentions for file context; inline diffsLocal machine; uses standalone CLI if installedStaying in your editor; highlighting code to pass context; reviewing diffs inline

All three surfaces connect to the same agent engine. What changes is the UI. A session started in the CLI can be resumed in the Desktop app with /desktop or teleported to the web. A skill or CLAUDE.md created for the CLI works identically in the VS Code extension. Permission rules set in one surface apply everywhere.

The permission boundary in detail

Claude Code enforces two layers of control. The permission mode (set with Shift+Tab in the CLI) controls the baseline approval behavior:

  • Manual (default): Claude asks before file edits and most shell commands
  • Accept edits: Claude edits files and runs common commands (mkdir, mv) without asking; still asks for destructive operations
  • Plan: Claude reads and proposes changes without editing files
  • Auto: Claude evaluates all actions with server-side safety checks

Within each mode, permission rules provide fine-grained control. You can allow specific commands without prompts (npm test always runs), deny others entirely (rm -rf is blocked), or ask for confirmation on patterns. These rules are stored in .claude/settings.json or ~/.claude/settings.json (user-scoped defaults).

The boundary applies to exact tool categories:

Read (no approval required):

  • Read files, list directories, grep contents
  • Run read-only shell commands (git log, npm list, find)
  • Run tests

Propose (shown to you; approval required):

  • Edit files, create new files, delete files Claude created
  • File-moving and organizational changes

Write (approval always required or explicitly allowed):

  • Run state-changing commands (git commit, git push, rm, mv for your own files)
  • Call external APIs or webhooks
  • Run package installs or system commands

This is not overly restrictive. Claude Code can work fast: tests pass without asking, file edits show a diff (which you can approve in batches), and once you approve a command pattern, you don't re-approve it. But Claude can never silently delete files or push to production without your explicit consent.

What Claude Code can and cannot do

Claude Code can:

  • Read any file in your project (or any file you grant access to)
  • Edit and create files across multiple directories
  • Run shell commands: tests, builds, git operations, package managers, scripts
  • Call external APIs and services (via MCP servers)
  • Reason about errors, test failures, and warnings
  • Iterate across multiple turns (10-50 actions per session is typical)
  • Load and use project-specific instructions from CLAUDE.md
  • Access your development environment with the same tools you have

Claude Code cannot:

  • Bypass the permission boundary
  • Access files you haven't granted access to
  • Execute a command you haven't approved (with the exception of whitelisted read-only and common operations)
  • Push to production without explicit instruction
  • Forget context between actions in the same turn (but context resets between sessions unless you use /resume)

The boundary is not a limitation; it is architectural. Production software and user data are valuable. Agents that move fast within clear, enforced rules are trustworthy enough to use in real workflows. Unrestricted agents are not.

Worked example: what Claude Code actually does

You start a session: claude

You type: "Fix the failing payment test in test/payments.test.js"

Here is what happens inside the agent loop across multiple turns:

Turn 1:

  1. Claude reads the test file to understand what it's testing
  2. Claude runs the test suite to see the exact error message
  3. Claude reads the payment module being tested to understand the implementation
  4. Claude observes: the test expects validateCard() to reject expired cards, but the implementation doesn't check the expiration date
  5. Plan: add expiration date validation

Turn 2:

  1. Claude shows you the proposed edit (diff) to the payment module
  2. You review the diff; it looks correct, so you approve with y
  3. Claude writes the file
  4. Claude runs the test suite again
  5. The test passes
  6. Claude observes: goal met
  7. Claude reports the result and waits for the next instruction

Total time: ~20 seconds. Your active work: 5 seconds to review one diff.

The same task in a chat interface would be: copy test code, copy error, ask for a fix, copy the code back, run manually, paste error again if it's wrong, repeat. Three manual copy-paste cycles and 3 minutes.

Common mistake

Assuming permission boundaries prevent Claude Code from being useful. The opposite is true. Because the boundaries are explicit and enforced, you can confidently run Claude Code on production code with full project access without worrying that a confused agent will delete the repository. The permission model enables productive use of agents, not disables it. The mistake is either ignoring the boundary ("let Claude Code do whatever") or over-constraining it ("only let Claude Code read files"), both of which defeat the point.

Sources and license context

These references informed the lesson. ToolDix adds its own explanation, workflow, and practice rather than reproducing source material. Every link below leaves ToolDix and opens the publisher's own site in a new tab.

Keep going

Read these next on ToolDix.

Original lessons that build on what you just read.