A plain-English walkthrough of the source tree in this folder — the agent loop, the tools it can call, the sub-agents it can spawn, the background tasks it tracks, and the guardrails in front of it all. No prior knowledge required.
BashTool runs shell commands. FileEditTool edits files. WebFetchTool fetches URLs. Each has a schema, a permission gate, and a UI.AgentTool lets the main agent delegate a self-contained task to a fresh mini-agent that has its own context window.memdir/ folder stores facts about you, feedback you've given, and project context — indexed by MEMORY.md.Everything else is scaffolding around this one cycle.
Type a message, or run a slash command like /commit.
Receives your message + a system prompt + available tools.
Shown to you. Loop ends.
E.g. "run ls" or "read file.ts".
Allowed? Ask you? Blocked?
Output captured.
query.ts and QueryEngine.ts. The tool-result round-trip is what keeps the model "grounded" in your actual machine instead of hallucinating.
The engine assembles: the system prompt (constants/prompts.ts), your messages, the conversation history, the list of tools currently available, and any memory that looked relevant.
The API is called with retries and fallbacks (services/api/withRetry.js). The response streams back token by token so the UI can render as it arrives.
If the model wants to use a tool, the reply contains a tool_use block: the tool name and the JSON arguments. Otherwise, it's just text, and the turn is over.
useCanUseTool decides: allowed automatically, ask the user, or deny. Rules come from your settings, CLI flags, and hook scripts you configured.
Each tool's call() does its real work: spawn a shell, read a file, fetch a URL, spawn a sub-agent. Progress can stream back to the UI.
The tool's output becomes a tool_result message, appended to the conversation. Then we go back to step 1 — the model now sees what happened and decides what to do next.
If the conversation is getting close to the context limit, services/compact/ summarizes older turns so the agent can keep working without hitting the ceiling.
Think of tools as the agent's hands. Each one is a small TypeScript module in tools/.
src/**/*.tsx.skills/.tools.ts. Tools can be gated by feature flags (e.g. feature('AGENT_TRIGGERS')) or by a user type — so what shows up depends on the build and environment.
The main agent can say "I'll let a specialist handle this" and delegate. The specialist returns one answer and disappears.
Sees your conversation, uses the full tool set, drives the REPL. One per session.
Spawned via AgentTool. Gets a fresh context, a narrower instruction, and returns a single result back to the parent. Doesn't see the parent's conversation — only the prompt it was given.
Broad research or open-ended coding tasks.
Fast codebase exploration (search, read, summarize).
Designs an implementation plan before you commit.
Configures the CLI status line — narrow scope.
Answers "how do I…" questions about Claude Code itself.
End-to-end deploy + SEO workflow example.
Definitions for built-in agents live in tools/AgentTool/built-in/. Users can add their own in ~/.claude/agents/.
When something doesn't finish instantly, it becomes a task with an ID, a status, and an output file. The UI shows all of them; the agent can poll or kill them.
A shell command running in the background.
A sub-agent running on your machine.
An agent running in the cloud (via the bridge).
A long-lived teammate you can chat with alongside the main session.
A packaged workflow (skill) running as a task.
A streaming MCP monitor feeding events in.
Opportunistic background "thinking" work.
tasks/. The base shape & ID scheme are defined in Task.ts.
The model can ask for anything. The program decides what actually happens.
settings.json — PreToolUse, PostToolUse, UserPromptSubmit — can approve, deny, or modify tool use.hooks/ folder holds React UI hooks for the terminal. Settings-file hooks (the shell-script kind) are schema'd in schemas/hooks.ts.
The agent doesn't remember on its own. A dedicated memory layer writes small Markdown files that are re-read in future conversations.
Your role, goals, preferences. Helps the agent tailor explanations to who you are.
Corrections and confirmations. "Don't mock the DB in tests" stays true next week.
Current initiatives, deadlines, why things are the way they are. Decays fast — updated often.
Pointers to external systems: "pipeline bugs are in Linear project INGEST".
MEMORY.md is the short index loaded into every conversation. Code lives in memdir/.
Before any of this runs, the model is given a long system prompt: who it is, what it can do, how to format answers, when to ask vs. act.
Assembled in constants/prompts.ts from the section files in constants/systemPromptSections.ts. You can dump the exact prompt via the internal --dump-system-prompt flag.
entrypoints/cli.tsx → main.tsx parses flags, loads config, starts the REPL (or a one-shot print mode).
An Ink (React-in-the-terminal) app renders the chat, input box, status line, and dialogs. State lives in state/AppState.
Every turn goes through query.ts / QueryEngine.ts: build messages → call API → handle tool uses → compact if needed → repeat.
Each tool in tools/ owns its schema, permission checks, execution, and terminal UI. Registered in tools.ts.
Long work goes into the task registry (tasks/). Sub-agents spawned by AgentTool are just another task type.
Outside-world integrations: Anthropic API, MCP servers, OAuth, analytics, plugins, team sync, compaction. All under services/.
Persisted in memdir/. Loaded at session start, updated when you (or the agent) decide something is worth keeping.
When you send a message, picture a conveyor belt:
That's the whole thing. Everything else in this repository is either a new tool, a new kind of task, a new way to render the belt, or a guardrail to keep the belt from hitting something it shouldn't.