Claude
Skills
Sign in
Back

learn-coding-agent

Included with Lifetime
$97 forever

```markdown

AI Agents

What this skill does

```markdown
---
name: learn-coding-agent
description: Architecture reference and deep analysis skill for Claude Code CLI agent internals, patterns, and implementation details
triggers:
  - "explain how claude code works internally"
  - "help me understand coding agent architecture"
  - "what is the claude code agent loop"
  - "how do claude code tools work"
  - "explain claude code permission system"
  - "how does claude code handle context compaction"
  - "what are claude code sub-agents"
  - "help me build a coding agent like claude code"
---

# Learn Coding Agent — Claude Code Architecture Reference

> Skill by [ara.so](https://ara.so) — Daily 2026 Skills collection

A research repository documenting the internal architecture of Claude Code (v2.1.88), the highly popular CLI coding agent by Anthropic. This skill gives AI coding agents deep knowledge of agent loop patterns, tool systems, permission flows, telemetry, and production harness mechanisms derived from publicly available sources.

---

## What This Project Covers

This repository provides:
- **Deep analysis reports** on telemetry, hidden features, remote control, and future roadmap (EN/JA/KO/ZH)
- **Architecture diagrams** of the agent loop, tool system, and service layer
- **Code structure reference** for Claude Code's ~512K-line TypeScript codebase
- **12 progressive harness mechanisms** layered on top of the minimal agent loop
- Research for developers building their own coding agents

---

## The Minimal Agent Loop

The core pattern underlying Claude Code (and most coding agents):

```typescript
// Minimal agent loop — the foundation everything else builds on
async function agentLoop(userMessage: string) {
  const messages: Message[] = [
    { role: "user", content: userMessage }
  ];

  while (true) {
    const response = await claude.messages.create({
      model: "claude-opus-4-5",
      max_tokens: 8096,
      tools: TOOL_DEFINITIONS,
      messages,
    });

    if (response.stop_reason === "end_turn") {
      // Final text response — return to user
      return extractText(response.content);
    }

    if (response.stop_reason === "tool_use") {
      // Execute each tool the model requested
      const toolResults = await executeTools(response.content);

      // Append assistant response + tool results and loop
      messages.push({ role: "assistant", content: response.content });
      messages.push({ role: "user", content: toolResults });
      // → loop back to API call
    }
  }
}
```

**Key insight**: This 20-line loop is the entire agent. Claude Code wraps it with a production harness of 12 mechanisms.

---

## The 12 Progressive Harness Mechanisms

Claude Code layers these on top of the minimal loop:

| # | Mechanism | Purpose |
|---|-----------|---------|
| 1 | **Streaming** | Stream tokens to terminal as they arrive |
| 2 | **Permission gate** | Block dangerous tools until user approves |
| 3 | **Parallel tool execution** | Run independent tools concurrently |
| 4 | **Context compaction** | Summarize old messages when near token limit |
| 5 | **Sub-agents** | Spawn child agent processes for subtasks |
| 6 | **Persistence** | Save/resume sessions across restarts |
| 7 | **MCP integration** | Connect external tool servers via protocol |
| 8 | **Cost tracking** | Accumulate and display API spend |
| 9 | **Retry + error handling** | Categorize and retry transient failures |
| 10 | **Telemetry** | Track usage events to Anthropic + Datadog |
| 11 | **Settings sync** | Remote-controlled feature flags via GrowthBook |
| 12 | **KAIROS mode** | Autonomous `<tick>` heartbeat for background tasks |

---

## Tool System Architecture

### Tool Interface Pattern

```typescript
// Based on Claude Code's Tool.ts pattern
interface Tool<TInput, TOutput> {
  name: string;
  description: string;
  inputSchema: JSONSchema;
  
  // Permission check before execution
  checkPermission(input: TInput, context: PermissionContext): PermissionResult;
  
  // Actual execution
  execute(input: TInput, context: ExecutionContext): Promise<TOutput>;
  
  // Whether this tool can run in parallel with others
  isReadOnly: boolean;
}

// buildTool factory pattern
function buildTool<TInput, TOutput>(config: ToolConfig<TInput, TOutput>): Tool<TInput, TOutput> {
  return {
    name: config.name,
    description: config.description,
    inputSchema: config.inputSchema,
    checkPermission: config.checkPermission ?? defaultPermissionCheck,
    execute: config.execute,
    isReadOnly: config.isReadOnly ?? false,
  };
}

// Example: a simple file-reading tool
const readFileTool = buildTool({
  name: "read_file",
  description: "Read the contents of a file",
  isReadOnly: true,
  inputSchema: {
    type: "object",
    properties: {
      path: { type: "string", description: "Absolute or relative file path" }
    },
    required: ["path"]
  },
  checkPermission: (input, ctx) => {
    if (isPathOutsideWorkdir(input.path, ctx.workdir)) {
      return { allowed: false, reason: "Path outside working directory" };
    }
    return { allowed: true };
  },
  execute: async (input) => {
    const content = await fs.readFile(input.path, "utf-8");
    return { content, lines: content.split("\n").length };
  }
});
```

### Permission Flow

```typescript
// Permission decision hierarchy (Claude Code pattern)
type PermissionLevel = 
  | "always_allow"    // Pre-approved (e.g., read-only tools)
  | "ask_once"        // Prompt once, remember for session  
  | "ask_every_time"  // Prompt on each invocation
  | "never_allow";    // Blocked (e.g., rm -rf patterns)

async function executeWithPermission(
  tool: Tool,
  input: unknown,
  permissionStore: PermissionStore
): Promise<ToolResult> {
  const cached = permissionStore.get(tool.name, input);
  
  if (cached === "denied") {
    return { error: "Permission denied by user" };
  }
  
  if (cached !== "granted") {
    // Show permission dialog to user
    const decision = await promptUserForPermission(tool, input);
    permissionStore.set(tool.name, input, decision);
    
    if (decision === "denied") {
      return { error: "Permission denied by user" };
    }
  }
  
  return tool.execute(input);
}
```

---

## Parallel Tool Execution (StreamingToolExecutor Pattern)

```typescript
// Claude Code runs independent tools concurrently
async function executeToolsBatch(
  toolUseBlocks: ToolUseBlock[],
  tools: Map<string, Tool>
): Promise<ToolResult[]> {
  // Separate read-only (parallelizable) from write (sequential)
  const readOnly = toolUseBlocks.filter(t => tools.get(t.name)?.isReadOnly);
  const writes = toolUseBlocks.filter(t => !tools.get(t.name)?.isReadOnly);

  // Run all reads in parallel
  const readResults = await Promise.all(
    readOnly.map(block => executeSingleTool(block, tools))
  );

  // Run writes sequentially to avoid conflicts
  const writeResults: ToolResult[] = [];
  for (const block of writes) {
    writeResults.push(await executeSingleTool(block, tools));
  }

  // Reassemble in original order
  return toolUseBlocks.map(block => 
    [...readResults, ...writeResults].find(r => r.toolUseId === block.id)!
  );
}
```

---

## Context Compaction Pattern

```typescript
// When approaching token limit, summarize conversation history
async function compactContextIfNeeded(
  messages: Message[],
  currentTokenCount: number,
  tokenLimit: number
): Promise<Message[]> {
  const COMPACTION_THRESHOLD = 0.85; // compact at 85% of limit
  
  if (currentTokenCount < tokenLimit * COMPACTION_THRESHOLD) {
    return messages; // No compaction needed
  }

  // Keep system prompt + recent messages, summarize the middle
  const [systemMsg, ...rest] = messages;
  const recentMessages = rest.slice(-10); // Keep last 10 exchanges
  const oldMessages = rest.slice(0, -10);

  if (oldMessages.length === 0) return messages;

  // Ask Claude to summarize old context
  const summary = await claude.messages.create({
    model: "claude-haiku-4-5", // Use faster/cheaper model for compacti

Related in AI Agents