✨ milady
This commit is contained in:
8
.github/copilot-instructions.md
vendored
8
.github/copilot-instructions.md
vendored
@@ -64,4 +64,12 @@ Bun strips inactive code at build time via `import { feature } from 'bun:bundle'
|
||||
- **Follow the bridge**: IDE integration starts at `src/bridge/bridgeMain.ts`
|
||||
- **MCP integration**: `src/services/mcp/`
|
||||
|
||||
## Terminal Management
|
||||
|
||||
- **Always use background terminals** (`isBackground: true`) for every command so a terminal ID is returned
|
||||
- **Always kill the terminal** after the command completes, whether it succeeds or fails — never leave terminals open
|
||||
- Do not reuse foreground shell sessions — stale sessions block future terminal operations in Codespaces
|
||||
- In GitHub Codespaces, agent-spawned terminals may be hidden — they still work. Do not assume a terminal is broken if you cannot see it
|
||||
- If a terminal appears unresponsive, kill it and create a new one rather than retrying in the same terminal
|
||||
|
||||
|
||||
|
||||
48
.github/workflows/publish-mcp.yml
vendored
Normal file
48
.github/workflows/publish-mcp.yml
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
name: Publish to MCP Registry
|
||||
|
||||
on:
|
||||
push:
|
||||
tags: ["v*"]
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
name: Publish MCP Server
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: read
|
||||
defaults:
|
||||
run:
|
||||
working-directory: mcp-server
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "22"
|
||||
registry-url: "https://registry.npmjs.org"
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Build
|
||||
run: npm run build
|
||||
|
||||
- name: Publish to npm
|
||||
run: npm publish --access public
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
- name: Install MCP Publisher CLI
|
||||
run: |
|
||||
curl -L "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" | tar xz mcp-publisher
|
||||
working-directory: ${{ github.workspace }}
|
||||
|
||||
- name: Login to MCP Registry
|
||||
run: ../mcp-publisher login github-oidc
|
||||
working-directory: ${{ github.workspace }}/mcp-server
|
||||
|
||||
- name: Publish to MCP Registry
|
||||
run: ../mcp-publisher publish
|
||||
working-directory: ${{ github.workspace }}/mcp-server
|
||||
72
CONTRIBUTING.md
Normal file
72
CONTRIBUTING.md
Normal file
@@ -0,0 +1,72 @@
|
||||
# Contributing
|
||||
|
||||
Thanks for your interest in contributing to this repository!
|
||||
|
||||
## What This Is
|
||||
|
||||
This repo archives the **leaked source code** of Anthropic's Claude Code CLI. Contributions here are about **documentation, tooling, and exploration aids** — not modifying the original Claude Code source.
|
||||
|
||||
## What You Can Contribute
|
||||
|
||||
- **Documentation** — Improve or expand the [docs/](docs/) directory
|
||||
- **MCP Server** — Enhance the exploration MCP server in [mcp-server/](mcp-server/)
|
||||
- **Analysis** — Write-ups, architecture diagrams, or annotated walkthroughs
|
||||
- **Tooling** — Scripts or tools that aid in studying the source code
|
||||
- **Bug fixes** — Fix issues in the MCP server or supporting infrastructure
|
||||
|
||||
## What Not to Change
|
||||
|
||||
- **`src/` directory** — This is the original leaked source, preserved as-is. Don't modify it.
|
||||
- The [`backup` branch](https://github.com/nirholas/claude-code/tree/backup) contains the unmodified original.
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- **Node.js** 18+ (for the MCP server)
|
||||
- **Git**
|
||||
|
||||
### Setup
|
||||
|
||||
```bash
|
||||
git clone https://github.com/nirholas/claude-code.git
|
||||
cd claude-code
|
||||
```
|
||||
|
||||
### MCP Server Development
|
||||
|
||||
```bash
|
||||
cd mcp-server
|
||||
npm install
|
||||
npm run dev # Run with tsx (no build step)
|
||||
npm run build # Compile to dist/
|
||||
```
|
||||
|
||||
### Linting & Type Checking
|
||||
|
||||
```bash
|
||||
# From the repo root — checks the leaked src/
|
||||
npm run lint # Biome lint
|
||||
npm run typecheck # TypeScript type check
|
||||
```
|
||||
|
||||
## Code Style
|
||||
|
||||
For any new code (MCP server, tooling, scripts):
|
||||
|
||||
- TypeScript with strict mode
|
||||
- ES modules
|
||||
- 2-space indentation (tabs for `src/` to match Biome config)
|
||||
- Descriptive variable names, minimal comments
|
||||
|
||||
## Submitting Changes
|
||||
|
||||
1. Fork the repository
|
||||
2. Create a feature branch (`git checkout -b my-feature`)
|
||||
3. Make your changes
|
||||
4. Commit with a clear message
|
||||
5. Push and open a pull request
|
||||
|
||||
## Questions?
|
||||
|
||||
Open an issue or reach out to [nichxbt](https://www.x.com/nichxbt).
|
||||
487
README.md
487
README.md
@@ -1,34 +1,182 @@
|
||||
> **Note:** The original unmodified leaked source is preserved in the [`backup` branch](https://github.com/nirholas/claude-code/tree/backup).
|
||||
<div align="center">
|
||||
|
||||
# Claude Code — Leaked Source (2026-03-31)
|
||||
# Claude Code — Leaked Source
|
||||
|
||||
> **On March 31, 2026, the full source code of Anthropic's Claude Code CLI was leaked** via a `.map` file exposed in their npm registry.
|
||||
**The full source code of Anthropic's Claude Code CLI, leaked on March 31, 2026**
|
||||
|
||||
[](#tech-stack)
|
||||
[](#tech-stack)
|
||||
[](#tech-stack)
|
||||
[](#directory-structure)
|
||||
[](#-explore-with-mcp-server)
|
||||
|
||||
> The original unmodified leaked source is preserved in the [`backup` branch](https://github.com/nirholas/claude-code/tree/backup).
|
||||
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [How It Leaked](#how-it-leaked)
|
||||
- [What Is Claude Code?](#what-is-claude-code)
|
||||
- [Documentation](#-documentation)
|
||||
- [Explore with MCP Server](#-explore-with-mcp-server)
|
||||
- [Directory Structure](#directory-structure)
|
||||
- [Architecture](#architecture)
|
||||
- [Tool System](#1-tool-system)
|
||||
- [Command System](#2-command-system)
|
||||
- [Service Layer](#3-service-layer)
|
||||
- [Bridge System](#4-bridge-system)
|
||||
- [Permission System](#5-permission-system)
|
||||
- [Feature Flags](#6-feature-flags)
|
||||
- [Key Files](#key-files)
|
||||
- [Tech Stack](#tech-stack)
|
||||
- [Design Patterns](#design-patterns)
|
||||
- [GitPretty Setup](#gitpretty-setup)
|
||||
- [Contributing](#contributing)
|
||||
- [Disclaimer](#disclaimer)
|
||||
|
||||
---
|
||||
|
||||
## How It Leaked
|
||||
|
||||
[Chaofan Shou (@Fried_rice)](https://x.com/Fried_rice) discovered the leak and posted it publicly:
|
||||
[Chaofan Shou (@Fried_rice)](https://x.com/Fried_rice) discovered that the published npm package for Claude Code included a `.map` file referencing the full, unobfuscated TypeScript source — downloadable as a zip from Anthropic's R2 storage bucket.
|
||||
|
||||
> **"Claude code source code has been leaked via a map file in their npm registry!"**
|
||||
>
|
||||
> — [@Fried_rice, March 31, 2026](https://x.com/Fried_rice/status/2038894956459290963)
|
||||
|
||||
The source map file in the published npm package contained a reference to the full, unobfuscated TypeScript source, which was downloadable as a zip archive from Anthropic's R2 storage bucket.
|
||||
---
|
||||
|
||||
## What Is Claude Code?
|
||||
|
||||
Claude Code is Anthropic's official CLI tool for interacting with Claude directly from the terminal — editing files, running commands, searching codebases, managing git workflows, and more. This repository contains the leaked `src/` directory.
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| **Leaked** | 2026-03-31 |
|
||||
| **Language** | TypeScript (strict) |
|
||||
| **Runtime** | [Bun](https://bun.sh) |
|
||||
| **Terminal UI** | [React](https://react.dev) + [Ink](https://github.com/vadimdemedes/ink) |
|
||||
| **Scale** | ~1,900 files · 512,000+ lines of code |
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
## <EFBFBD> Documentation
|
||||
|
||||
Claude Code is Anthropic's official CLI tool that lets you interact with Claude directly from the terminal to perform software engineering tasks — editing files, running commands, searching codebases, managing git workflows, and more.
|
||||
For in-depth guides, see the [`docs/`](docs/) directory:
|
||||
|
||||
This repository contains the leaked `src/` directory.
|
||||
| Guide | Description |
|
||||
|-------|-------------|
|
||||
| **[Architecture](docs/architecture.md)** | Core pipeline, startup sequence, state management, rendering, data flow |
|
||||
| **[Tools Reference](docs/tools.md)** | Complete catalog of all ~40 agent tools with categories and permission model |
|
||||
| **[Commands Reference](docs/commands.md)** | All ~85 slash commands organized by category |
|
||||
| **[Subsystems Guide](docs/subsystems.md)** | Deep dives into Bridge, MCP, Permissions, Plugins, Skills, Tasks, Memory, Voice |
|
||||
| **[Exploration Guide](docs/exploration-guide.md)** | How to navigate the codebase — study paths, grep patterns, key files |
|
||||
|
||||
- **Leaked on**: 2026-03-31
|
||||
- **Language**: TypeScript
|
||||
- **Runtime**: Bun
|
||||
- **Terminal UI**: React + [Ink](https://github.com/vadimdemedes/ink) (React for CLI)
|
||||
- **Scale**: ~1,900 files, 512,000+ lines of code
|
||||
Also see: [CONTRIBUTING.md](CONTRIBUTING.md) · [MCP Server README](mcp-server/README.md)
|
||||
|
||||
---
|
||||
|
||||
## <20>🔍 Explore with MCP Server
|
||||
|
||||
This repo ships an [MCP server](https://modelcontextprotocol.io/) that lets any MCP-compatible client (Claude Code, Claude Desktop, VS Code Copilot, Cursor) explore the full source interactively.
|
||||
|
||||
### One-liner setup
|
||||
|
||||
```bash
|
||||
git clone https://github.com/nirholas/claude-code.git ~/claude-code \
|
||||
&& cd ~/claude-code/mcp-server \
|
||||
&& npm install && npm run build \
|
||||
&& claude mcp add claude-code-explorer -- node ~/claude-code/mcp-server/dist/index.js
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary><strong>Step-by-step setup</strong></summary>
|
||||
|
||||
```bash
|
||||
# 1. Clone the repo
|
||||
git clone https://github.com/nirholas/claude-code.git
|
||||
cd claude-code/mcp-server
|
||||
|
||||
# 2. Install & build
|
||||
npm install && npm run build
|
||||
|
||||
# 3. Register with Claude Code
|
||||
claude mcp add claude-code-explorer -- node /absolute/path/to/claude-code/mcp-server/dist/index.js
|
||||
```
|
||||
|
||||
Replace `/absolute/path/to/claude-code` with your actual clone path.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>VS Code / Cursor / Claude Desktop config</strong></summary>
|
||||
|
||||
**VS Code** — add to `.vscode/mcp.json`:
|
||||
```json
|
||||
{
|
||||
"servers": {
|
||||
"claude-code-explorer": {
|
||||
"type": "stdio",
|
||||
"command": "node",
|
||||
"args": ["${workspaceFolder}/mcp-server/dist/index.js"],
|
||||
"env": { "CLAUDE_CODE_SRC_ROOT": "${workspaceFolder}/src" }
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Claude Desktop** — add to your config file:
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"claude-code-explorer": {
|
||||
"command": "node",
|
||||
"args": ["/absolute/path/to/claude-code/mcp-server/dist/index.js"],
|
||||
"env": { "CLAUDE_CODE_SRC_ROOT": "/absolute/path/to/claude-code/src" }
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Cursor** — add to `~/.cursor/mcp.json` (same format as Claude Desktop).
|
||||
|
||||
</details>
|
||||
|
||||
### Available tools & prompts
|
||||
|
||||
| Tool | Description |
|
||||
|------|-------------|
|
||||
| `list_tools` | List all ~40 agent tools with source files |
|
||||
| `list_commands` | List all ~50 slash commands with source files |
|
||||
| `get_tool_source` | Read full source of any tool (e.g. BashTool, FileEditTool) |
|
||||
| `get_command_source` | Read source of any slash command (e.g. review, mcp) |
|
||||
| `read_source_file` | Read any file from `src/` by path |
|
||||
| `search_source` | Grep across the entire source tree |
|
||||
| `list_directory` | Browse `src/` directories |
|
||||
| `get_architecture` | High-level architecture overview |
|
||||
|
||||
| Prompt | Description |
|
||||
|--------|-------------|
|
||||
| `explain_tool` | Deep-dive into how a specific tool works |
|
||||
| `explain_command` | Understand a slash command's implementation |
|
||||
| `architecture_overview` | Guided tour of the full architecture |
|
||||
| `how_does_it_work` | Explain any subsystem (permissions, MCP, bridge, etc.) |
|
||||
| `compare_tools` | Side-by-side comparison of two tools |
|
||||
|
||||
**Try asking:** *"How does the BashTool work?"* · *"Search for where permissions are checked"* · *"Show me the /review command source"*
|
||||
|
||||
### Custom source path / Remove
|
||||
|
||||
```bash
|
||||
# Custom source location
|
||||
claude mcp add claude-code-explorer -e CLAUDE_CODE_SRC_ROOT=/path/to/src -- node /path/to/mcp-server/dist/index.js
|
||||
|
||||
# Remove
|
||||
claude mcp remove claude-code-explorer
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -36,173 +184,158 @@ This repository contains the leaked `src/` directory.
|
||||
|
||||
```
|
||||
src/
|
||||
├── main.tsx # Entrypoint (Commander.js-based CLI parser)
|
||||
├── commands.ts # Command registry
|
||||
├── main.tsx # Entrypoint — Commander.js CLI parser + React/Ink renderer
|
||||
├── QueryEngine.ts # Core LLM API caller (~46K lines)
|
||||
├── Tool.ts # Tool type definitions (~29K lines)
|
||||
├── commands.ts # Command registry (~25K lines)
|
||||
├── tools.ts # Tool registry
|
||||
├── Tool.ts # Tool type definitions
|
||||
├── QueryEngine.ts # LLM query engine (core Anthropic API caller)
|
||||
├── context.ts # System/user context collection
|
||||
├── cost-tracker.ts # Token cost tracking
|
||||
│
|
||||
├── commands/ # Slash command implementations (~50)
|
||||
├── tools/ # Agent tool implementations (~40)
|
||||
├── commands/ # Slash command implementations (~50)
|
||||
├── components/ # Ink UI components (~140)
|
||||
├── hooks/ # React hooks
|
||||
├── services/ # External service integrations
|
||||
├── screens/ # Full-screen UIs (Doctor, REPL, Resume)
|
||||
├── hooks/ # React hooks (incl. permission checks)
|
||||
├── types/ # TypeScript type definitions
|
||||
├── utils/ # Utility functions
|
||||
├── screens/ # Full-screen UIs (Doctor, REPL, Resume)
|
||||
│
|
||||
├── bridge/ # IDE integration bridge (VS Code, JetBrains)
|
||||
├── coordinator/ # Multi-agent coordinator
|
||||
├── bridge/ # IDE integration (VS Code, JetBrains)
|
||||
├── coordinator/ # Multi-agent orchestration
|
||||
├── plugins/ # Plugin system
|
||||
├── skills/ # Skill system
|
||||
├── keybindings/ # Keybinding configuration
|
||||
├── vim/ # Vim mode
|
||||
├── voice/ # Voice input
|
||||
├── remote/ # Remote sessions
|
||||
├── server/ # Server mode
|
||||
├── memdir/ # Memory directory (persistent memory)
|
||||
├── remote/ # Remote sessions
|
||||
├── memdir/ # Persistent memory directory
|
||||
├── tasks/ # Task management
|
||||
├── state/ # State management
|
||||
├── migrations/ # Config migrations
|
||||
│
|
||||
├── voice/ # Voice input
|
||||
├── vim/ # Vim mode
|
||||
├── keybindings/ # Keybinding configuration
|
||||
├── schemas/ # Config schemas (Zod)
|
||||
├── migrations/ # Config migrations
|
||||
├── entrypoints/ # Initialization logic
|
||||
├── query/ # Query pipeline
|
||||
├── ink/ # Ink renderer wrapper
|
||||
├── buddy/ # Companion sprite (Easter egg)
|
||||
├── buddy/ # Companion sprite (Easter egg 🐣)
|
||||
├── native-ts/ # Native TypeScript utils
|
||||
├── outputStyles/ # Output styling
|
||||
├── query/ # Query pipeline
|
||||
└── upstreamproxy/ # Proxy configuration
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Core Architecture
|
||||
## Architecture
|
||||
|
||||
### 1. Tool System (`src/tools/`)
|
||||
### 1. Tool System
|
||||
|
||||
Every tool Claude Code can invoke is implemented as a self-contained module. Each tool defines its input schema, permission model, and execution logic.
|
||||
> `src/tools/` — Every tool Claude can invoke is a self-contained module with its own input schema, permission model, and execution logic.
|
||||
|
||||
| Tool | Description |
|
||||
|---|---|
|
||||
| `BashTool` | Shell command execution |
|
||||
| `FileReadTool` | File reading (images, PDFs, notebooks) |
|
||||
| `FileWriteTool` | File creation / overwrite |
|
||||
| `FileEditTool` | Partial file modification (string replacement) |
|
||||
| `GlobTool` | File pattern matching search |
|
||||
| **File I/O** | |
|
||||
| `FileReadTool` | Read files (images, PDFs, notebooks) |
|
||||
| `FileWriteTool` | Create / overwrite files |
|
||||
| `FileEditTool` | Partial modification (string replacement) |
|
||||
| `NotebookEditTool` | Jupyter notebook editing |
|
||||
| **Search** | |
|
||||
| `GlobTool` | File pattern matching |
|
||||
| `GrepTool` | ripgrep-based content search |
|
||||
| `WebFetchTool` | Fetch URL content |
|
||||
| `WebSearchTool` | Web search |
|
||||
| `AgentTool` | Sub-agent spawning |
|
||||
| `WebFetchTool` | Fetch URL content |
|
||||
| **Execution** | |
|
||||
| `BashTool` | Shell command execution |
|
||||
| `SkillTool` | Skill execution |
|
||||
| `MCPTool` | MCP server tool invocation |
|
||||
| `LSPTool` | Language Server Protocol integration |
|
||||
| `NotebookEditTool` | Jupyter notebook editing |
|
||||
| `TaskCreateTool` / `TaskUpdateTool` | Task creation and management |
|
||||
| **Agents & Teams** | |
|
||||
| `AgentTool` | Sub-agent spawning |
|
||||
| `SendMessageTool` | Inter-agent messaging |
|
||||
| `TeamCreateTool` / `TeamDeleteTool` | Team agent management |
|
||||
| `TeamCreateTool` / `TeamDeleteTool` | Team management |
|
||||
| `TaskCreateTool` / `TaskUpdateTool` | Task management |
|
||||
| **Mode & State** | |
|
||||
| `EnterPlanModeTool` / `ExitPlanModeTool` | Plan mode toggle |
|
||||
| `EnterWorktreeTool` / `ExitWorktreeTool` | Git worktree isolation |
|
||||
| `ToolSearchTool` | Deferred tool discovery |
|
||||
| `CronCreateTool` | Scheduled trigger creation |
|
||||
| `RemoteTriggerTool` | Remote trigger |
|
||||
| `SleepTool` | Proactive mode wait |
|
||||
| `CronCreateTool` | Scheduled triggers |
|
||||
| `RemoteTriggerTool` | Remote trigger |
|
||||
| `SyntheticOutputTool` | Structured output generation |
|
||||
|
||||
### 2. Command System (`src/commands/`)
|
||||
### 2. Command System
|
||||
|
||||
User-facing slash commands invoked with `/` prefix.
|
||||
> `src/commands/` — User-facing slash commands invoked with `/` in the REPL.
|
||||
|
||||
| Command | Description |
|
||||
|---|---|
|
||||
| `/commit` | Create a git commit |
|
||||
| `/review` | Code review |
|
||||
| `/compact` | Context compression |
|
||||
| `/mcp` | MCP server management |
|
||||
| `/config` | Settings management |
|
||||
| `/doctor` | Environment diagnostics |
|
||||
| `/login` / `/logout` | Authentication |
|
||||
| `/memory` | Persistent memory management |
|
||||
| `/skills` | Skill management |
|
||||
| `/tasks` | Task management |
|
||||
| `/vim` | Vim mode toggle |
|
||||
| `/diff` | View changes |
|
||||
| `/cost` | Check usage cost |
|
||||
| `/theme` | Change theme |
|
||||
| `/context` | Context visualization |
|
||||
| `/pr_comments` | View PR comments |
|
||||
| `/resume` | Restore previous session |
|
||||
| `/share` | Share session |
|
||||
| `/desktop` | Desktop app handoff |
|
||||
| `/mobile` | Mobile app handoff |
|
||||
| Command | Description | | Command | Description |
|
||||
|---|---|---|---|---|
|
||||
| `/commit` | Git commit | | `/memory` | Persistent memory |
|
||||
| `/review` | Code review | | `/skills` | Skill management |
|
||||
| `/compact` | Context compression | | `/tasks` | Task management |
|
||||
| `/mcp` | MCP server management | | `/vim` | Vim mode toggle |
|
||||
| `/config` | Settings | | `/diff` | View changes |
|
||||
| `/doctor` | Environment diagnostics | | `/cost` | Check usage cost |
|
||||
| `/login` / `/logout` | Auth | | `/theme` | Change theme |
|
||||
| `/context` | Context visualization | | `/share` | Share session |
|
||||
| `/pr_comments` | PR comments | | `/resume` | Restore session |
|
||||
| `/desktop` | Desktop handoff | | `/mobile` | Mobile handoff |
|
||||
|
||||
### 3. Service Layer (`src/services/`)
|
||||
### 3. Service Layer
|
||||
|
||||
> `src/services/` — External integrations and core infrastructure.
|
||||
|
||||
| Service | Description |
|
||||
|---|---|
|
||||
| `api/` | Anthropic API client, file API, bootstrap |
|
||||
| `mcp/` | Model Context Protocol server connection and management |
|
||||
| `oauth/` | OAuth 2.0 authentication flow |
|
||||
| `mcp/` | Model Context Protocol connection & management |
|
||||
| `oauth/` | OAuth 2.0 authentication |
|
||||
| `lsp/` | Language Server Protocol manager |
|
||||
| `analytics/` | GrowthBook-based feature flags and analytics |
|
||||
| `analytics/` | GrowthBook feature flags & analytics |
|
||||
| `plugins/` | Plugin loader |
|
||||
| `compact/` | Conversation context compression |
|
||||
| `extractMemories/` | Automatic memory extraction |
|
||||
| `teamMemorySync/` | Team memory synchronization |
|
||||
| `tokenEstimation.ts` | Token count estimation |
|
||||
| `policyLimits/` | Organization policy limits |
|
||||
| `remoteManagedSettings/` | Remote managed settings |
|
||||
| `extractMemories/` | Automatic memory extraction |
|
||||
| `tokenEstimation.ts` | Token count estimation |
|
||||
| `teamMemorySync/` | Team memory synchronization |
|
||||
|
||||
### 4. Bridge System (`src/bridge/`)
|
||||
### 4. Bridge System
|
||||
|
||||
A bidirectional communication layer connecting IDE extensions (VS Code, JetBrains) with the Claude Code CLI.
|
||||
> `src/bridge/` — Bidirectional communication layer connecting IDE extensions (VS Code, JetBrains) with the CLI.
|
||||
|
||||
- `bridgeMain.ts` — Bridge main loop
|
||||
- `bridgeMessaging.ts` — Message protocol
|
||||
- `bridgePermissionCallbacks.ts` — Permission callbacks
|
||||
- `replBridge.ts` — REPL session bridge
|
||||
- `jwtUtils.ts` — JWT-based authentication
|
||||
- `sessionRunner.ts` — Session execution management
|
||||
Key files: `bridgeMain.ts` (main loop) · `bridgeMessaging.ts` (protocol) · `bridgePermissionCallbacks.ts` (permission callbacks) · `replBridge.ts` (REPL session) · `jwtUtils.ts` (JWT auth) · `sessionRunner.ts` (session execution)
|
||||
|
||||
### 5. Permission System (`src/hooks/toolPermission/`)
|
||||
### 5. Permission System
|
||||
|
||||
Checks permissions on every tool invocation. Either prompts the user for approval/denial or automatically resolves based on the configured permission mode (`default`, `plan`, `bypassPermissions`, `auto`, etc.).
|
||||
> `src/hooks/toolPermission/` — Checks permissions on every tool invocation.
|
||||
|
||||
Prompts the user for approval/denial or auto-resolves based on the configured permission mode: `default`, `plan`, `bypassPermissions`, `auto`, etc.
|
||||
|
||||
### 6. Feature Flags
|
||||
|
||||
Dead code elimination via Bun's `bun:bundle` feature flags:
|
||||
Dead code elimination at build time via Bun's `bun:bundle`:
|
||||
|
||||
```typescript
|
||||
import { feature } from 'bun:bundle'
|
||||
|
||||
// Inactive code is completely stripped at build time
|
||||
const voiceCommand = feature('VOICE_MODE')
|
||||
? require('./commands/voice/index.js').default
|
||||
: null
|
||||
```
|
||||
|
||||
Notable flags: `PROACTIVE`, `KAIROS`, `BRIDGE_MODE`, `DAEMON`, `VOICE_MODE`, `AGENT_TRIGGERS`, `MONITOR_TOOL`
|
||||
Notable flags: `PROACTIVE` · `KAIROS` · `BRIDGE_MODE` · `DAEMON` · `VOICE_MODE` · `AGENT_TRIGGERS` · `MONITOR_TOOL`
|
||||
|
||||
---
|
||||
|
||||
## Key Files in Detail
|
||||
## Key Files
|
||||
|
||||
### `QueryEngine.ts` (~46K lines)
|
||||
|
||||
The core engine for LLM API calls. Handles streaming responses, tool-call loops, thinking mode, retry logic, and token counting.
|
||||
|
||||
### `Tool.ts` (~29K lines)
|
||||
|
||||
Defines base types and interfaces for all tools — input schemas, permission models, and progress state types.
|
||||
|
||||
### `commands.ts` (~25K lines)
|
||||
|
||||
Manages registration and execution of all slash commands. Uses conditional imports to load different command sets per environment.
|
||||
|
||||
### `main.tsx`
|
||||
|
||||
Commander.js-based CLI parser + React/Ink renderer initialization. At startup, parallelizes MDM settings, keychain prefetch, and GrowthBook initialization for faster boot.
|
||||
| File | Lines | Purpose |
|
||||
|------|------:|---------|
|
||||
| `QueryEngine.ts` | ~46K | Core LLM API engine — streaming, tool loops, thinking mode, retries, token counting |
|
||||
| `Tool.ts` | ~29K | Base types/interfaces for all tools — input schemas, permissions, progress state |
|
||||
| `commands.ts` | ~25K | Command registration & execution with conditional per-environment imports |
|
||||
| `main.tsx` | — | CLI parser + React/Ink renderer; parallelizes MDM, keychain, and GrowthBook on startup |
|
||||
|
||||
---
|
||||
|
||||
@@ -216,151 +349,89 @@ Commander.js-based CLI parser + React/Ink renderer initialization. At startup, p
|
||||
| CLI Parsing | [Commander.js](https://github.com/tj/commander.js) (extra-typings) |
|
||||
| Schema Validation | [Zod v4](https://zod.dev) |
|
||||
| Code Search | [ripgrep](https://github.com/BurntSushi/ripgrep) (via GrepTool) |
|
||||
| Protocols | [MCP SDK](https://modelcontextprotocol.io), LSP |
|
||||
| Protocols | [MCP SDK](https://modelcontextprotocol.io) · LSP |
|
||||
| API | [Anthropic SDK](https://docs.anthropic.com) |
|
||||
| Telemetry | OpenTelemetry + gRPC |
|
||||
| Feature Flags | GrowthBook |
|
||||
| Auth | OAuth 2.0, JWT, macOS Keychain |
|
||||
| Auth | OAuth 2.0 · JWT · macOS Keychain |
|
||||
|
||||
---
|
||||
|
||||
## Notable Design Patterns
|
||||
## Design Patterns
|
||||
|
||||
### Parallel Prefetch
|
||||
<details>
|
||||
<summary><strong>Parallel Prefetch</strong> — Startup optimization</summary>
|
||||
|
||||
Startup time is optimized by prefetching MDM settings, keychain reads, and API preconnect in parallel — before heavy module evaluation begins.
|
||||
MDM settings, keychain reads, and API preconnect fire in parallel as side-effects before heavy module evaluation:
|
||||
|
||||
```typescript
|
||||
// main.tsx — fired as side-effects before other imports
|
||||
// main.tsx
|
||||
startMdmRawRead()
|
||||
startKeychainPrefetch()
|
||||
```
|
||||
|
||||
### Lazy Loading
|
||||
</details>
|
||||
|
||||
Heavy modules (OpenTelemetry ~400KB, gRPC ~700KB) are deferred via dynamic `import()` until actually needed.
|
||||
<details>
|
||||
<summary><strong>Lazy Loading</strong> — Deferred heavy modules</summary>
|
||||
|
||||
### Agent Swarms
|
||||
OpenTelemetry (~400KB) and gRPC (~700KB) are loaded via dynamic `import()` only when needed.
|
||||
|
||||
Sub-agents are spawned via `AgentTool`, with `coordinator/` handling multi-agent orchestration. `TeamCreateTool` enables team-level parallel work.
|
||||
</details>
|
||||
|
||||
### Skill System
|
||||
<details>
|
||||
<summary><strong>Agent Swarms</strong> — Multi-agent orchestration</summary>
|
||||
|
||||
Reusable workflows defined in `skills/` and executed through `SkillTool`. Users can add custom skills.
|
||||
Sub-agents spawn via `AgentTool`, with `coordinator/` handling orchestration. `TeamCreateTool` enables team-level parallel work.
|
||||
|
||||
### Plugin Architecture
|
||||
</details>
|
||||
|
||||
Built-in and third-party plugins are loaded through the `plugins/` subsystem.
|
||||
<details>
|
||||
<summary><strong>Skill System</strong> — Reusable workflows</summary>
|
||||
|
||||
Defined in `skills/` and executed through `SkillTool`. Users can add custom skills.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Plugin Architecture</strong> — Extensibility</summary>
|
||||
|
||||
Built-in and third-party plugins loaded through the `plugins/` subsystem.
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
## GitPretty Setup (Per-File Pretty Commits)
|
||||
## GitPretty Setup
|
||||
|
||||
If you want GitHub's file UI to show visually distinct commit messages per file, use the helper script in this repo:
|
||||
<details>
|
||||
<summary>Show per-file emoji commit messages in GitHub's file UI</summary>
|
||||
|
||||
```bash
|
||||
# Apply emoji commits
|
||||
bash ./gitpretty-apply.sh .
|
||||
```
|
||||
|
||||
This will:
|
||||
|
||||
1. Clone `gitpretty` into `~/.gitpretty` (first run only)
|
||||
2. Make scripts executable
|
||||
3. Run `emoji-file-commits.sh` against this repo
|
||||
|
||||
Optional: install auto-emoji hooks for future commits:
|
||||
|
||||
```bash
|
||||
# Optional: install hooks for future commits
|
||||
bash ./gitpretty-apply.sh . --hooks
|
||||
```
|
||||
|
||||
After running, push as usual:
|
||||
|
||||
```bash
|
||||
# Push as usual
|
||||
git push origin main
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
## Use It in Claude Code (MCP Server)
|
||||
## Contributing
|
||||
|
||||
This repo includes an MCP server that lets you explore the Claude Code source directly from any Claude session. One command to set it up:
|
||||
Contributions to documentation, the MCP server, and exploration tooling are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
||||
|
||||
### Quick Start
|
||||
|
||||
```bash
|
||||
# Clone the repo (if you haven't already)
|
||||
git clone https://github.com/nirholas/claude-code.git
|
||||
cd claude-code/mcp-server
|
||||
|
||||
# Install dependencies and build
|
||||
npm install && npm run build
|
||||
|
||||
# Add to Claude Code (run from the repo root)
|
||||
claude mcp add claude-code-explorer -- node /absolute/path/to/claude-code/mcp-server/dist/index.js
|
||||
```
|
||||
|
||||
Replace `/absolute/path/to/claude-code` with the actual path where you cloned the repo.
|
||||
|
||||
**Or as a single copy-paste block** (clones, builds, and registers in one go):
|
||||
|
||||
```bash
|
||||
git clone https://github.com/nirholas/claude-code.git ~/claude-code \
|
||||
&& cd ~/claude-code/mcp-server \
|
||||
&& npm install && npm run build \
|
||||
&& claude mcp add claude-code-explorer -- node ~/claude-code/mcp-server/dist/index.js
|
||||
```
|
||||
|
||||
### What You Get
|
||||
|
||||
Once added, Claude has access to these tools for exploring the codebase:
|
||||
|
||||
| Tool | Description |
|
||||
|------|-------------|
|
||||
| `list_tools` | List all ~40 agent tools with source files |
|
||||
| `list_commands` | List all ~50 slash commands with source files |
|
||||
| `get_tool_source` | Read full source of any tool (e.g. `BashTool`, `FileEditTool`) |
|
||||
| `get_command_source` | Read source of any slash command (e.g. `review`, `mcp`) |
|
||||
| `read_source_file` | Read any file from `src/` by path |
|
||||
| `search_source` | Grep across the entire source tree |
|
||||
| `list_directory` | Browse `src/` directories |
|
||||
| `get_architecture` | High-level architecture overview |
|
||||
|
||||
Plus **prompts** for guided exploration:
|
||||
|
||||
- `explain_tool` — Deep-dive into how a specific tool works
|
||||
- `explain_command` — Understand a slash command's implementation
|
||||
- `architecture_overview` — Guided tour of the full architecture
|
||||
- `how_does_it_work` — Explain any subsystem (permissions, MCP, bridge, etc.)
|
||||
- `compare_tools` — Side-by-side comparison of two tools
|
||||
|
||||
### Example Usage
|
||||
|
||||
After adding the MCP server, just ask Claude naturally:
|
||||
|
||||
> "How does the BashTool work?"
|
||||
> "Search for where permissions are checked"
|
||||
> "Show me the /review command source"
|
||||
> "Explain the MCP client integration"
|
||||
|
||||
### Custom Source Path
|
||||
|
||||
If your `src/` directory is in a non-standard location, set the environment variable:
|
||||
|
||||
```bash
|
||||
claude mcp add claude-code-explorer -e CLAUDE_CODE_SRC_ROOT=/path/to/src -- node /path/to/mcp-server/dist/index.js
|
||||
```
|
||||
|
||||
### Remove It
|
||||
|
||||
```bash
|
||||
claude mcp remove claude-code-explorer
|
||||
```
|
||||
> **Note:** The `src/` directory is the original leaked source and should not be modified.
|
||||
|
||||
---
|
||||
|
||||
## Disclaimer
|
||||
|
||||
This repository archives source code that was leaked from Anthropic's npm registry on **2026-03-31**. All original source code is the property of [Anthropic](https://www.anthropic.com). Contact [nichxbt](https://www.x.com/nichxbt) for any comments.
|
||||
This repository archives source code leaked from Anthropic's npm registry on **2026-03-31**. All original source code is the property of [Anthropic](https://www.anthropic.com). This is not an official release and is not licensed for redistribution. Contact [nichxbt](https://www.x.com/nichxbt) for any comments.
|
||||
|
||||
|
||||
|
||||
224
docs/architecture.md
Normal file
224
docs/architecture.md
Normal file
@@ -0,0 +1,224 @@
|
||||
# Architecture
|
||||
|
||||
> Deep-dive into how Claude Code is structured internally.
|
||||
|
||||
---
|
||||
|
||||
## High-Level Overview
|
||||
|
||||
Claude Code is a terminal-native AI coding assistant built as a single-binary CLI. The architecture follows a pipeline model:
|
||||
|
||||
```
|
||||
User Input → CLI Parser → Query Engine → LLM API → Tool Execution Loop → Terminal UI
|
||||
```
|
||||
|
||||
The entire UI layer is built with **React + Ink** (React for the terminal), making it a fully reactive CLI application with components, hooks, state management, and all the patterns you'd expect in a React web app — just rendered to the terminal.
|
||||
|
||||
---
|
||||
|
||||
## Core Pipeline
|
||||
|
||||
### 1. Entrypoint (`src/main.tsx`)
|
||||
|
||||
The CLI parser is built with [Commander.js](https://github.com/tj/commander.js) (`@commander-js/extra-typings`). On startup, it:
|
||||
|
||||
- Fires parallel prefetch side-effects (MDM settings, Keychain, API preconnect) before heavy module imports
|
||||
- Parses CLI arguments and flags
|
||||
- Initializes the React/Ink renderer
|
||||
- Hands off to the REPL launcher (`src/replLauncher.tsx`)
|
||||
|
||||
### 2. Initialization (`src/entrypoints/`)
|
||||
|
||||
| File | Role |
|
||||
|------|------|
|
||||
| `cli.tsx` | CLI session orchestration — the main path from launch to REPL |
|
||||
| `init.ts` | Config, telemetry, OAuth, MDM policy initialization |
|
||||
| `mcp.ts` | MCP server mode entrypoint (Claude Code as an MCP server) |
|
||||
| `sdk/` | Agent SDK — programmatic API for embedding Claude Code |
|
||||
|
||||
Startup performs parallel initialization: MDM policy reads, Keychain prefetch, feature flag checks, then core init.
|
||||
|
||||
### 3. Query Engine (`src/QueryEngine.ts`, ~46K lines)
|
||||
|
||||
The heart of Claude Code. Handles:
|
||||
|
||||
- **Streaming responses** from the Anthropic API
|
||||
- **Tool-call loops** — when the LLM requests a tool, execute it and feed the result back
|
||||
- **Thinking mode** — extended thinking with budget management
|
||||
- **Retry logic** — automatic retries with backoff for transient failures
|
||||
- **Token counting** — tracks input/output tokens and cost per turn
|
||||
- **Context management** — manages conversation history and context windows
|
||||
|
||||
### 4. Tool System (`src/Tool.ts` + `src/tools/`)
|
||||
|
||||
Every capability Claude can invoke is a **tool**. Each tool is self-contained with:
|
||||
|
||||
- **Input schema** (Zod validation)
|
||||
- **Permission model** (what needs user approval)
|
||||
- **Execution logic** (the actual implementation)
|
||||
- **UI components** (how invocation/results render in the terminal)
|
||||
|
||||
Tools are registered in `src/tools.ts` and discovered by the Query Engine during tool-call loops.
|
||||
|
||||
See [Tools Reference](tools.md) for the complete catalog.
|
||||
|
||||
### 5. Command System (`src/commands.ts` + `src/commands/`)
|
||||
|
||||
User-facing slash commands (`/commit`, `/review`, `/mcp`, etc.) that can be typed in the REPL. Three types:
|
||||
|
||||
| Type | Description | Example |
|
||||
|------|-------------|---------|
|
||||
| **PromptCommand** | Sends a formatted prompt to the LLM with injected tools | `/review`, `/commit` |
|
||||
| **LocalCommand** | Runs in-process, returns plain text | `/cost`, `/version` |
|
||||
| **LocalJSXCommand** | Runs in-process, returns React JSX | `/doctor`, `/install` |
|
||||
|
||||
Commands are registered in `src/commands.ts` and invoked via `/command-name` in the REPL.
|
||||
|
||||
See [Commands Reference](commands.md) for the complete catalog.
|
||||
|
||||
---
|
||||
|
||||
## State Management
|
||||
|
||||
Claude Code uses a **React context + custom store** pattern:
|
||||
|
||||
| Component | Location | Purpose |
|
||||
|-----------|----------|---------|
|
||||
| `AppState` | `src/state/AppStateStore.ts` | Global mutable state object |
|
||||
| Context Providers | `src/context/` | React context for notifications, stats, FPS |
|
||||
| Selectors | `src/state/` | Derived state functions |
|
||||
| Change Observers | `src/state/onChangeAppState.ts` | Side-effects on state changes |
|
||||
|
||||
The `AppState` object is passed into tool contexts, giving tools access to conversation history, settings, and runtime state.
|
||||
|
||||
---
|
||||
|
||||
## UI Layer
|
||||
|
||||
### Components (`src/components/`, ~140 components)
|
||||
|
||||
- Functional React components using Ink primitives (`Box`, `Text`, `useInput()`)
|
||||
- Styled with [Chalk](https://github.com/chalk/chalk) for terminal colors
|
||||
- React Compiler enabled for optimized re-renders
|
||||
- Design system primitives in `src/components/design-system/`
|
||||
|
||||
### Screens (`src/screens/`)
|
||||
|
||||
Full-screen UI modes:
|
||||
|
||||
| Screen | Purpose |
|
||||
|--------|---------|
|
||||
| `REPL.tsx` | Main interactive REPL (the default screen) |
|
||||
| `Doctor.tsx` | Environment diagnostics (`/doctor`) |
|
||||
| `ResumeConversation.tsx` | Session restore (`/resume`) |
|
||||
|
||||
### Hooks (`src/hooks/`, ~80 hooks)
|
||||
|
||||
Standard React hooks pattern. Notable categories:
|
||||
|
||||
- **Permission hooks** — `useCanUseTool`, `src/hooks/toolPermission/`
|
||||
- **IDE integration** — `useIDEIntegration`, `useIdeConnectionStatus`, `useDiffInIDE`
|
||||
- **Input handling** — `useTextInput`, `useVimInput`, `usePasteHandler`, `useInputBuffer`
|
||||
- **Session management** — `useSessionBackgrounding`, `useRemoteSession`, `useAssistantHistory`
|
||||
- **Plugin/skill hooks** — `useManagePlugins`, `useSkillsChange`
|
||||
- **Notification hooks** — `src/hooks/notifs/` (rate limits, deprecation warnings, etc.)
|
||||
|
||||
---
|
||||
|
||||
## Configuration & Schemas
|
||||
|
||||
### Config Schemas (`src/schemas/`)
|
||||
|
||||
Zod v4-based schemas for all configuration:
|
||||
|
||||
- User settings
|
||||
- Project-level settings
|
||||
- Organization/enterprise policies
|
||||
- Permission rules
|
||||
|
||||
### Migrations (`src/migrations/`)
|
||||
|
||||
Handles config format changes between versions — reads old configs and transforms them to the current schema.
|
||||
|
||||
---
|
||||
|
||||
## Build System
|
||||
|
||||
### Bun Runtime
|
||||
|
||||
Claude Code runs on [Bun](https://bun.sh) (not Node.js). Key implications:
|
||||
|
||||
- Native JSX/TSX support without a transpilation step
|
||||
- `bun:bundle` feature flags for dead-code elimination
|
||||
- ES modules with `.js` extensions (Bun convention)
|
||||
|
||||
### Feature Flags (Dead Code Elimination)
|
||||
|
||||
```typescript
|
||||
import { feature } from 'bun:bundle'
|
||||
|
||||
// Code inside inactive feature flags is completely stripped at build time
|
||||
if (feature('VOICE_MODE')) {
|
||||
const voiceCommand = require('./commands/voice/index.js').default
|
||||
}
|
||||
```
|
||||
|
||||
Notable flags:
|
||||
|
||||
| Flag | Feature |
|
||||
|------|---------|
|
||||
| `PROACTIVE` | Proactive agent mode (autonomous actions) |
|
||||
| `KAIROS` | Kairos subsystem |
|
||||
| `BRIDGE_MODE` | IDE bridge integration |
|
||||
| `DAEMON` | Background daemon mode |
|
||||
| `VOICE_MODE` | Voice input/output |
|
||||
| `AGENT_TRIGGERS` | Triggered agent actions |
|
||||
| `MONITOR_TOOL` | Monitoring tool |
|
||||
| `COORDINATOR_MODE` | Multi-agent coordinator |
|
||||
| `WORKFLOW_SCRIPTS` | Workflow automation scripts |
|
||||
|
||||
### Lazy Loading
|
||||
|
||||
Heavy modules are deferred via dynamic `import()` until first use:
|
||||
|
||||
- OpenTelemetry (~400KB)
|
||||
- gRPC (~700KB)
|
||||
- Other optional dependencies
|
||||
|
||||
---
|
||||
|
||||
## Error Handling & Telemetry
|
||||
|
||||
### Telemetry (`src/services/analytics/`)
|
||||
|
||||
- [GrowthBook](https://www.growthbook.io/) for feature flags and A/B testing
|
||||
- [OpenTelemetry](https://opentelemetry.io/) for distributed tracing and metrics
|
||||
- Custom event tracking for usage analytics
|
||||
|
||||
### Cost Tracking (`src/cost-tracker.ts`)
|
||||
|
||||
Tracks token usage and estimated cost per conversation turn. Accessible via the `/cost` command.
|
||||
|
||||
### Diagnostics (`/doctor` command)
|
||||
|
||||
The `Doctor.tsx` screen runs environment checks: API connectivity, authentication, tool availability, MCP server status, and more.
|
||||
|
||||
---
|
||||
|
||||
## Concurrency Model
|
||||
|
||||
Claude Code uses a **single-threaded event loop** (Bun/Node.js model) with:
|
||||
|
||||
- Async/await for I/O operations
|
||||
- React's concurrent rendering for UI updates
|
||||
- Web Workers or child processes for CPU-intensive tasks (gRPC, etc.)
|
||||
- Tool concurrency safety — each tool declares `isConcurrencySafe()` to indicate if it can run in parallel with other tools
|
||||
|
||||
---
|
||||
|
||||
## See Also
|
||||
|
||||
- [Tools Reference](tools.md) — Complete catalog of all 40 agent tools
|
||||
- [Commands Reference](commands.md) — Complete catalog of all slash commands
|
||||
- [Subsystems Guide](subsystems.md) — Bridge, MCP, permissions, skills, plugins, and more
|
||||
- [Exploration Guide](exploration-guide.md) — How to navigate this codebase
|
||||
211
docs/commands.md
Normal file
211
docs/commands.md
Normal file
@@ -0,0 +1,211 @@
|
||||
# Commands Reference
|
||||
|
||||
> Complete catalog of all slash commands in Claude Code.
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Commands are user-facing actions invoked with a `/` prefix in the REPL (e.g., `/commit`, `/review`). They live in `src/commands/` and are registered in `src/commands.ts`.
|
||||
|
||||
### Command Types
|
||||
|
||||
| Type | Description | Example |
|
||||
|------|-------------|---------|
|
||||
| **PromptCommand** | Sends a formatted prompt to the LLM with injected tools | `/review`, `/commit` |
|
||||
| **LocalCommand** | Runs in-process, returns plain text | `/cost`, `/version` |
|
||||
| **LocalJSXCommand** | Runs in-process, returns React JSX | `/install`, `/doctor` |
|
||||
|
||||
### Command Definition Pattern
|
||||
|
||||
```typescript
|
||||
const command = {
|
||||
type: 'prompt',
|
||||
name: 'my-command',
|
||||
description: 'What this command does',
|
||||
progressMessage: 'working...',
|
||||
allowedTools: ['Bash(git *)', 'FileRead(*)'],
|
||||
source: 'builtin',
|
||||
async getPromptForCommand(args, context) {
|
||||
return [{ type: 'text', text: '...' }]
|
||||
},
|
||||
} satisfies Command
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Git & Version Control
|
||||
|
||||
| Command | Source | Description |
|
||||
|---------|--------|-------------|
|
||||
| `/commit` | `commit.ts` | Create a git commit with an AI-generated message |
|
||||
| `/commit-push-pr` | `commit-push-pr.ts` | Commit, push, and create a PR in one step |
|
||||
| `/branch` | `branch/` | Create or switch git branches |
|
||||
| `/diff` | `diff/` | View file changes (staged, unstaged, or against a ref) |
|
||||
| `/pr_comments` | `pr_comments/` | View and address PR review comments |
|
||||
| `/rewind` | `rewind/` | Revert to a previous state |
|
||||
|
||||
## Code Quality
|
||||
|
||||
| Command | Source | Description |
|
||||
|---------|--------|-------------|
|
||||
| `/review` | `review.ts` | AI-powered code review of staged/unstaged changes |
|
||||
| `/security-review` | `security-review.ts` | Security-focused code review |
|
||||
| `/advisor` | `advisor.ts` | Get architectural or design advice |
|
||||
| `/bughunter` | `bughunter/` | Find potential bugs in the codebase |
|
||||
|
||||
## Session & Context
|
||||
|
||||
| Command | Source | Description |
|
||||
|---------|--------|-------------|
|
||||
| `/compact` | `compact/` | Compress conversation context to fit more history |
|
||||
| `/context` | `context/` | Visualize current context (files, memory, etc.) |
|
||||
| `/resume` | `resume/` | Restore a previous conversation session |
|
||||
| `/session` | `session/` | Manage sessions (list, switch, delete) |
|
||||
| `/share` | `share/` | Share a session via link |
|
||||
| `/export` | `export/` | Export conversation to a file |
|
||||
| `/summary` | `summary/` | Generate a summary of the current session |
|
||||
| `/clear` | `clear/` | Clear the conversation history |
|
||||
|
||||
## Configuration & Settings
|
||||
|
||||
| Command | Source | Description |
|
||||
|---------|--------|-------------|
|
||||
| `/config` | `config/` | View or modify Claude Code settings |
|
||||
| `/permissions` | `permissions/` | Manage tool permission rules |
|
||||
| `/theme` | `theme/` | Change the terminal color theme |
|
||||
| `/output-style` | `output-style/` | Change output formatting style |
|
||||
| `/color` | `color/` | Toggle color output |
|
||||
| `/keybindings` | `keybindings/` | View or customize keybindings |
|
||||
| `/vim` | `vim/` | Toggle vim mode for input |
|
||||
| `/effort` | `effort/` | Adjust response effort level |
|
||||
| `/model` | `model/` | Switch the active model |
|
||||
| `/privacy-settings` | `privacy-settings/` | Manage privacy/data settings |
|
||||
| `/fast` | `fast/` | Toggle fast mode (shorter responses) |
|
||||
| `/brief` | `brief.ts` | Toggle brief output mode |
|
||||
|
||||
## Memory & Knowledge
|
||||
|
||||
| Command | Source | Description |
|
||||
|---------|--------|-------------|
|
||||
| `/memory` | `memory/` | Manage persistent memory (CLAUDE.md files) |
|
||||
| `/add-dir` | `add-dir/` | Add a directory to the project context |
|
||||
| `/files` | `files/` | List files in the current context |
|
||||
|
||||
## MCP & Plugins
|
||||
|
||||
| Command | Source | Description |
|
||||
|---------|--------|-------------|
|
||||
| `/mcp` | `mcp/` | Manage MCP server connections |
|
||||
| `/plugin` | `plugin/` | Install, remove, or manage plugins |
|
||||
| `/reload-plugins` | `reload-plugins/` | Reload all installed plugins |
|
||||
| `/skills` | `skills/` | View and manage skills |
|
||||
|
||||
## Authentication
|
||||
|
||||
| Command | Source | Description |
|
||||
|---------|--------|-------------|
|
||||
| `/login` | `login/` | Authenticate with Anthropic |
|
||||
| `/logout` | `logout/` | Sign out |
|
||||
| `/oauth-refresh` | `oauth-refresh/` | Refresh OAuth tokens |
|
||||
|
||||
## Tasks & Agents
|
||||
|
||||
| Command | Source | Description |
|
||||
|---------|--------|-------------|
|
||||
| `/tasks` | `tasks/` | Manage background tasks |
|
||||
| `/agents` | `agents/` | Manage sub-agents |
|
||||
| `/ultraplan` | `ultraplan.tsx` | Generate a detailed execution plan |
|
||||
| `/plan` | `plan/` | Enter planning mode |
|
||||
|
||||
## Diagnostics & Status
|
||||
|
||||
| Command | Source | Description |
|
||||
|---------|--------|-------------|
|
||||
| `/doctor` | `doctor/` | Run environment diagnostics |
|
||||
| `/status` | `status/` | Show system and session status |
|
||||
| `/stats` | `stats/` | Show session statistics |
|
||||
| `/cost` | `cost/` | Display token usage and estimated cost |
|
||||
| `/version` | `version.ts` | Show Claude Code version |
|
||||
| `/usage` | `usage/` | Show detailed API usage |
|
||||
| `/extra-usage` | `extra-usage/` | Show extended usage details |
|
||||
| `/rate-limit-options` | `rate-limit-options/` | View rate limit configuration |
|
||||
|
||||
## Installation & Setup
|
||||
|
||||
| Command | Source | Description |
|
||||
|---------|--------|-------------|
|
||||
| `/install` | `install.tsx` | Install or update Claude Code |
|
||||
| `/upgrade` | `upgrade/` | Upgrade to the latest version |
|
||||
| `/init` | `init.ts` | Initialize a project (create CLAUDE.md) |
|
||||
| `/init-verifiers` | `init-verifiers.ts` | Set up verifier hooks |
|
||||
| `/onboarding` | `onboarding/` | Run the first-time setup wizard |
|
||||
| `/terminalSetup` | `terminalSetup/` | Configure terminal integration |
|
||||
|
||||
## IDE & Desktop Integration
|
||||
|
||||
| Command | Source | Description |
|
||||
|---------|--------|-------------|
|
||||
| `/bridge` | `bridge/` | Manage IDE bridge connections |
|
||||
| `/bridge-kick` | `bridge-kick.ts` | Force-restart the IDE bridge |
|
||||
| `/ide` | `ide/` | Open in IDE |
|
||||
| `/desktop` | `desktop/` | Hand off to the desktop app |
|
||||
| `/mobile` | `mobile/` | Hand off to the mobile app |
|
||||
| `/teleport` | `teleport/` | Transfer session to another device |
|
||||
|
||||
## Remote & Environment
|
||||
|
||||
| Command | Source | Description |
|
||||
|---------|--------|-------------|
|
||||
| `/remote-env` | `remote-env/` | Configure remote environment |
|
||||
| `/remote-setup` | `remote-setup/` | Set up remote session |
|
||||
| `/env` | `env/` | View environment variables |
|
||||
| `/sandbox-toggle` | `sandbox-toggle/` | Toggle sandbox mode |
|
||||
|
||||
## Misc
|
||||
|
||||
| Command | Source | Description |
|
||||
|---------|--------|-------------|
|
||||
| `/help` | `help/` | Show help and available commands |
|
||||
| `/exit` | `exit/` | Exit Claude Code |
|
||||
| `/copy` | `copy/` | Copy content to clipboard |
|
||||
| `/feedback` | `feedback/` | Send feedback to Anthropic |
|
||||
| `/release-notes` | `release-notes/` | View release notes |
|
||||
| `/rename` | `rename/` | Rename the current session |
|
||||
| `/tag` | `tag/` | Tag the current session |
|
||||
| `/insights` | `insights.ts` | Show codebase insights |
|
||||
| `/stickers` | `stickers/` | Easter egg — stickers |
|
||||
| `/good-claude` | `good-claude/` | Easter egg — praise Claude |
|
||||
| `/voice` | `voice/` | Toggle voice input mode |
|
||||
| `/chrome` | `chrome/` | Chrome extension integration |
|
||||
| `/issue` | `issue/` | File a GitHub issue |
|
||||
| `/statusline` | `statusline.tsx` | Customize the status line |
|
||||
| `/thinkback` | `thinkback/` | Replay Claude's thinking process |
|
||||
| `/thinkback-play` | `thinkback-play/` | Animated thinking replay |
|
||||
| `/passes` | `passes/` | Multi-pass execution |
|
||||
| `/x402` | `x402/` | x402 payment protocol integration |
|
||||
|
||||
## Internal / Debug Commands
|
||||
|
||||
| Command | Source | Description |
|
||||
|---------|--------|-------------|
|
||||
| `/ant-trace` | `ant-trace/` | Anthropic-internal tracing |
|
||||
| `/autofix-pr` | `autofix-pr/` | Auto-fix PR issues |
|
||||
| `/backfill-sessions` | `backfill-sessions/` | Backfill session data |
|
||||
| `/break-cache` | `break-cache/` | Invalidate caches |
|
||||
| `/btw` | `btw/` | "By the way" interjection |
|
||||
| `/ctx_viz` | `ctx_viz/` | Context visualization (debug) |
|
||||
| `/debug-tool-call` | `debug-tool-call/` | Debug a specific tool call |
|
||||
| `/heapdump` | `heapdump/` | Dump heap for memory analysis |
|
||||
| `/hooks` | `hooks/` | Manage hook scripts |
|
||||
| `/mock-limits` | `mock-limits/` | Mock rate limits for testing |
|
||||
| `/perf-issue` | `perf-issue/` | Report performance issues |
|
||||
| `/reset-limits` | `reset-limits/` | Reset rate limit counters |
|
||||
|
||||
---
|
||||
|
||||
## See Also
|
||||
|
||||
- [Architecture](architecture.md) — How the command system fits into the pipeline
|
||||
- [Tools Reference](tools.md) — Agent tools (different from slash commands)
|
||||
- [Exploration Guide](exploration-guide.md) — Finding command source code
|
||||
246
docs/exploration-guide.md
Normal file
246
docs/exploration-guide.md
Normal file
@@ -0,0 +1,246 @@
|
||||
# Exploration Guide
|
||||
|
||||
> How to navigate and study the Claude Code source code.
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
|
||||
This is a **read-only reference codebase** — there's no build system or test suite. The goal is to understand how a production AI coding assistant is built.
|
||||
|
||||
### Orientation
|
||||
|
||||
| What | Where |
|
||||
|------|-------|
|
||||
| CLI entrypoint | `src/main.tsx` |
|
||||
| Core LLM engine | `src/QueryEngine.ts` (~46K lines) |
|
||||
| Tool definitions | `src/Tool.ts` (~29K lines) |
|
||||
| Command registry | `src/commands.ts` (~25K lines) |
|
||||
| Tool registry | `src/tools.ts` |
|
||||
| Context collection | `src/context.ts` |
|
||||
| All tool implementations | `src/tools/` (40 subdirectories) |
|
||||
| All command implementations | `src/commands/` (~85 subdirectories + 15 files) |
|
||||
|
||||
---
|
||||
|
||||
## Finding Things
|
||||
|
||||
### "How does tool X work?"
|
||||
|
||||
1. Go to `src/tools/{ToolName}/`
|
||||
2. Main implementation is `{ToolName}.ts` or `.tsx`
|
||||
3. UI rendering is in `UI.tsx`
|
||||
4. System prompt contribution is in `prompt.ts`
|
||||
|
||||
Example — understanding BashTool:
|
||||
```
|
||||
src/tools/BashTool/
|
||||
├── BashTool.ts ← Core execution logic
|
||||
├── UI.tsx ← How bash output renders in terminal
|
||||
├── prompt.ts ← What the system prompt says about bash
|
||||
└── ...
|
||||
```
|
||||
|
||||
### "How does command X work?"
|
||||
|
||||
1. Check `src/commands/{command-name}/` (directory) or `src/commands/{command-name}.ts` (file)
|
||||
2. Look for the `getPromptForCommand()` function (PromptCommands) or direct implementation (LocalCommands)
|
||||
|
||||
### "How does feature X work?"
|
||||
|
||||
| Feature | Start Here |
|
||||
|---------|-----------|
|
||||
| Permissions | `src/hooks/toolPermission/` |
|
||||
| IDE bridge | `src/bridge/bridgeMain.ts` |
|
||||
| MCP client | `src/services/mcp/` |
|
||||
| Plugin system | `src/plugins/` + `src/services/plugins/` |
|
||||
| Skills | `src/skills/` |
|
||||
| Voice input | `src/voice/` + `src/services/voice.ts` |
|
||||
| Multi-agent | `src/coordinator/` |
|
||||
| Memory | `src/memdir/` |
|
||||
| Authentication | `src/services/oauth/` |
|
||||
| Config schemas | `src/schemas/` |
|
||||
| State management | `src/state/` |
|
||||
|
||||
### "How does an API call flow?"
|
||||
|
||||
Trace from user input to API response:
|
||||
|
||||
```
|
||||
src/main.tsx ← CLI parsing
|
||||
→ src/replLauncher.tsx ← REPL session start
|
||||
→ src/QueryEngine.ts ← Core engine
|
||||
→ src/services/api/ ← Anthropic SDK client
|
||||
→ (Anthropic API) ← HTTP/streaming
|
||||
← Tool use response
|
||||
→ src/tools/{ToolName}/ ← Tool execution
|
||||
← Tool result
|
||||
→ (feed back to API) ← Continue the loop
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Code Patterns to Recognize
|
||||
|
||||
### `buildTool()` — Tool Factory
|
||||
|
||||
Every tool uses this pattern:
|
||||
|
||||
```typescript
|
||||
export const MyTool = buildTool({
|
||||
name: 'MyTool',
|
||||
inputSchema: z.object({ ... }),
|
||||
async call(args, context) { ... },
|
||||
async checkPermissions(input, context) { ... },
|
||||
})
|
||||
```
|
||||
|
||||
### Feature Flag Gates
|
||||
|
||||
```typescript
|
||||
import { feature } from 'bun:bundle'
|
||||
|
||||
if (feature('VOICE_MODE')) {
|
||||
// This code is stripped at build time if VOICE_MODE is off
|
||||
}
|
||||
```
|
||||
|
||||
### Anthropic-Internal Gates
|
||||
|
||||
```typescript
|
||||
if (process.env.USER_TYPE === 'ant') {
|
||||
// Anthropic employee-only features
|
||||
}
|
||||
```
|
||||
|
||||
### Index Re-exports
|
||||
|
||||
Most directories have an `index.ts` that re-exports the public API:
|
||||
|
||||
```typescript
|
||||
// src/tools/BashTool/index.ts
|
||||
export { BashTool } from './BashTool.js'
|
||||
```
|
||||
|
||||
### Lazy Dynamic Imports
|
||||
|
||||
Heavy modules are loaded only when needed:
|
||||
|
||||
```typescript
|
||||
const { OpenTelemetry } = await import('./heavy-module.js')
|
||||
```
|
||||
|
||||
### ESM with `.js` Extensions
|
||||
|
||||
Bun convention — all imports use `.js` extensions even for `.ts` files:
|
||||
|
||||
```typescript
|
||||
import { something } from './utils.js' // Actually imports utils.ts
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Key Files by Size
|
||||
|
||||
The largest files contain the most logic and are worth studying:
|
||||
|
||||
| File | Lines | What's Inside |
|
||||
|------|-------|---------------|
|
||||
| `QueryEngine.ts` | ~46K | Streaming, tool loops, retries, token counting |
|
||||
| `Tool.ts` | ~29K | Tool types, `buildTool`, permission models |
|
||||
| `commands.ts` | ~25K | Command registry, conditional loading |
|
||||
| `main.tsx` | — | CLI parser, startup optimization |
|
||||
| `context.ts` | — | OS, shell, git, user context assembly |
|
||||
|
||||
---
|
||||
|
||||
## Study Paths
|
||||
|
||||
### Path 1: "How does a tool work end-to-end?"
|
||||
|
||||
1. Read `src/Tool.ts` — understand the `buildTool` interface
|
||||
2. Pick a simple tool like `FileReadTool` in `src/tools/FileReadTool/`
|
||||
3. Trace how `QueryEngine.ts` calls tools during the tool loop
|
||||
4. See how permissions are checked in `src/hooks/toolPermission/`
|
||||
|
||||
### Path 2: "How does the UI work?"
|
||||
|
||||
1. Read `src/screens/REPL.tsx` — the main screen
|
||||
2. Explore `src/components/` — pick a few components
|
||||
3. See `src/hooks/useTextInput.ts` — how user input is captured
|
||||
4. Check `src/ink/` — the Ink renderer wrapper
|
||||
|
||||
### Path 3: "How does the IDE integration work?"
|
||||
|
||||
1. Start at `src/bridge/bridgeMain.ts`
|
||||
2. Follow `bridgeMessaging.ts` for the message protocol
|
||||
3. See `bridgePermissionCallbacks.ts` for how permissions route to the IDE
|
||||
4. Check `replBridge.ts` for REPL session bridging
|
||||
|
||||
### Path 4: "How do plugins extend Claude Code?"
|
||||
|
||||
1. Read `src/types/plugin.ts` — the plugin API surface
|
||||
2. See `src/services/plugins/` — how plugins are loaded
|
||||
3. Check `src/plugins/builtinPlugins.ts` — built-in examples
|
||||
4. Look at `src/plugins/bundled/` — bundled plugin code
|
||||
|
||||
### Path 5: "How does MCP work?"
|
||||
|
||||
1. Read `src/services/mcp/` — the MCP client
|
||||
2. See `src/tools/MCPTool/` — how MCP tools are invoked
|
||||
3. Check `src/entrypoints/mcp.ts` — Claude Code as an MCP server
|
||||
4. Look at `src/skills/mcpSkillBuilders.ts` — skills from MCP
|
||||
|
||||
---
|
||||
|
||||
## Using the MCP Server for Exploration
|
||||
|
||||
This repo includes a standalone MCP server (`mcp-server/`) that lets any MCP-compatible client explore the source code. See the [MCP Server README](../mcp-server/README.md) for setup.
|
||||
|
||||
Once connected, you can ask an AI assistant to explore the source:
|
||||
|
||||
- "How does the BashTool work?"
|
||||
- "Search for where permissions are checked"
|
||||
- "List all files in the bridge directory"
|
||||
- "Read QueryEngine.ts lines 1-100"
|
||||
|
||||
---
|
||||
|
||||
## Grep Patterns
|
||||
|
||||
Useful grep/ripgrep patterns for finding things:
|
||||
|
||||
```bash
|
||||
# Find all tool definitions
|
||||
rg "buildTool\(" src/tools/
|
||||
|
||||
# Find all command definitions
|
||||
rg "satisfies Command" src/commands/
|
||||
|
||||
# Find feature flag usage
|
||||
rg "feature\(" src/
|
||||
|
||||
# Find Anthropic-internal gates
|
||||
rg "USER_TYPE.*ant" src/
|
||||
|
||||
# Find all React hooks
|
||||
rg "^export function use" src/hooks/
|
||||
|
||||
# Find all Zod schemas
|
||||
rg "z\.object\(" src/schemas/
|
||||
|
||||
# Find all system prompt contributions
|
||||
rg "prompt\(" src/tools/*/prompt.ts
|
||||
|
||||
# Find permission rule patterns
|
||||
rg "checkPermissions" src/tools/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## See Also
|
||||
|
||||
- [Architecture](architecture.md) — Overall system design
|
||||
- [Tools Reference](tools.md) — Complete tool catalog
|
||||
- [Commands Reference](commands.md) — All slash commands
|
||||
- [Subsystems Guide](subsystems.md) — Deep dives into Bridge, MCP, Permissions, etc.
|
||||
346
docs/subsystems.md
Normal file
346
docs/subsystems.md
Normal file
@@ -0,0 +1,346 @@
|
||||
# Subsystems Guide
|
||||
|
||||
> Detailed documentation of Claude Code's major subsystems.
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Bridge (IDE Integration)](#bridge-ide-integration)
|
||||
- [MCP (Model Context Protocol)](#mcp-model-context-protocol)
|
||||
- [Permission System](#permission-system)
|
||||
- [Plugin System](#plugin-system)
|
||||
- [Skill System](#skill-system)
|
||||
- [Task System](#task-system)
|
||||
- [Memory System](#memory-system)
|
||||
- [Coordinator (Multi-Agent)](#coordinator-multi-agent)
|
||||
- [Voice System](#voice-system)
|
||||
- [Service Layer](#service-layer)
|
||||
|
||||
---
|
||||
|
||||
## Bridge (IDE Integration)
|
||||
|
||||
**Location:** `src/bridge/`
|
||||
|
||||
The bridge is a bidirectional communication layer connecting Claude Code's CLI with IDE extensions (VS Code, JetBrains). It allows the CLI to run as a backend for IDE-based interfaces.
|
||||
|
||||
### Architecture
|
||||
|
||||
```
|
||||
┌──────────────────┐ ┌──────────────────────┐
|
||||
│ IDE Extension │◄───────►│ Bridge Layer │
|
||||
│ (VS Code, JB) │ JWT │ (src/bridge/) │
|
||||
│ │ Auth │ │
|
||||
│ - UI rendering │ │ - Session mgmt │
|
||||
│ - File watching │ │ - Message routing │
|
||||
│ - Diff display │ │ - Permission proxy │
|
||||
└──────────────────┘ └──────────┬───────────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────────────┐
|
||||
│ Claude Code Core │
|
||||
│ (QueryEngine, Tools) │
|
||||
└──────────────────────┘
|
||||
```
|
||||
|
||||
### Key Files
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `bridgeMain.ts` | Main bridge loop — starts the bidirectional channel |
|
||||
| `bridgeMessaging.ts` | Message protocol (serialize/deserialize) |
|
||||
| `bridgePermissionCallbacks.ts` | Routes permission prompts to the IDE |
|
||||
| `bridgeApi.ts` | API surface exposed to the IDE |
|
||||
| `bridgeConfig.ts` | Bridge configuration |
|
||||
| `replBridge.ts` | Connects the REPL session to the bridge |
|
||||
| `jwtUtils.ts` | JWT-based authentication between CLI and IDE |
|
||||
| `sessionRunner.ts` | Manages bridge session execution |
|
||||
| `createSession.ts` | Creates new bridge sessions |
|
||||
| `trustedDevice.ts` | Device trust verification |
|
||||
| `workSecret.ts` | Workspace-scoped secrets |
|
||||
| `inboundMessages.ts` | Handles messages coming from the IDE |
|
||||
| `inboundAttachments.ts` | Handles file attachments from the IDE |
|
||||
| `types.ts` | TypeScript types for the bridge protocol |
|
||||
|
||||
### Feature Flag
|
||||
|
||||
The bridge is gated behind the `BRIDGE_MODE` feature flag and is stripped from non-IDE builds.
|
||||
|
||||
---
|
||||
|
||||
## MCP (Model Context Protocol)
|
||||
|
||||
**Location:** `src/services/mcp/`
|
||||
|
||||
Claude Code acts as both an **MCP client** (consuming tools/resources from MCP servers) and can run as an **MCP server** (exposing its own tools via `src/entrypoints/mcp.ts`).
|
||||
|
||||
### Client Features
|
||||
|
||||
- **Tool discovery** — Enumerates tools from connected MCP servers
|
||||
- **Resource browsing** — Lists and reads MCP-exposed resources
|
||||
- **Dynamic tool loading** — `ToolSearchTool` discovers tools at runtime
|
||||
- **Authentication** — `McpAuthTool` handles MCP server auth flows
|
||||
- **Connectivity monitoring** — `useMcpConnectivityStatus` hook tracks connection health
|
||||
|
||||
### Server Mode
|
||||
|
||||
When launched via `src/entrypoints/mcp.ts`, Claude Code exposes its own tools and resources via the MCP protocol, allowing other AI agents to use Claude Code as a tool server.
|
||||
|
||||
### Related Tools
|
||||
|
||||
| Tool | Purpose |
|
||||
|------|---------|
|
||||
| `MCPTool` | Invoke tools on connected MCP servers |
|
||||
| `ListMcpResourcesTool` | List available MCP resources |
|
||||
| `ReadMcpResourceTool` | Read a specific MCP resource |
|
||||
| `McpAuthTool` | Authenticate with an MCP server |
|
||||
| `ToolSearchTool` | Discover deferred tools from MCP servers |
|
||||
|
||||
### Configuration
|
||||
|
||||
MCP servers are configured via `/mcp` command or settings files. The server approval flow lives in `src/services/mcpServerApproval.tsx`.
|
||||
|
||||
---
|
||||
|
||||
## Permission System
|
||||
|
||||
**Location:** `src/hooks/toolPermission/`
|
||||
|
||||
Every tool invocation passes through a centralized permission check before execution.
|
||||
|
||||
### Permission Modes
|
||||
|
||||
| Mode | Behavior |
|
||||
|------|----------|
|
||||
| `default` | Prompts the user for each potentially destructive operation |
|
||||
| `plan` | Shows the full execution plan, asks once for batch approval |
|
||||
| `bypassPermissions` | Auto-approves all operations (dangerous — for trusted environments) |
|
||||
| `auto` | ML-based classifier automatically decides (experimental) |
|
||||
|
||||
### How It Works
|
||||
|
||||
1. Tool is invoked by the Query Engine
|
||||
2. `checkPermissions(input, context)` is called on the tool
|
||||
3. Permission handler checks against configured rules
|
||||
4. If not auto-approved, user is prompted via terminal or IDE
|
||||
|
||||
### Permission Rules
|
||||
|
||||
Rules use wildcard patterns to match tool invocations:
|
||||
|
||||
```
|
||||
Bash(git *) # Allow all git commands without prompt
|
||||
Bash(npm test) # Allow 'npm test' specifically
|
||||
FileEdit(/src/*) # Allow edits to anything under src/
|
||||
FileRead(*) # Allow reading any file
|
||||
```
|
||||
|
||||
### Key Files
|
||||
|
||||
| File | Path |
|
||||
|------|------|
|
||||
| Permission context | `src/hooks/toolPermission/PermissionContext.ts` |
|
||||
| Permission handlers | `src/hooks/toolPermission/handlers/` |
|
||||
| Permission logging | `src/hooks/toolPermission/permissionLogging.ts` |
|
||||
| Permission types | `src/types/permissions.ts` |
|
||||
|
||||
---
|
||||
|
||||
## Plugin System
|
||||
|
||||
**Location:** `src/plugins/`, `src/services/plugins/`
|
||||
|
||||
Claude Code supports installable plugins that can extend its capabilities.
|
||||
|
||||
### Structure
|
||||
|
||||
| Component | Location | Purpose |
|
||||
|-----------|----------|---------|
|
||||
| Plugin loader | `src/services/plugins/` | Discovers and loads plugins |
|
||||
| Built-in plugins | `src/plugins/builtinPlugins.ts` | Plugins that ship with Claude Code |
|
||||
| Bundled plugins | `src/plugins/bundled/` | Plugin code bundled into the binary |
|
||||
| Plugin types | `src/types/plugin.ts` | TypeScript types for plugin API |
|
||||
|
||||
### Plugin Lifecycle
|
||||
|
||||
1. **Discovery** — Scans plugin directories and marketplace
|
||||
2. **Installation** — Downloaded and registered (`/plugin` command)
|
||||
3. **Loading** — Initialized at startup or on-demand
|
||||
4. **Execution** — Plugins can contribute tools, commands, and prompts
|
||||
5. **Auto-update** — `usePluginAutoupdateNotification` handles updates
|
||||
|
||||
### Related Commands
|
||||
|
||||
| Command | Purpose |
|
||||
|---------|---------|
|
||||
| `/plugin` | Install, remove, or manage plugins |
|
||||
| `/reload-plugins` | Reload all installed plugins |
|
||||
|
||||
---
|
||||
|
||||
## Skill System
|
||||
|
||||
**Location:** `src/skills/`
|
||||
|
||||
Skills are reusable, named workflows that bundle prompts and tool configurations for specific tasks.
|
||||
|
||||
### Structure
|
||||
|
||||
| Component | Location | Purpose |
|
||||
|-----------|----------|---------|
|
||||
| Bundled skills | `src/skills/bundled/` | Skills that ship with Claude Code |
|
||||
| Skill loader | `src/skills/loadSkillsDir.ts` | Loads skills from disk |
|
||||
| MCP skill builders | `src/skills/mcpSkillBuilders.ts` | Creates skills from MCP resources |
|
||||
| Skill registry | `src/skills/bundledSkills.ts` | Registration of all bundled skills |
|
||||
|
||||
### Bundled Skills (16)
|
||||
|
||||
| Skill | Purpose |
|
||||
|-------|---------|
|
||||
| `batch` | Batch operations across multiple files |
|
||||
| `claudeApi` | Direct Anthropic API interaction |
|
||||
| `claudeInChrome` | Chrome extension integration |
|
||||
| `debug` | Debugging workflows |
|
||||
| `keybindings` | Keybinding configuration |
|
||||
| `loop` | Iterative refinement loops |
|
||||
| `loremIpsum` | Generate placeholder text |
|
||||
| `remember` | Persist information to memory |
|
||||
| `scheduleRemoteAgents` | Schedule agents for remote execution |
|
||||
| `simplify` | Simplify complex code |
|
||||
| `skillify` | Create new skills from workflows |
|
||||
| `stuck` | Get unstuck when blocked |
|
||||
| `updateConfig` | Modify configuration programmatically |
|
||||
| `verify` / `verifyContent` | Verify code correctness |
|
||||
|
||||
### Execution
|
||||
|
||||
Skills are invoked via the `SkillTool` or the `/skills` command. Users can also create custom skills.
|
||||
|
||||
---
|
||||
|
||||
## Task System
|
||||
|
||||
**Location:** `src/tasks/`
|
||||
|
||||
Manages background and parallel work items — shell tasks, agent tasks, and teammate agents.
|
||||
|
||||
### Task Types
|
||||
|
||||
| Type | Location | Purpose |
|
||||
|------|----------|---------|
|
||||
| `LocalShellTask` | `LocalShellTask/` | Background shell command execution |
|
||||
| `LocalAgentTask` | `LocalAgentTask/` | Sub-agent running locally |
|
||||
| `RemoteAgentTask` | `RemoteAgentTask/` | Agent running on a remote machine |
|
||||
| `InProcessTeammateTask` | `InProcessTeammateTask/` | Parallel teammate agent |
|
||||
| `DreamTask` | `DreamTask/` | Background "dreaming" process |
|
||||
| `LocalMainSessionTask` | `LocalMainSessionTask.ts` | Main session as a task |
|
||||
|
||||
### Task Tools
|
||||
|
||||
| Tool | Purpose |
|
||||
|------|---------|
|
||||
| `TaskCreateTool` | Create a new background task |
|
||||
| `TaskUpdateTool` | Update task status |
|
||||
| `TaskGetTool` | Retrieve task details |
|
||||
| `TaskListTool` | List all tasks |
|
||||
| `TaskOutputTool` | Get task output |
|
||||
| `TaskStopTool` | Stop a running task |
|
||||
|
||||
---
|
||||
|
||||
## Memory System
|
||||
|
||||
**Location:** `src/memdir/`
|
||||
|
||||
Claude Code's persistent memory system, based on `CLAUDE.md` files.
|
||||
|
||||
### Memory Hierarchy
|
||||
|
||||
| Scope | Location | Purpose |
|
||||
|-------|----------|---------|
|
||||
| Project memory | `CLAUDE.md` in project root | Project-specific facts, conventions |
|
||||
| User memory | `~/.claude/CLAUDE.md` | User preferences, cross-project |
|
||||
| Extracted memories | `src/services/extractMemories/` | Auto-extracted from conversations |
|
||||
| Team memory sync | `src/services/teamMemorySync/` | Shared team knowledge |
|
||||
|
||||
### Related
|
||||
|
||||
- `/memory` command for managing memories
|
||||
- `remember` skill for persisting information
|
||||
- `useMemoryUsage` hook for tracking memory size
|
||||
|
||||
---
|
||||
|
||||
## Coordinator (Multi-Agent)
|
||||
|
||||
**Location:** `src/coordinator/`
|
||||
|
||||
Orchestrates multiple agents working in parallel on different aspects of a task.
|
||||
|
||||
### How It Works
|
||||
|
||||
- `coordinatorMode.ts` manages the coordinator lifecycle
|
||||
- `TeamCreateTool` and `TeamDeleteTool` manage agent teams
|
||||
- `SendMessageTool` enables inter-agent communication
|
||||
- `AgentTool` spawns sub-agents
|
||||
|
||||
Gated behind the `COORDINATOR_MODE` feature flag.
|
||||
|
||||
---
|
||||
|
||||
## Voice System
|
||||
|
||||
**Location:** `src/voice/`
|
||||
|
||||
Voice input/output support for hands-free interaction.
|
||||
|
||||
### Components
|
||||
|
||||
| File | Location | Purpose |
|
||||
|------|----------|---------|
|
||||
| Voice service | `src/services/voice.ts` | Core voice processing |
|
||||
| STT streaming | `src/services/voiceStreamSTT.ts` | Speech-to-text streaming |
|
||||
| Key terms | `src/services/voiceKeyterms.ts` | Domain-specific vocabulary |
|
||||
| Voice hooks | `src/hooks/useVoice.ts`, `useVoiceEnabled.ts`, `useVoiceIntegration.tsx` | React hooks |
|
||||
| Voice command | `src/commands/voice/` | `/voice` slash command |
|
||||
|
||||
Gated behind the `VOICE_MODE` feature flag.
|
||||
|
||||
---
|
||||
|
||||
## Service Layer
|
||||
|
||||
**Location:** `src/services/`
|
||||
|
||||
External integrations and shared services.
|
||||
|
||||
| Service | Path | Purpose |
|
||||
|---------|------|---------|
|
||||
| **API** | `api/` | Anthropic SDK client, file uploads, bootstrap |
|
||||
| **MCP** | `mcp/` | MCP client connections and tool discovery |
|
||||
| **OAuth** | `oauth/` | OAuth 2.0 authentication flow |
|
||||
| **LSP** | `lsp/` | Language Server Protocol manager |
|
||||
| **Analytics** | `analytics/` | GrowthBook feature flags, telemetry |
|
||||
| **Plugins** | `plugins/` | Plugin loader and marketplace |
|
||||
| **Compact** | `compact/` | Conversation context compression |
|
||||
| **Policy Limits** | `policyLimits/` | Organization rate limits/quota |
|
||||
| **Remote Settings** | `remoteManagedSettings/` | Enterprise managed settings sync |
|
||||
| **Token Estimation** | `tokenEstimation.ts` | Token count estimation |
|
||||
| **Team Memory** | `teamMemorySync/` | Team knowledge synchronization |
|
||||
| **Tips** | `tips/` | Contextual usage tips |
|
||||
| **Agent Summary** | `AgentSummary/` | Agent work summaries |
|
||||
| **Prompt Suggestion** | `PromptSuggestion/` | Suggested follow-up prompts |
|
||||
| **Session Memory** | `SessionMemory/` | Session-level memory |
|
||||
| **Magic Docs** | `MagicDocs/` | Documentation generation |
|
||||
| **Auto Dream** | `autoDream/` | Background ideation |
|
||||
| **x402** | `x402/` | x402 payment protocol |
|
||||
|
||||
---
|
||||
|
||||
## See Also
|
||||
|
||||
- [Architecture](architecture.md) — How subsystems connect in the core pipeline
|
||||
- [Tools Reference](tools.md) — Tools related to each subsystem
|
||||
- [Commands Reference](commands.md) — Commands for managing subsystems
|
||||
- [Exploration Guide](exploration-guide.md) — Finding subsystem source code
|
||||
173
docs/tools.md
Normal file
173
docs/tools.md
Normal file
@@ -0,0 +1,173 @@
|
||||
# Tools Reference
|
||||
|
||||
> Complete catalog of all ~40 agent tools in Claude Code.
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Every tool lives in `src/tools/<ToolName>/` as a self-contained module. Each tool defines:
|
||||
|
||||
- **Input schema** — Zod-validated parameters
|
||||
- **Permission model** — What requires user approval
|
||||
- **Execution logic** — The tool's implementation
|
||||
- **UI components** — Terminal rendering for invocation and results
|
||||
- **Concurrency safety** — Whether it can run in parallel
|
||||
|
||||
Tools are registered in `src/tools.ts` and invoked by the Query Engine during LLM tool-call loops.
|
||||
|
||||
### Tool Definition Pattern
|
||||
|
||||
```typescript
|
||||
export const MyTool = buildTool({
|
||||
name: 'MyTool',
|
||||
aliases: ['my_tool'],
|
||||
description: 'What this tool does',
|
||||
inputSchema: z.object({
|
||||
param: z.string(),
|
||||
}),
|
||||
async call(args, context, canUseTool, parentMessage, onProgress) {
|
||||
// Execute and return { data: result, newMessages?: [...] }
|
||||
},
|
||||
async checkPermissions(input, context) { /* Permission checks */ },
|
||||
isConcurrencySafe(input) { /* Can run in parallel? */ },
|
||||
isReadOnly(input) { /* Non-destructive? */ },
|
||||
prompt(options) { /* System prompt injection */ },
|
||||
renderToolUseMessage(input, options) { /* UI for invocation */ },
|
||||
renderToolResultMessage(content, progressMessages, options) { /* UI for result */ },
|
||||
})
|
||||
```
|
||||
|
||||
**Directory structure per tool:**
|
||||
|
||||
```
|
||||
src/tools/MyTool/
|
||||
├── MyTool.ts # Main implementation
|
||||
├── UI.tsx # Terminal rendering
|
||||
├── prompt.ts # System prompt contribution
|
||||
└── utils.ts # Tool-specific helpers
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## File System Tools
|
||||
|
||||
| Tool | Description | Read-Only |
|
||||
|------|-------------|-----------|
|
||||
| **FileReadTool** | Read file contents (text, images, PDFs, notebooks). Supports line ranges | Yes |
|
||||
| **FileWriteTool** | Create or overwrite files | No |
|
||||
| **FileEditTool** | Partial file modification via string replacement | No |
|
||||
| **GlobTool** | Find files matching glob patterns (e.g. `**/*.ts`) | Yes |
|
||||
| **GrepTool** | Content search using ripgrep (regex-capable) | Yes |
|
||||
| **NotebookEditTool** | Edit Jupyter notebook cells | No |
|
||||
| **TodoWriteTool** | Write to a structured todo/task file | No |
|
||||
|
||||
## Shell & Execution Tools
|
||||
|
||||
| Tool | Description | Read-Only |
|
||||
|------|-------------|-----------|
|
||||
| **BashTool** | Execute shell commands in bash | No |
|
||||
| **PowerShellTool** | Execute PowerShell commands (Windows) | No |
|
||||
| **REPLTool** | Run code in a REPL session (Python, Node, etc.) | No |
|
||||
|
||||
## Agent & Orchestration Tools
|
||||
|
||||
| Tool | Description | Read-Only |
|
||||
|------|-------------|-----------|
|
||||
| **AgentTool** | Spawn a sub-agent for complex tasks | No |
|
||||
| **SendMessageTool** | Send messages between agents | No |
|
||||
| **TeamCreateTool** | Create a team of parallel agents | No |
|
||||
| **TeamDeleteTool** | Remove a team agent | No |
|
||||
| **EnterPlanModeTool** | Switch to planning mode (no execution) | No |
|
||||
| **ExitPlanModeTool** | Exit planning mode, resume execution | No |
|
||||
| **EnterWorktreeTool** | Isolate work in a git worktree | No |
|
||||
| **ExitWorktreeTool** | Exit worktree isolation | No |
|
||||
| **SleepTool** | Pause execution (proactive mode) | Yes |
|
||||
| **SyntheticOutputTool** | Generate structured output | Yes |
|
||||
|
||||
## Task Management Tools
|
||||
|
||||
| Tool | Description | Read-Only |
|
||||
|------|-------------|-----------|
|
||||
| **TaskCreateTool** | Create a new background task | No |
|
||||
| **TaskUpdateTool** | Update a task's status or details | No |
|
||||
| **TaskGetTool** | Get details of a specific task | Yes |
|
||||
| **TaskListTool** | List all tasks | Yes |
|
||||
| **TaskOutputTool** | Get output from a completed task | Yes |
|
||||
| **TaskStopTool** | Stop a running task | No |
|
||||
|
||||
## Web Tools
|
||||
|
||||
| Tool | Description | Read-Only |
|
||||
|------|-------------|-----------|
|
||||
| **WebFetchTool** | Fetch content from a URL | Yes |
|
||||
| **WebSearchTool** | Search the web | Yes |
|
||||
|
||||
## MCP (Model Context Protocol) Tools
|
||||
|
||||
| Tool | Description | Read-Only |
|
||||
|------|-------------|-----------|
|
||||
| **MCPTool** | Invoke tools on connected MCP servers | Varies |
|
||||
| **ListMcpResourcesTool** | List resources exposed by MCP servers | Yes |
|
||||
| **ReadMcpResourceTool** | Read a specific MCP resource | Yes |
|
||||
| **McpAuthTool** | Handle MCP server authentication | No |
|
||||
| **ToolSearchTool** | Discover deferred/dynamic tools from MCP servers | Yes |
|
||||
|
||||
## Integration Tools
|
||||
|
||||
| Tool | Description | Read-Only |
|
||||
|------|-------------|-----------|
|
||||
| **LSPTool** | Language Server Protocol operations (go-to-definition, find references, etc.) | Yes |
|
||||
| **SkillTool** | Execute a registered skill | Varies |
|
||||
|
||||
## Scheduling & Triggers
|
||||
|
||||
| Tool | Description | Read-Only |
|
||||
|------|-------------|-----------|
|
||||
| **ScheduleCronTool** | Create a scheduled cron trigger | No |
|
||||
| **RemoteTriggerTool** | Fire a remote trigger | No |
|
||||
|
||||
## Utility Tools
|
||||
|
||||
| Tool | Description | Read-Only |
|
||||
|------|-------------|-----------|
|
||||
| **AskUserQuestionTool** | Prompt the user for input during execution | Yes |
|
||||
| **BriefTool** | Generate a brief/summary | Yes |
|
||||
| **ConfigTool** | Read or modify Claude Code configuration | No |
|
||||
|
||||
---
|
||||
|
||||
## Permission Model
|
||||
|
||||
Every tool invocation passes through the permission system (`src/hooks/toolPermission/`). Permission modes:
|
||||
|
||||
| Mode | Behavior |
|
||||
|------|----------|
|
||||
| `default` | Prompt the user for each potentially destructive operation |
|
||||
| `plan` | Show the full plan, ask once |
|
||||
| `bypassPermissions` | Auto-approve everything (dangerous) |
|
||||
| `auto` | ML-based classifier decides |
|
||||
|
||||
Permission rules use wildcard patterns:
|
||||
|
||||
```
|
||||
Bash(git *) # Allow all git commands
|
||||
FileEdit(/src/*) # Allow edits to anything in src/
|
||||
FileRead(*) # Allow reading any file
|
||||
```
|
||||
|
||||
Each tool implements `checkPermissions()` returning `{ granted: boolean, reason?, prompt? }`.
|
||||
|
||||
---
|
||||
|
||||
## Tool Presets
|
||||
|
||||
Tools are grouped into presets in `src/tools.ts` for different contexts (e.g. read-only tools for code review, full toolset for development).
|
||||
|
||||
---
|
||||
|
||||
## See Also
|
||||
|
||||
- [Architecture](architecture.md) — How tools fit into the overall pipeline
|
||||
- [Subsystems Guide](subsystems.md) — MCP, permissions, and other tool-related subsystems
|
||||
- [Exploration Guide](exploration-guide.md) — How to read tool source code
|
||||
@@ -134,6 +134,30 @@ Once connected, you can ask your AI assistant things like:
|
||||
- Use the `explain_tool` prompt with "FileEditTool" to get a full breakdown
|
||||
- Use `how_does_it_work` with "bridge" to understand IDE integration
|
||||
|
||||
## Publishing to MCP Registry
|
||||
|
||||
This server is published to the [MCP Registry](https://registry.modelcontextprotocol.io) via GitHub Actions. On a tagged release (`v*`), the workflow:
|
||||
|
||||
1. Publishes the npm package to npmjs.org
|
||||
2. Authenticates with the MCP Registry using GitHub OIDC
|
||||
3. Publishes the `server.json` metadata to the registry
|
||||
|
||||
To publish manually:
|
||||
|
||||
```bash
|
||||
# Install the MCP Publisher CLI
|
||||
curl -L "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" | tar xz mcp-publisher
|
||||
|
||||
# Authenticate (GitHub OAuth)
|
||||
./mcp-publisher login github
|
||||
|
||||
# Publish
|
||||
cd mcp-server
|
||||
../mcp-publisher publish
|
||||
```
|
||||
|
||||
Registry name: `io.github.nirholas/claude-code-explorer-mcp`
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
|
||||
1364
mcp-server/package-lock.json
generated
1364
mcp-server/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
24
mcp-server/server.json
Normal file
24
mcp-server/server.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
||||
"name": "io.github.nirholas/claude-code-explorer-mcp",
|
||||
"title": "Claude Code Explorer MCP",
|
||||
"description": "MCP server for exploring the Claude Code CLI source code — browse 40+ tools, 50+ commands, search the full 512K-line codebase, and get architecture overviews.",
|
||||
"repository": {
|
||||
"url": "https://github.com/nirholas/claude-code",
|
||||
"source": "github",
|
||||
"subfolder": "mcp-server"
|
||||
},
|
||||
"version": "1.1.0",
|
||||
"packages": [
|
||||
{
|
||||
"registryType": "npm",
|
||||
"registryBaseUrl": "https://registry.npmjs.org",
|
||||
"identifier": "claude-code-explorer-mcp",
|
||||
"version": "1.1.0",
|
||||
"transport": {
|
||||
"type": "stdio"
|
||||
},
|
||||
"runtimeHint": "node"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -24,386 +24,6 @@ main().catch((err) => {
|
||||
});
|
||||
|
||||
|
||||
/** Recursively collect all file paths under `root` (relative to root). */
|
||||
async function walkFiles(root: string, rel = ""): Promise<string[]> {
|
||||
const results: string[] = [];
|
||||
let entries;
|
||||
try {
|
||||
entries = await fs.readdir(path.join(root, rel), { withFileTypes: true });
|
||||
} catch {
|
||||
return results;
|
||||
}
|
||||
for (const e of entries) {
|
||||
const child = rel ? `${rel}/${e.name}` : e.name;
|
||||
if (e.isDirectory()) {
|
||||
results.push(...(await walkFiles(root, child)));
|
||||
} else {
|
||||
results.push(child);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
/** Safely resolve a user-supplied relative path under SRC_ROOT. */
|
||||
function safePath(relPath: string): string | null {
|
||||
const resolved = path.resolve(SRC_ROOT, relPath);
|
||||
if (!resolved.startsWith(SRC_ROOT)) return null; // path traversal blocked
|
||||
return resolved;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Tool & Command Metadata
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
interface ToolInfo {
|
||||
name: string;
|
||||
directory: string;
|
||||
files: string[];
|
||||
}
|
||||
|
||||
interface CommandInfo {
|
||||
name: string;
|
||||
path: string;
|
||||
isDirectory: boolean;
|
||||
files?: string[];
|
||||
}
|
||||
|
||||
async function getToolList(): Promise<ToolInfo[]> {
|
||||
const toolsDir = path.join(SRC_ROOT, "tools");
|
||||
const entries = await fs.readdir(toolsDir, { withFileTypes: true });
|
||||
const tools: ToolInfo[] = [];
|
||||
|
||||
for (const e of entries) {
|
||||
if (!e.isDirectory() || e.name === "shared" || e.name === "testing")
|
||||
continue;
|
||||
const files = await listDir(path.join(toolsDir, e.name));
|
||||
tools.push({ name: e.name, directory: `tools/${e.name}`, files });
|
||||
}
|
||||
return tools.sort((a, b) => a.name.localeCompare(b.name));
|
||||
}
|
||||
|
||||
async function getCommandList(): Promise<CommandInfo[]> {
|
||||
const cmdsDir = path.join(SRC_ROOT, "commands");
|
||||
const entries = await fs.readdir(cmdsDir, { withFileTypes: true });
|
||||
const commands: CommandInfo[] = [];
|
||||
|
||||
for (const e of entries) {
|
||||
if (e.isDirectory()) {
|
||||
const files = await listDir(path.join(cmdsDir, e.name));
|
||||
commands.push({
|
||||
name: e.name,
|
||||
path: `commands/${e.name}`,
|
||||
isDirectory: true,
|
||||
files,
|
||||
});
|
||||
} else {
|
||||
commands.push({
|
||||
name: e.name.replace(/\.(ts|tsx)$/, ""),
|
||||
path: `commands/${e.name}`,
|
||||
isDirectory: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
return commands.sort((a, b) => a.name.localeCompare(b.name));
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Server
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const server = new Server(
|
||||
{ name: "claude-code-explorer", version: "1.0.0" },
|
||||
{
|
||||
capabilities: {
|
||||
tools: {},
|
||||
resources: {},
|
||||
prompts: {},
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
// ---- Resources -----------------------------------------------------------
|
||||
|
||||
server.setRequestHandler(ListResourcesRequestSchema, async () => ({
|
||||
resources: [
|
||||
{
|
||||
uri: "claude-code://architecture",
|
||||
name: "Architecture Overview",
|
||||
description: "High-level overview of the Claude Code source architecture",
|
||||
mimeType: "text/markdown",
|
||||
},
|
||||
{
|
||||
uri: "claude-code://tools",
|
||||
name: "Tool Registry",
|
||||
description: "List of all agent tools with their files",
|
||||
mimeType: "application/json",
|
||||
},
|
||||
{
|
||||
uri: "claude-code://commands",
|
||||
name: "Command Registry",
|
||||
description: "List of all slash commands",
|
||||
mimeType: "application/json",
|
||||
},
|
||||
],
|
||||
}));
|
||||
|
||||
server.setRequestHandler(ListResourceTemplatesRequestSchema, async () => ({
|
||||
resourceTemplates: [
|
||||
{
|
||||
uriTemplate: "claude-code://source/{path}",
|
||||
name: "Source file",
|
||||
description: "Read a source file from the Claude Code src/ directory",
|
||||
mimeType: "text/plain",
|
||||
},
|
||||
],
|
||||
}));
|
||||
|
||||
server.setRequestHandler(ReadResourceRequestSchema, async (request: { params: { uri: string } }) => {
|
||||
const { uri } = request.params;
|
||||
|
||||
if (uri === "claude-code://architecture") {
|
||||
const readmePath = path.resolve(SRC_ROOT, "..", "README.md");
|
||||
let text: string;
|
||||
try {
|
||||
text = await fs.readFile(readmePath, "utf-8");
|
||||
} catch {
|
||||
text = "README.md not found.";
|
||||
}
|
||||
return { contents: [{ uri, mimeType: "text/markdown", text }] };
|
||||
}
|
||||
|
||||
if (uri === "claude-code://tools") {
|
||||
const tools = await getToolList();
|
||||
return {
|
||||
contents: [
|
||||
{
|
||||
uri,
|
||||
mimeType: "application/json",
|
||||
text: JSON.stringify(tools, null, 2),
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
if (uri === "claude-code://commands") {
|
||||
const commands = await getCommandList();
|
||||
return {
|
||||
contents: [
|
||||
{
|
||||
uri,
|
||||
mimeType: "application/json",
|
||||
text: JSON.stringify(commands, null, 2),
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
// Source file template
|
||||
if (uri.startsWith("claude-code://source/")) {
|
||||
const relPath = uri.slice("claude-code://source/".length);
|
||||
const abs = safePath(relPath);
|
||||
if (!abs) throw new Error("Invalid path");
|
||||
const text = await fs.readFile(abs, "utf-8");
|
||||
return { contents: [{ uri, mimeType: "text/plain", text }] };
|
||||
}
|
||||
|
||||
throw new Error(`Unknown resource: ${uri}`);
|
||||
});
|
||||
|
||||
// ---- Tools ---------------------------------------------------------------
|
||||
|
||||
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
||||
tools: [
|
||||
{
|
||||
name: "list_tools",
|
||||
description:
|
||||
"List all Claude Code agent tools (BashTool, FileReadTool, etc.) with their source files.",
|
||||
inputSchema: { type: "object" as const, properties: {} },
|
||||
},
|
||||
{
|
||||
name: "list_commands",
|
||||
description:
|
||||
"List all Claude Code slash commands (/commit, /review, /mcp, etc.) with their source files.",
|
||||
inputSchema: { type: "object" as const, properties: {} },
|
||||
},
|
||||
{
|
||||
name: "get_tool_source",
|
||||
description:
|
||||
"Read the full source code of a specific Claude Code tool implementation. Provide the tool directory name (e.g. 'BashTool', 'FileEditTool').",
|
||||
inputSchema: {
|
||||
type: "object" as const,
|
||||
properties: {
|
||||
toolName: {
|
||||
type: "string",
|
||||
description:
|
||||
"Tool directory name, e.g. 'BashTool', 'FileReadTool'",
|
||||
},
|
||||
fileName: {
|
||||
type: "string",
|
||||
description:
|
||||
"Optional: specific file within the tool directory. If omitted, returns the main implementation file.",
|
||||
},
|
||||
},
|
||||
required: ["toolName"],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "get_command_source",
|
||||
description:
|
||||
"Read the source code of a specific Claude Code slash command. Provide the command name (e.g. 'commit', 'review', 'mcp').",
|
||||
inputSchema: {
|
||||
type: "object" as const,
|
||||
properties: {
|
||||
commandName: {
|
||||
type: "string",
|
||||
description: "Command name, e.g. 'commit', 'review', 'mcp'",
|
||||
},
|
||||
fileName: {
|
||||
type: "string",
|
||||
description:
|
||||
"Optional: specific file within the command directory.",
|
||||
},
|
||||
},
|
||||
required: ["commandName"],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "read_source_file",
|
||||
description:
|
||||
"Read any source file from the Claude Code src/ directory by relative path.",
|
||||
inputSchema: {
|
||||
type: "object" as const,
|
||||
properties: {
|
||||
path: {
|
||||
type: "string",
|
||||
description:
|
||||
"Relative path from src/, e.g. 'QueryEngine.ts', 'services/mcp/types.ts'",
|
||||
},
|
||||
startLine: {
|
||||
type: "number",
|
||||
description: "Optional 1-based start line to read from.",
|
||||
},
|
||||
endLine: {
|
||||
type: "number",
|
||||
description: "Optional 1-based end line to read to.",
|
||||
},
|
||||
},
|
||||
required: ["path"],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "search_source",
|
||||
description:
|
||||
"Search for a pattern (regex or plain text) across the Claude Code source code. Returns matching lines with file paths and line numbers.",
|
||||
inputSchema: {
|
||||
type: "object" as const,
|
||||
properties: {
|
||||
pattern: {
|
||||
type: "string",
|
||||
description: "Search pattern (regex supported).",
|
||||
},
|
||||
filePattern: {
|
||||
type: "string",
|
||||
description:
|
||||
"Optional glob-like filter for file extensions, e.g. '.ts', '.tsx'.",
|
||||
},
|
||||
maxResults: {
|
||||
type: "number",
|
||||
description: "Maximum number of matches to return (default: 50).",
|
||||
},
|
||||
},
|
||||
required: ["pattern"],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "list_directory",
|
||||
description:
|
||||
"List files and subdirectories within a directory under src/.",
|
||||
inputSchema: {
|
||||
type: "object" as const,
|
||||
properties: {
|
||||
path: {
|
||||
type: "string",
|
||||
description:
|
||||
"Relative path from src/, e.g. 'services', 'tools/BashTool'. Use '' for the root.",
|
||||
},
|
||||
},
|
||||
required: ["path"],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "get_architecture",
|
||||
description:
|
||||
"Get a high-level architecture overview of Claude Code including directory structure, core systems, and key files.",
|
||||
inputSchema: { type: "object" as const, properties: {} },
|
||||
},
|
||||
],
|
||||
}));
|
||||
|
||||
server.setRequestHandler(CallToolRequestSchema, async (request: { params: { name: string; arguments?: Record<string, unknown> } }) => {
|
||||
const { name, arguments: args } = request.params;
|
||||
|
||||
switch (name) {
|
||||
// ---- list_tools ----
|
||||
case "list_tools": {
|
||||
const tools = await getToolList();
|
||||
return {
|
||||
content: [{ type: "text" as const, text: JSON.stringify(tools, null, 2) }],
|
||||
};
|
||||
}
|
||||
|
||||
// ---- list_commands ----
|
||||
case "list_commands": {
|
||||
const commands = await getCommandList();
|
||||
return {
|
||||
content: [
|
||||
{ type: "text" as const, text: JSON.stringify(commands, null, 2) },
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
// ---- get_tool_source ----
|
||||
case "get_tool_source": {
|
||||
const toolName = (args as Record<string, unknown>)?.toolName as string;
|
||||
if (!toolName) throw new Error("toolName is required");
|
||||
const toolDir = safePath(`tools/${toolName}`);
|
||||
if (!toolDir || !(await dirExists(toolDir)))
|
||||
throw new Error(`Tool not found: ${toolName}`);
|
||||
|
||||
let fileName = (args as Record<string, unknown>)?.fileName as
|
||||
| string
|
||||
| undefined;
|
||||
if (!fileName) {
|
||||
// Find the main implementation file
|
||||
const files = await listDir(toolDir);
|
||||
const main =
|
||||
files.find(
|
||||
(f) => f === `${toolName}.ts` || f === `${toolName}.tsx`
|
||||
) ?? files.find((f) => f.endsWith(".ts") || f.endsWith(".tsx"));
|
||||
if (!main) throw new Error(`No source files in ${toolName}`);
|
||||
fileName = main;
|
||||
}
|
||||
|
||||
const filePath = safePath(`tools/${toolName}/${fileName}`);
|
||||
if (!filePath || !(await fileExists(filePath)))
|
||||
throw new Error(`File not found: tools/${toolName}/${fileName}`);
|
||||
const content = await fs.readFile(filePath, "utf-8");
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: "text" as const,
|
||||
text: `// tools/${toolName}/${fileName}\n// ${content.split("\n").length} lines\n\n${content}`,
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
// ---- get_command_source ----
|
||||
case "get_command_source": {
|
||||
const commandName = (args as Record<string, unknown>)
|
||||
?.commandName as string;
|
||||
if (!commandName) throw new Error("commandName is required");
|
||||
|
||||
// Try directory first, then .ts / .tsx
|
||||
const candidates = [
|
||||
`commands/${commandName}`,
|
||||
|
||||
24
mcp-server/src/index.ts.new
Normal file
24
mcp-server/src/index.ts.new
Normal file
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* STDIO entrypoint — for local use with Claude Desktop, Claude Code, etc.
|
||||
*
|
||||
* Usage:
|
||||
* node dist/index.js
|
||||
* CLAUDE_CODE_SRC_ROOT=/path/to/src node dist/index.js
|
||||
*/
|
||||
|
||||
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
||||
import { createServer, validateSrcRoot, SRC_ROOT } from "./server.js";
|
||||
|
||||
async function main() {
|
||||
await validateSrcRoot();
|
||||
const server = createServer();
|
||||
const transport = new StdioServerTransport();
|
||||
await server.connect(transport);
|
||||
console.error(`Claude Code Explorer MCP (stdio) started — src: ${SRC_ROOT}`);
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error("Fatal error:", err);
|
||||
process.exit(1);
|
||||
});
|
||||
2560
package-lock.json
generated
Normal file
2560
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
35
prompts/00-overview.md
Normal file
35
prompts/00-overview.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# Build-Out Prompt Index
|
||||
|
||||
Run these prompts **in order** in separate chat sessions. Each one is self-contained.
|
||||
|
||||
| # | File | What It Does | Depends On |
|
||||
|---|------|-------------|------------|
|
||||
| 01 | `01-install-bun-and-deps.md` | Install Bun runtime, install all dependencies | — |
|
||||
| 02 | `02-runtime-shims.md` | Create `bun:bundle` runtime shim + `MACRO` globals so code runs without Bun's bundler | 01 |
|
||||
| 03 | `03-build-config.md` | Create esbuild-based build system that bundles the CLI to a single runnable file | 01, 02 |
|
||||
| 04 | `04-fix-mcp-server.md` | Fix TypeScript errors in `mcp-server/` and make it build | 01 |
|
||||
| 05 | `05-env-and-auth.md` | Set up `.env` file, API key config, OAuth stubs | 01 |
|
||||
| 06 | `06-ink-react-terminal-ui.md` | Verify and fix the Ink/React terminal rendering pipeline | 01, 02, 03 |
|
||||
| 07 | `07-tool-system.md` | Audit and wire up the 40+ tool implementations (BashTool, FileEditTool, etc.) | 01–03 |
|
||||
| 08 | `08-command-system.md` | Audit and wire up the 50+ slash commands (/commit, /review, etc.) | 01–03, 07 |
|
||||
| 09 | `09-query-engine.md` | Get the core LLM call loop (QueryEngine) functional — streaming, tool calls, retries | 01–03, 05, 07 |
|
||||
| 10 | `10-context-and-prompts.md` | Wire up system prompt construction, context gathering, memory system | 01–03 |
|
||||
| 11 | `11-mcp-integration.md` | Get MCP client/server integration working — registry, tool discovery | 01–04 |
|
||||
| 12 | `12-services-layer.md` | Wire up analytics, policy limits, remote settings, session memory | 01–03, 05 |
|
||||
| 13 | `13-bridge-ide.md` | Stub out or implement the VS Code / JetBrains bridge layer | 01–03, 09 |
|
||||
| 14 | `14-dev-runner.md` | Create `npm run dev` / `bun run dev` script that launches the CLI in dev mode | 01–03 |
|
||||
| 15 | `15-production-bundle.md` | Create production build: minified bundle, platform-specific packaging | 03 |
|
||||
| 16 | `16-testing.md` | Add test infrastructure (vitest), write smoke tests for core subsystems | All |
|
||||
|
||||
## Quick Start
|
||||
|
||||
1. Open a new Copilot chat
|
||||
2. Paste the contents of `01-install-bun-and-deps.md`
|
||||
3. Follow the instructions / let the agent run
|
||||
4. Repeat for `02`, `03`, etc.
|
||||
|
||||
## Notes
|
||||
|
||||
- Prompts 07–13 can be run somewhat in **parallel** (they touch different subsystems)
|
||||
- If a prompt fails, fix the issue before moving to the next one
|
||||
- Each prompt is designed to be **independently verifiable** — it tells you how to confirm it worked
|
||||
38
prompts/01-install-bun-and-deps.md
Normal file
38
prompts/01-install-bun-and-deps.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# Prompt 01: Install Bun Runtime & Dependencies
|
||||
|
||||
## Context
|
||||
|
||||
You are working in `/workspaces/claude-code`, which contains the leaked source code of Anthropic's Claude Code CLI. It's a TypeScript/TSX project that uses **Bun** as its runtime (not Node.js). The `package.json` specifies `"engines": { "bun": ">=1.1.0" }`.
|
||||
|
||||
There is no `bun.lockb` lockfile — it was not included in the leak.
|
||||
|
||||
## Task
|
||||
|
||||
1. **Install Bun** (if not already installed):
|
||||
```
|
||||
curl -fsSL https://bun.sh/install | bash
|
||||
```
|
||||
Then ensure `bun` is on the PATH.
|
||||
|
||||
2. **Run `bun install`** in the project root (`/workspaces/claude-code`) to install all dependencies. This will generate a `bun.lockb` lockfile.
|
||||
|
||||
3. **Verify the install** — confirm that:
|
||||
- `node_modules/` exists and has the major packages: `@anthropic-ai/sdk`, `react`, `chalk`, `@commander-js/extra-typings`, `ink` (may not exist separately — check `@anthropic-ai/sdk`, `zod`, `@modelcontextprotocol/sdk`)
|
||||
- `bun --version` returns 1.1.0+
|
||||
|
||||
4. **Run the typecheck** to see current state:
|
||||
```
|
||||
bun run typecheck
|
||||
```
|
||||
Report any errors — don't fix them yet, just capture the output.
|
||||
|
||||
5. **Also install deps for the mcp-server sub-project**:
|
||||
```
|
||||
cd mcp-server && npm install && cd ..
|
||||
```
|
||||
|
||||
## Verification
|
||||
|
||||
- `bun --version` outputs >= 1.1.0
|
||||
- `ls node_modules/@anthropic-ai/sdk` succeeds
|
||||
- `bun run typecheck` runs (errors are expected at this stage, just report them)
|
||||
137
prompts/02-runtime-shims.md
Normal file
137
prompts/02-runtime-shims.md
Normal file
@@ -0,0 +1,137 @@
|
||||
# Prompt 02: Runtime Shims for `bun:bundle` Feature Flags & `MACRO` Globals
|
||||
|
||||
## Context
|
||||
|
||||
You are working in `/workspaces/claude-code`. This is the Claude Code CLI source. It was built to run under **Bun's bundler** which provides two build-time features that don't exist at runtime:
|
||||
|
||||
### 1. `bun:bundle` feature flags
|
||||
Throughout the code you'll find:
|
||||
```ts
|
||||
import { feature } from 'bun:bundle'
|
||||
if (feature('BRIDGE_MODE')) { ... }
|
||||
```
|
||||
Bun's bundler replaces `feature('X')` with `true`/`false` at build time for dead-code elimination. Without the bundler, this import fails at runtime.
|
||||
|
||||
**Current state**: There's a type stub at `src/types/bun-bundle.d.ts` that satisfies TypeScript, but there's no runtime module. We need a real module.
|
||||
|
||||
### 2. `MACRO` global object
|
||||
The code references a global `MACRO` object with these properties:
|
||||
- `MACRO.VERSION` — package version string (e.g., `"1.0.53"`)
|
||||
- `MACRO.PACKAGE_URL` — npm package name (e.g., `"@anthropic-ai/claude-code"`)
|
||||
- `MACRO.ISSUES_EXPLAINER` — feedback URL/instructions string
|
||||
|
||||
These are normally inlined by the bundler. Some files already guard with `typeof MACRO !== 'undefined'`, but most don't.
|
||||
|
||||
## Task
|
||||
|
||||
### Part A: Create `bun:bundle` runtime module
|
||||
|
||||
Create a file at `src/shims/bun-bundle.ts` that exports a `feature()` function. Feature flags should be configurable via environment variables so we can toggle them:
|
||||
|
||||
```ts
|
||||
// src/shims/bun-bundle.ts
|
||||
|
||||
// Map of feature flags to their enabled state.
|
||||
// In production Bun builds, these are compile-time constants.
|
||||
// For our dev build, we read from env vars with sensible defaults.
|
||||
const FEATURE_FLAGS: Record<string, boolean> = {
|
||||
PROACTIVE: envBool('CLAUDE_CODE_PROACTIVE', false),
|
||||
KAIROS: envBool('CLAUDE_CODE_KAIROS', false),
|
||||
BRIDGE_MODE: envBool('CLAUDE_CODE_BRIDGE_MODE', false),
|
||||
DAEMON: envBool('CLAUDE_CODE_DAEMON', false),
|
||||
VOICE_MODE: envBool('CLAUDE_CODE_VOICE_MODE', false),
|
||||
AGENT_TRIGGERS: envBool('CLAUDE_CODE_AGENT_TRIGGERS', false),
|
||||
MONITOR_TOOL: envBool('CLAUDE_CODE_MONITOR_TOOL', false),
|
||||
COORDINATOR_MODE: envBool('CLAUDE_CODE_COORDINATOR_MODE', false),
|
||||
ABLATION_BASELINE: false, // always off for external builds
|
||||
DUMP_SYSTEM_PROMPT: envBool('CLAUDE_CODE_DUMP_SYSTEM_PROMPT', false),
|
||||
BG_SESSIONS: envBool('CLAUDE_CODE_BG_SESSIONS', false),
|
||||
}
|
||||
|
||||
function envBool(key: string, fallback: boolean): boolean {
|
||||
const v = process.env[key]
|
||||
if (v === undefined) return fallback
|
||||
return v === '1' || v === 'true'
|
||||
}
|
||||
|
||||
export function feature(name: string): boolean {
|
||||
return FEATURE_FLAGS[name] ?? false
|
||||
}
|
||||
```
|
||||
|
||||
### Part B: Create `MACRO` global definition
|
||||
|
||||
Create a file at `src/shims/macro.ts` that defines and installs the global `MACRO` object:
|
||||
|
||||
```ts
|
||||
// src/shims/macro.ts
|
||||
|
||||
// Read version from package.json at startup
|
||||
import { readFileSync } from 'fs'
|
||||
import { resolve, dirname } from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url)
|
||||
const pkgPath = resolve(dirname(__filename), '..', '..', 'package.json')
|
||||
let version = '0.0.0-dev'
|
||||
try {
|
||||
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'))
|
||||
version = pkg.version || version
|
||||
} catch {}
|
||||
|
||||
const MACRO_OBJ = {
|
||||
VERSION: version,
|
||||
PACKAGE_URL: '@anthropic-ai/claude-code',
|
||||
ISSUES_EXPLAINER: 'report issues at https://github.com/anthropics/claude-code/issues',
|
||||
}
|
||||
|
||||
// Install as global
|
||||
;(globalThis as any).MACRO = MACRO_OBJ
|
||||
|
||||
export default MACRO_OBJ
|
||||
```
|
||||
|
||||
### Part C: Create a preload/bootstrap file
|
||||
|
||||
Create `src/shims/preload.ts` that imports both shims so they're available before any app code runs:
|
||||
|
||||
```ts
|
||||
// src/shims/preload.ts
|
||||
// Must be loaded before any application code.
|
||||
// Provides runtime equivalents of Bun bundler build-time features.
|
||||
|
||||
import './macro.js'
|
||||
// bun:bundle is resolved via the build alias, not imported here
|
||||
```
|
||||
|
||||
### Part D: Update tsconfig.json `paths`
|
||||
|
||||
The current tsconfig.json has:
|
||||
```json
|
||||
"paths": {
|
||||
"bun:bundle": ["./src/types/bun-bundle.d.ts"]
|
||||
}
|
||||
```
|
||||
|
||||
This handles type-checking. For runtime, we'll need the build system (Prompt 03) to alias `bun:bundle` → `src/shims/bun-bundle.ts`. **Don't change tsconfig.json** — the type stub is correct for `tsc`. Just note this for the next prompt.
|
||||
|
||||
### Part E: Add global MACRO type declaration
|
||||
|
||||
Check if there's already a global type declaration for `MACRO`. If not, add one to `src/types/bun-bundle.d.ts` or a new `src/types/macro.d.ts`:
|
||||
|
||||
```ts
|
||||
declare const MACRO: {
|
||||
VERSION: string
|
||||
PACKAGE_URL: string
|
||||
ISSUES_EXPLAINER: string
|
||||
}
|
||||
```
|
||||
|
||||
Make sure `tsc --noEmit` still passes after your changes.
|
||||
|
||||
## Verification
|
||||
|
||||
1. `bun run typecheck` should pass (or have the same errors as before — no new errors)
|
||||
2. The files `src/shims/bun-bundle.ts`, `src/shims/macro.ts`, `src/shims/preload.ts` exist
|
||||
3. Running `bun -e "import { feature } from './src/shims/bun-bundle.ts'; console.log(feature('BRIDGE_MODE'))"` should print `false`
|
||||
4. Running `bun -e "import './src/shims/macro.ts'; console.log(MACRO.VERSION)"` should print the version
|
||||
165
prompts/03-build-config.md
Normal file
165
prompts/03-build-config.md
Normal file
@@ -0,0 +1,165 @@
|
||||
# Prompt 03: Create esbuild-Based Build System
|
||||
|
||||
## Context
|
||||
|
||||
You are working in `/workspaces/claude-code`. This is the Claude Code CLI — a TypeScript/TSX terminal app using React + Ink. It was originally built using **Bun's bundler** with feature flags, but that build config wasn't included in the leak.
|
||||
|
||||
We need to create a build system that:
|
||||
1. Bundles the entire `src/` tree into a runnable output
|
||||
2. Aliases `bun:bundle` → our shim at `src/shims/bun-bundle.ts`
|
||||
3. Injects the `MACRO` global (via `src/shims/macro.ts` preload)
|
||||
4. Handles TSX/JSX (React)
|
||||
5. Handles ESM `.js` extension imports (the code uses `import from './foo.js'` which maps to `./foo.ts`)
|
||||
6. Produces output that can run under **Bun** (primary) or **Node.js 20+** (secondary)
|
||||
|
||||
## Existing Files
|
||||
|
||||
- `src/shims/bun-bundle.ts` — runtime `feature()` function (created in Prompt 02)
|
||||
- `src/shims/macro.ts` — global `MACRO` object (created in Prompt 02)
|
||||
- `src/shims/preload.ts` — preload bootstrap (created in Prompt 02)
|
||||
- `src/entrypoints/cli.tsx` — main entrypoint
|
||||
- `tsconfig.json` — has `"jsx": "react-jsx"`, `"module": "ESNext"`, `"moduleResolution": "bundler"`
|
||||
|
||||
## Task
|
||||
|
||||
### Part A: Install esbuild
|
||||
|
||||
```bash
|
||||
bun add -d esbuild
|
||||
```
|
||||
|
||||
### Part B: Create build script
|
||||
|
||||
Create `scripts/build-bundle.ts` (a Bun-runnable build script):
|
||||
|
||||
```ts
|
||||
// scripts/build-bundle.ts
|
||||
// Usage: bun scripts/build-bundle.ts [--watch] [--minify]
|
||||
|
||||
import * as esbuild from 'esbuild'
|
||||
import { resolve } from 'path'
|
||||
|
||||
const ROOT = resolve(import.meta.dir, '..')
|
||||
const watch = process.argv.includes('--watch')
|
||||
const minify = process.argv.includes('--minify')
|
||||
|
||||
const buildOptions: esbuild.BuildOptions = {
|
||||
entryPoints: [resolve(ROOT, 'src/entrypoints/cli.tsx')],
|
||||
bundle: true,
|
||||
platform: 'node',
|
||||
target: 'node20',
|
||||
format: 'esm',
|
||||
outdir: resolve(ROOT, 'dist'),
|
||||
outExtension: { '.js': '.mjs' },
|
||||
|
||||
// Inject the MACRO global before all other code
|
||||
inject: [resolve(ROOT, 'src/shims/macro.ts')],
|
||||
|
||||
// Alias bun:bundle to our runtime shim
|
||||
alias: {
|
||||
'bun:bundle': resolve(ROOT, 'src/shims/bun-bundle.ts'),
|
||||
},
|
||||
|
||||
// Don't bundle node built-ins or native packages
|
||||
external: [
|
||||
// Node built-ins
|
||||
'fs', 'path', 'os', 'crypto', 'child_process', 'http', 'https',
|
||||
'net', 'tls', 'url', 'util', 'stream', 'events', 'buffer',
|
||||
'querystring', 'readline', 'zlib', 'assert', 'tty', 'worker_threads',
|
||||
'perf_hooks', 'async_hooks', 'dns', 'dgram', 'cluster',
|
||||
'node:*',
|
||||
// Native addons that can't be bundled
|
||||
'fsevents',
|
||||
],
|
||||
|
||||
jsx: 'automatic',
|
||||
|
||||
// Source maps for debugging
|
||||
sourcemap: true,
|
||||
|
||||
minify,
|
||||
|
||||
// Banner: shebang for CLI + preload the MACRO global
|
||||
banner: {
|
||||
js: '#!/usr/bin/env node\n',
|
||||
},
|
||||
|
||||
// Handle the .js → .ts resolution that the codebase uses
|
||||
resolveExtensions: ['.tsx', '.ts', '.jsx', '.js', '.json'],
|
||||
|
||||
logLevel: 'info',
|
||||
}
|
||||
|
||||
async function main() {
|
||||
if (watch) {
|
||||
const ctx = await esbuild.context(buildOptions)
|
||||
await ctx.watch()
|
||||
console.log('Watching for changes...')
|
||||
} else {
|
||||
const result = await esbuild.build(buildOptions)
|
||||
if (result.errors.length > 0) {
|
||||
console.error('Build failed')
|
||||
process.exit(1)
|
||||
}
|
||||
console.log('Build complete → dist/')
|
||||
}
|
||||
}
|
||||
|
||||
main().catch(err => {
|
||||
console.error(err)
|
||||
process.exit(1)
|
||||
})
|
||||
```
|
||||
|
||||
**Important**: This is a starting point. You will likely need to iterate on the externals list and alias configuration. The codebase has ~1,900 files — some imports may need special handling. When you run the build:
|
||||
|
||||
1. Run it: `bun scripts/build-bundle.ts`
|
||||
2. Look at the errors
|
||||
3. Fix them (add externals, fix aliases, etc.)
|
||||
4. Repeat until it bundles successfully
|
||||
|
||||
Common issues you'll hit:
|
||||
- **npm packages that use native modules** → add to `external`
|
||||
- **Dynamic `require()` calls** behind `process.env.USER_TYPE === 'ant'` → these are Anthropic-internal, wrap them or stub them
|
||||
- **Circular dependencies** → esbuild handles these but may warn
|
||||
- **Re-exports from barrel files** → should work but watch for issues
|
||||
|
||||
### Part C: Add npm scripts
|
||||
|
||||
Add these to `package.json` `"scripts"`:
|
||||
|
||||
```json
|
||||
{
|
||||
"build": "bun scripts/build-bundle.ts",
|
||||
"build:watch": "bun scripts/build-bundle.ts --watch",
|
||||
"build:prod": "bun scripts/build-bundle.ts --minify"
|
||||
}
|
||||
```
|
||||
|
||||
### Part D: Create dist output directory
|
||||
|
||||
Add `dist/` to `.gitignore` (create one if it doesn't exist).
|
||||
|
||||
### Part E: Iterate on build errors
|
||||
|
||||
Run the build and fix whatever comes up. The goal is a clean `bun scripts/build-bundle.ts` that produces `dist/cli.mjs`.
|
||||
|
||||
**Strategy for unresolvable modules**: If modules reference Anthropic-internal packages or Bun-specific APIs (like `Bun.hash`, `Bun.file`), create minimal stubs in `src/shims/` that provide compatible fallbacks.
|
||||
|
||||
### Part F: Test the output
|
||||
|
||||
After a successful build:
|
||||
```bash
|
||||
node dist/cli.mjs --version
|
||||
# or
|
||||
bun dist/cli.mjs --version
|
||||
```
|
||||
|
||||
This should print the version. It will likely crash after that because no API key is configured — that's fine for now.
|
||||
|
||||
## Verification
|
||||
|
||||
1. `bun scripts/build-bundle.ts` completes without errors
|
||||
2. `dist/cli.mjs` exists
|
||||
3. `bun dist/cli.mjs --version` or `node dist/cli.mjs --version` prints a version string
|
||||
4. `package.json` has `build`, `build:watch`, `build:prod` scripts
|
||||
45
prompts/04-fix-mcp-server.md
Normal file
45
prompts/04-fix-mcp-server.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# Prompt 04: Fix MCP Server Build
|
||||
|
||||
## Context
|
||||
|
||||
You are working in `/workspaces/claude-code/mcp-server/`. This is a separate sub-project that provides an MCP (Model Context Protocol) server for exploring the Claude Code source. It's a simpler, self-contained TypeScript project.
|
||||
|
||||
Currently `npm run build` (which runs `tsc`) fails with TypeScript errors.
|
||||
|
||||
## Task
|
||||
|
||||
1. **Run the build and capture errors**:
|
||||
```bash
|
||||
cd /workspaces/claude-code/mcp-server
|
||||
npm run build 2>&1
|
||||
```
|
||||
|
||||
2. **Fix all TypeScript errors** in `mcp-server/src/server.ts` and `mcp-server/src/index.ts`. Common issues include:
|
||||
- Duplicate function implementations
|
||||
- Missing imports
|
||||
- Type mismatches with the MCP SDK types
|
||||
|
||||
3. **Verify the fix**:
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
Should complete with zero errors and produce output in `mcp-server/dist/`.
|
||||
|
||||
4. **Test the MCP server runs**:
|
||||
```bash
|
||||
node dist/index.js --help 2>&1 || node dist/index.js 2>&1 | head -5
|
||||
```
|
||||
It may hang waiting for stdio input (that's normal for an MCP server) — just verify it starts without crashing.
|
||||
|
||||
## Key Files
|
||||
|
||||
- `mcp-server/package.json` — build script and dependencies
|
||||
- `mcp-server/tsconfig.json` — TypeScript config
|
||||
- `mcp-server/src/server.ts` — Main server logic (tools, resources, prompts)
|
||||
- `mcp-server/src/index.ts` — Entrypoint (stdio transport)
|
||||
|
||||
## Verification
|
||||
|
||||
1. `cd mcp-server && npm run build` succeeds with zero errors
|
||||
2. `ls mcp-server/dist/` shows compiled `.js` files
|
||||
3. `node mcp-server/dist/index.js` starts without immediate crash
|
||||
100
prompts/05-env-and-auth.md
Normal file
100
prompts/05-env-and-auth.md
Normal file
@@ -0,0 +1,100 @@
|
||||
# Prompt 05: Environment Configuration & API Authentication
|
||||
|
||||
## Context
|
||||
|
||||
You are working in `/workspaces/claude-code`. The CLI needs an Anthropic API key to function. The auth system supports multiple backends:
|
||||
- **Direct API** (`ANTHROPIC_API_KEY`) — simplest
|
||||
- **OAuth** (Claude.ai subscription) — complex browser flow
|
||||
- **AWS Bedrock** — `AWS_*` env vars
|
||||
- **Google Vertex AI** — GCP credentials
|
||||
- **Azure Foundry** — `ANTHROPIC_FOUNDRY_API_KEY`
|
||||
|
||||
## Task
|
||||
|
||||
### Part A: Create `.env` file from the existing code
|
||||
|
||||
Search the codebase for all environment variables used. Key files to check:
|
||||
- `src/entrypoints/cli.tsx` (reads env vars at top level)
|
||||
- `src/services/api/client.ts` (API client construction)
|
||||
- `src/utils/auth.ts` (authentication)
|
||||
- `src/utils/config.ts` (config loading)
|
||||
- `src/constants/` (any hardcoded config)
|
||||
- `src/entrypoints/init.ts` (initialization reads)
|
||||
|
||||
Create a `.env.example` file (or update the existing one if it exists) with ALL discoverable env vars, organized by category, with documentation comments. At minimum include:
|
||||
|
||||
```env
|
||||
# ─── Authentication ───
|
||||
ANTHROPIC_API_KEY= # Required: Your Anthropic API key (sk-ant-...)
|
||||
|
||||
# ─── API Configuration ───
|
||||
ANTHROPIC_BASE_URL= # Custom API endpoint (default: https://api.anthropic.com)
|
||||
ANTHROPIC_MODEL= # Override default model (e.g., claude-sonnet-4-20250514)
|
||||
ANTHROPIC_SMALL_FAST_MODEL= # Model for fast/cheap operations (e.g., claude-haiku)
|
||||
|
||||
# ─── Feature Flags (used by bun:bundle shim) ───
|
||||
CLAUDE_CODE_PROACTIVE=false
|
||||
CLAUDE_CODE_BRIDGE_MODE=false
|
||||
CLAUDE_CODE_COORDINATOR_MODE=false
|
||||
CLAUDE_CODE_VOICE_MODE=false
|
||||
|
||||
# ─── Debug ───
|
||||
CLAUDE_CODE_DEBUG_LOG_LEVEL= # debug, info, warn, error
|
||||
DEBUG=false
|
||||
```
|
||||
|
||||
### Part B: Trace the API client setup
|
||||
|
||||
Read `src/services/api/client.ts` to understand how the Anthropic SDK is initialized. Document:
|
||||
1. What env vars it reads
|
||||
2. How it selects between API backends (direct, Bedrock, Vertex, etc.)
|
||||
3. Where the API key comes from (env var? keychain? OAuth token?)
|
||||
|
||||
Create a comment block at the top of `.env.example` explaining how auth works.
|
||||
|
||||
### Part C: Create a minimal auth test
|
||||
|
||||
Create `scripts/test-auth.ts`:
|
||||
```ts
|
||||
// scripts/test-auth.ts
|
||||
// Quick test that the API key is configured and can reach Anthropic
|
||||
// Usage: bun scripts/test-auth.ts
|
||||
|
||||
import Anthropic from '@anthropic-ai/sdk'
|
||||
|
||||
const client = new Anthropic({
|
||||
apiKey: process.env.ANTHROPIC_API_KEY,
|
||||
})
|
||||
|
||||
async function main() {
|
||||
try {
|
||||
const msg = await client.messages.create({
|
||||
model: process.env.ANTHROPIC_MODEL || 'claude-sonnet-4-20250514',
|
||||
max_tokens: 50,
|
||||
messages: [{ role: 'user', content: 'Say "hello" and nothing else.' }],
|
||||
})
|
||||
console.log('✅ API connection successful!')
|
||||
console.log('Response:', msg.content[0].type === 'text' ? msg.content[0].text : msg.content[0])
|
||||
} catch (err: any) {
|
||||
console.error('❌ API connection failed:', err.message)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
main()
|
||||
```
|
||||
|
||||
### Part D: Stub OAuth for development
|
||||
|
||||
The OAuth flow (`src/services/oauth/`) requires browser interaction and Anthropic's OAuth endpoints. For development, we want to bypass it.
|
||||
|
||||
Search for where the auth decision is made (likely in `src/utils/auth.ts` or `src/entrypoints/init.ts`). Document what would need to be stubbed to skip OAuth and use only `ANTHROPIC_API_KEY`.
|
||||
|
||||
Don't modify source files yet — just document findings in a comment at the bottom of `.env.example`.
|
||||
|
||||
## Verification
|
||||
|
||||
1. `.env.example` exists with comprehensive env var documentation
|
||||
2. `scripts/test-auth.ts` exists
|
||||
3. With a valid `ANTHROPIC_API_KEY` set: `bun scripts/test-auth.ts` prints success
|
||||
4. Without an API key: `bun scripts/test-auth.ts` prints a clear error
|
||||
110
prompts/06-ink-react-terminal-ui.md
Normal file
110
prompts/06-ink-react-terminal-ui.md
Normal file
@@ -0,0 +1,110 @@
|
||||
# Prompt 06: Verify and Fix the Ink/React Terminal UI Pipeline
|
||||
|
||||
## Context
|
||||
|
||||
You are working in `/workspaces/claude-code`. The CLI renders its UI using **React + Ink** — a framework that renders React components to the terminal (not a browser). This project includes a **custom fork of Ink** embedded directly in `src/ink/`.
|
||||
|
||||
Key files:
|
||||
- `src/ink.ts` — Public API (re-exports `render()` and `createRoot()`, wraps with `ThemeProvider`)
|
||||
- `src/ink/root.ts` — Ink's root renderer
|
||||
- `src/ink/ink.tsx` — Core Ink component
|
||||
- `src/ink/reconciler.ts` — React reconciler for terminal output
|
||||
- `src/ink/dom.ts` — Terminal DOM implementation
|
||||
- `src/ink/renderer.ts` — Renders virtual DOM to terminal strings
|
||||
- `src/ink/components/` — Built-in Ink components (Box, Text, etc.)
|
||||
- `src/components/` — Claude Code's ~140 custom components
|
||||
|
||||
## Task
|
||||
|
||||
### Part A: Trace the render pipeline
|
||||
|
||||
Read these files in order and document the rendering flow:
|
||||
|
||||
1. `src/ink.ts` → how `render()` and `createRoot()` work
|
||||
2. `src/ink/root.ts` → how Ink creates a root and mounts React
|
||||
3. `src/ink/reconciler.ts` → what React reconciler is used
|
||||
4. `src/ink/renderer.ts` → how the virtual DOM becomes terminal output
|
||||
5. `src/ink/dom.ts` → what the "DOM nodes" look like
|
||||
|
||||
Create a brief architecture doc in a comment block or README section.
|
||||
|
||||
### Part B: Verify Ink components compile
|
||||
|
||||
Check that the core Ink components are self-contained:
|
||||
```
|
||||
src/ink/components/
|
||||
```
|
||||
List them all and verify they don't have missing imports.
|
||||
|
||||
### Part C: Check the ThemeProvider
|
||||
|
||||
Read `src/components/design-system/ThemeProvider.tsx` (or wherever it lives). Verify it:
|
||||
1. Exists
|
||||
2. Exports a `ThemeProvider` component
|
||||
3. The theme system doesn't depend on external resources
|
||||
|
||||
### Part D: Create a minimal render test
|
||||
|
||||
Create `scripts/test-ink.tsx`:
|
||||
```tsx
|
||||
// scripts/test-ink.tsx
|
||||
// Minimal test that the Ink terminal UI renders
|
||||
// Usage: bun scripts/test-ink.tsx
|
||||
|
||||
import React from 'react'
|
||||
|
||||
// We need the shims loaded first
|
||||
import './src/shims/preload.js'
|
||||
|
||||
// Now try to use Ink
|
||||
import { render } from './src/ink.js'
|
||||
|
||||
// Minimal component
|
||||
function Hello() {
|
||||
return <Text>Hello from Claude Code Ink UI!</Text>
|
||||
}
|
||||
|
||||
// Need to import Text from Ink
|
||||
import { Text } from './src/ink/components/Text.js'
|
||||
|
||||
async function main() {
|
||||
const instance = await render(<Hello />)
|
||||
// Give it a moment to render
|
||||
setTimeout(() => {
|
||||
instance.unmount()
|
||||
process.exit(0)
|
||||
}, 500)
|
||||
}
|
||||
|
||||
main().catch(err => {
|
||||
console.error('Ink render test failed:', err)
|
||||
process.exit(1)
|
||||
})
|
||||
```
|
||||
|
||||
Adjust the imports based on what you find — the Text component path may differ.
|
||||
|
||||
### Part E: Fix any issues
|
||||
|
||||
If Ink rendering fails, the common issues are:
|
||||
1. **Missing `yoga-wasm-web` or `yoga-layout`** — Ink uses Yoga for flexbox layout. Check if there's a Yoga dependency or if it's embedded.
|
||||
2. **React version mismatch** — The code uses React 19. Verify the reconciler is compatible.
|
||||
3. **Terminal detection** — Ink checks if stdout is a TTY. In some environments this may need to be forced.
|
||||
4. **Missing chalk/ansi dependency** — Terminal colors.
|
||||
|
||||
Fix whatever you find to make the test render successfully.
|
||||
|
||||
### Part F: Verify component imports
|
||||
|
||||
Check that `src/components/` components can import from the Ink system without errors. Pick 3-5 key components:
|
||||
- `src/components/MessageResponse.tsx` (or similar — the main chat message renderer)
|
||||
- `src/components/ToolUseResult.tsx` (or similar — tool output display)
|
||||
- `src/components/PermissionRequest.tsx` (or similar — permission modal)
|
||||
|
||||
Read their imports and verify nothing is missing.
|
||||
|
||||
## Verification
|
||||
|
||||
1. `scripts/test-ink.tsx` renders "Hello from Claude Code Ink UI!" to the terminal
|
||||
2. No new TypeScript errors introduced
|
||||
3. You've documented the render pipeline flow
|
||||
104
prompts/07-tool-system.md
Normal file
104
prompts/07-tool-system.md
Normal file
@@ -0,0 +1,104 @@
|
||||
# Prompt 07: Audit and Wire Up the Tool System
|
||||
|
||||
## Context
|
||||
|
||||
You are working in `/workspaces/claude-code`. The Claude Code CLI has ~40 tools that the LLM can invoke during conversations. Each tool is in `src/tools/<ToolName>/` and follows a consistent pattern.
|
||||
|
||||
Key files:
|
||||
- `src/Tool.ts` (~29K lines) — Tool type definitions, `ToolUseContext`, `PermissionResult`, etc.
|
||||
- `src/tools.ts` — Tool registry (`getTools()` function that returns all available tools)
|
||||
- `src/tools/` — Individual tool directories
|
||||
|
||||
## Task
|
||||
|
||||
### Part A: Understand the Tool interface
|
||||
|
||||
Read `src/Tool.ts` and document the `Tool` interface. Key questions:
|
||||
1. What fields does a `Tool` have? (name, description, inputSchema, execute, etc.)
|
||||
2. What is `ToolUseContext`? What does it provide to tool execution?
|
||||
3. How do tool permissions work? (`PermissionResult`, `needsPermission`)
|
||||
4. How do tools declare their input schema? (JSON Schema / Zod)
|
||||
|
||||
### Part B: Audit the tool registry
|
||||
|
||||
Read `src/tools.ts` fully. It dynamically imports tools behind feature flags and env checks:
|
||||
```ts
|
||||
const REPLTool = process.env.USER_TYPE === 'ant' ? ... : null
|
||||
const SleepTool = feature('PROACTIVE') || feature('KAIROS') ? ... : null
|
||||
```
|
||||
|
||||
Create a complete inventory of:
|
||||
1. **Always-available tools** — imported unconditionally
|
||||
2. **Feature-gated tools** — which feature flag enables them
|
||||
3. **Ant-only tools** — gated behind `USER_TYPE === 'ant'` (Anthropic internal)
|
||||
4. **Broken/missing tools** — any tools referenced but not found
|
||||
|
||||
### Part C: Verify each tool compiles
|
||||
|
||||
For each tool directory in `src/tools/`, check:
|
||||
1. Does it have an `index.ts` or main file?
|
||||
2. Does it export a tool definition matching the `Tool` interface?
|
||||
3. Are its imports resolvable?
|
||||
|
||||
Focus on the **core 10 tools** that are essential for basic operation:
|
||||
- `BashTool` — shell command execution
|
||||
- `FileReadTool` — read files
|
||||
- `FileWriteTool` — write files
|
||||
- `FileEditTool` — edit files (search & replace)
|
||||
- `GlobTool` — find files by pattern
|
||||
- `GrepTool` — search file contents
|
||||
- `AgentTool` — spawn sub-agent
|
||||
- `WebFetchTool` — HTTP requests
|
||||
- `AskUserQuestionTool` — ask the user for input
|
||||
- `TodoWriteTool` — todo list management
|
||||
|
||||
### Part D: Fix import issues
|
||||
|
||||
The tool registry (`src/tools.ts`) uses dynamic imports with `bun:bundle` feature flags. With our runtime shim, these should work — but verify:
|
||||
|
||||
1. Feature-gated imports resolve when the flag is `false` (should be skipped)
|
||||
2. Feature-gated imports resolve when the flag is `true` (should load)
|
||||
3. Ant-only tools gracefully handle `process.env.USER_TYPE !== 'ant'`
|
||||
|
||||
Fix any import resolution errors.
|
||||
|
||||
### Part E: Create a tool smoke test
|
||||
|
||||
Create `scripts/test-tools.ts`:
|
||||
```ts
|
||||
// scripts/test-tools.ts
|
||||
// Verify all tools load without errors
|
||||
// Usage: bun scripts/test-tools.ts
|
||||
|
||||
import './src/shims/preload.js'
|
||||
|
||||
async function main() {
|
||||
const { getTools } = await import('./src/tools.js')
|
||||
|
||||
// getTools() may need arguments — check its signature
|
||||
const tools = getTools(/* ... */)
|
||||
|
||||
console.log(`Loaded ${tools.length} tools:\n`)
|
||||
for (const tool of tools) {
|
||||
console.log(` ✓ ${tool.name}`)
|
||||
}
|
||||
}
|
||||
|
||||
main().catch(err => {
|
||||
console.error('Tool loading failed:', err)
|
||||
process.exit(1)
|
||||
})
|
||||
```
|
||||
|
||||
Adapt the script to match the actual `getTools()` signature.
|
||||
|
||||
### Part F: Stub Anthropic-internal tools
|
||||
|
||||
Any tools gated behind `USER_TYPE === 'ant'` should be cleanly excluded. Verify the null checks work and don't cause runtime errors when these tools are missing from the registry.
|
||||
|
||||
## Verification
|
||||
|
||||
1. `scripts/test-tools.ts` runs and lists all available tools without errors
|
||||
2. The core 10 tools listed above are all present
|
||||
3. No TypeScript errors in `src/tools/` or `src/tools.ts`
|
||||
4. Ant-only tools are cleanly excluded (no crashes)
|
||||
90
prompts/08-command-system.md
Normal file
90
prompts/08-command-system.md
Normal file
@@ -0,0 +1,90 @@
|
||||
# Prompt 08: Audit and Wire Up the Command System
|
||||
|
||||
## Context
|
||||
|
||||
You are working in `/workspaces/claude-code`. The CLI has ~50 slash commands (e.g., `/commit`, `/review`, `/init`, `/config`). These are registered in `src/commands.ts` and implemented in `src/commands/`.
|
||||
|
||||
Key files:
|
||||
- `src/commands.ts` (~25K lines) — Command registry (`getCommands()`)
|
||||
- `src/commands/` — Individual command implementations
|
||||
- `src/types/command.ts` — Command type definition
|
||||
|
||||
## Task
|
||||
|
||||
### Part A: Understand the Command interface
|
||||
|
||||
Read `src/types/command.ts` and the top of `src/commands.ts`. Document:
|
||||
1. The `Command` type (name, description, execute, args, etc.)
|
||||
2. How commands are registered
|
||||
3. How command execution is triggered (from the REPL? from CLI args?)
|
||||
|
||||
### Part B: Audit the command registry
|
||||
|
||||
Read `src/commands.ts` fully. Create a complete inventory of all commands, organized by category:
|
||||
|
||||
**Essential commands** (needed for basic operation):
|
||||
- `/help` — show help
|
||||
- `/config` — view/edit configuration
|
||||
- `/init` — initialize a project
|
||||
- `/commit` — git commit
|
||||
- `/review` — code review
|
||||
|
||||
**Feature-gated commands** (behind feature flags or USER_TYPE):
|
||||
- List which flag enables each
|
||||
|
||||
**Potentially broken commands** (reference missing imports or services):
|
||||
- List any that can't resolve their imports
|
||||
|
||||
### Part C: Verify core commands compile
|
||||
|
||||
For the essential commands listed above, read their implementations and check:
|
||||
1. All imports resolve
|
||||
2. They don't depend on unavailable services
|
||||
3. The function signatures match the Command type
|
||||
|
||||
### Part D: Fix import issues
|
||||
|
||||
Similar to the tool system, commands may have:
|
||||
- Feature-gated imports that need the `bun:bundle` shim
|
||||
- Ant-only code paths
|
||||
- Dynamic imports that need correct paths
|
||||
|
||||
Fix whatever is broken.
|
||||
|
||||
### Part E: Handle "moved to plugin" commands
|
||||
|
||||
There's a file `src/commands/createMovedToPluginCommand.ts`. Read it — some commands have been migrated to the plugin system. These should gracefully tell the user the command has moved, not crash.
|
||||
|
||||
### Part F: Create a command smoke test
|
||||
|
||||
Create `scripts/test-commands.ts`:
|
||||
```ts
|
||||
// scripts/test-commands.ts
|
||||
// Verify all commands load without errors
|
||||
// Usage: bun scripts/test-commands.ts
|
||||
|
||||
import './src/shims/preload.js'
|
||||
|
||||
async function main() {
|
||||
const { getCommands } = await import('./src/commands.js')
|
||||
|
||||
const commands = getCommands(/* check signature */)
|
||||
|
||||
console.log(`Loaded ${commands.length} commands:\n`)
|
||||
for (const cmd of commands) {
|
||||
console.log(` /${cmd.name} — ${cmd.description || '(no description)'}`)
|
||||
}
|
||||
}
|
||||
|
||||
main().catch(err => {
|
||||
console.error('Command loading failed:', err)
|
||||
process.exit(1)
|
||||
})
|
||||
```
|
||||
|
||||
## Verification
|
||||
|
||||
1. `scripts/test-commands.ts` lists all available commands
|
||||
2. Core commands (`/help`, `/config`, `/init`, `/commit`) are present
|
||||
3. No runtime crashes from missing imports
|
||||
4. Moved-to-plugin commands show a friendly message instead of crashing
|
||||
118
prompts/09-query-engine.md
Normal file
118
prompts/09-query-engine.md
Normal file
@@ -0,0 +1,118 @@
|
||||
# Prompt 09: Get the QueryEngine (Core LLM Loop) Functional
|
||||
|
||||
## Context
|
||||
|
||||
You are working in `/workspaces/claude-code`. The `QueryEngine` (`src/QueryEngine.ts`, ~46K lines) is the heart of the CLI — it:
|
||||
1. Sends messages to the Anthropic API (streaming)
|
||||
2. Processes streaming responses (text, thinking, tool_use blocks)
|
||||
3. Executes tools when the LLM requests them (tool loop)
|
||||
4. Handles retries, rate limits, and errors
|
||||
5. Tracks token usage and costs
|
||||
6. Manages conversation context (message history)
|
||||
|
||||
This is the most complex single file. The goal is to get it functional enough for a basic conversation loop.
|
||||
|
||||
## Key Dependencies
|
||||
|
||||
The QueryEngine depends on:
|
||||
- `src/services/api/client.ts` — Anthropic SDK client
|
||||
- `src/services/api/claude.ts` — Message API wrapper
|
||||
- `src/Tool.ts` — Tool definitions
|
||||
- `src/tools.ts` — Tool registry
|
||||
- `src/context.ts` — System context
|
||||
- `src/constants/prompts.ts` — System prompt
|
||||
- Token counting utilities
|
||||
- Streaming event handlers
|
||||
|
||||
## Task
|
||||
|
||||
### Part A: Map the QueryEngine architecture
|
||||
|
||||
Read `src/QueryEngine.ts` and create a structural map:
|
||||
1. **Class structure** — What classes/interfaces are defined?
|
||||
2. **Public API** — What method starts a query? What does it return?
|
||||
3. **Message flow** — How does a user message become an API call?
|
||||
4. **Tool loop** — How are tool calls detected, executed, and fed back?
|
||||
5. **Streaming** — How are streaming events processed?
|
||||
6. **Retry logic** — How are API errors handled?
|
||||
|
||||
### Part B: Trace the API call path
|
||||
|
||||
Follow the chain from QueryEngine → API client:
|
||||
1. Read `src/services/api/client.ts` — how is the Anthropic SDK client created?
|
||||
2. Read `src/services/api/claude.ts` — what's the message creation wrapper?
|
||||
3. What parameters are passed? (model, max_tokens, system prompt, tools, messages)
|
||||
4. How is streaming handled? (SSE? SDK streaming?)
|
||||
|
||||
### Part C: Identify and fix blockers
|
||||
|
||||
The QueryEngine will have dependencies on many subsystems. For each dependency:
|
||||
- **If it's essential** (API client, tool execution) → make sure it works
|
||||
- **If it's optional** (analytics, telemetry, policy limits) → stub or skip it
|
||||
|
||||
Common blockers:
|
||||
1. **Missing API configuration** → needs `ANTHROPIC_API_KEY` (Prompt 05)
|
||||
2. **Policy limits service** → may block execution, needs stubbing
|
||||
3. **GrowthBook/analytics** → needs stubbing or graceful failure
|
||||
4. **Remote managed settings** → needs stubbing
|
||||
5. **Bootstrap data fetch** → may need to be optional
|
||||
|
||||
### Part D: Create a minimal conversation test
|
||||
|
||||
Create `scripts/test-query.ts` that exercises the QueryEngine directly:
|
||||
|
||||
```ts
|
||||
// scripts/test-query.ts
|
||||
// Minimal test of the QueryEngine — single query, no REPL
|
||||
// Usage: ANTHROPIC_API_KEY=sk-ant-... bun scripts/test-query.ts "What is 2+2?"
|
||||
|
||||
import './src/shims/preload.js'
|
||||
|
||||
async function main() {
|
||||
const query = process.argv[2] || 'What is 2+2?'
|
||||
|
||||
// Import and set up minimal dependencies
|
||||
// You'll need to figure out the exact imports and initialization
|
||||
// by reading src/QueryEngine.ts, src/query.ts, and src/replLauncher.tsx
|
||||
|
||||
// The basic flow should be:
|
||||
// 1. Create API client
|
||||
// 2. Build system prompt
|
||||
// 3. Create QueryEngine instance
|
||||
// 4. Send a query
|
||||
// 5. Print the response
|
||||
|
||||
console.log(`Query: ${query}`)
|
||||
console.log('---')
|
||||
|
||||
// TODO: Wire up the actual QueryEngine call
|
||||
// This is the hardest part — document what you need to do
|
||||
}
|
||||
|
||||
main().catch(err => {
|
||||
console.error('Query test failed:', err)
|
||||
process.exit(1)
|
||||
})
|
||||
```
|
||||
|
||||
### Part E: Handle the streaming response
|
||||
|
||||
The QueryEngine likely uses the Anthropic SDK's streaming interface. Make sure:
|
||||
1. Text content is printed to stdout as it streams
|
||||
2. Thinking blocks are handled (displayed or hidden based on config)
|
||||
3. Tool use blocks trigger tool execution
|
||||
4. The tool loop feeds results back and continues
|
||||
|
||||
### Part F: Document what's still broken
|
||||
|
||||
After getting a basic query working, document:
|
||||
1. Which features work
|
||||
2. Which features are stubbed
|
||||
3. What would need to happen for full functionality
|
||||
|
||||
## Verification
|
||||
|
||||
1. `ANTHROPIC_API_KEY=sk-ant-... bun scripts/test-query.ts "What is 2+2?"` gets a response
|
||||
2. Streaming output appears in real-time
|
||||
3. No unhandled crashes (graceful error messages are fine)
|
||||
4. Architecture is documented
|
||||
100
prompts/10-context-and-prompts.md
Normal file
100
prompts/10-context-and-prompts.md
Normal file
@@ -0,0 +1,100 @@
|
||||
# Prompt 10: Wire Up System Prompt, Context Gathering & Memory System
|
||||
|
||||
## Context
|
||||
|
||||
You are working in `/workspaces/claude-code`. The CLI constructs a detailed system prompt before each conversation. This prompt includes:
|
||||
1. **Static instructions** — core behavior rules (from `src/constants/prompts.ts`)
|
||||
2. **Dynamic context** — OS, shell, git status, working directory (from `src/context.ts`)
|
||||
3. **Tool descriptions** — auto-generated from tool schemas
|
||||
4. **Memory** — persistent `.claude.md` files (from `src/memdir/`)
|
||||
5. **User context** — config, preferences, project settings
|
||||
|
||||
## Key Files
|
||||
|
||||
- `src/constants/prompts.ts` — System prompt construction
|
||||
- `src/constants/system.ts` — System identity strings
|
||||
- `src/context.ts` — OS/shell/git context collection
|
||||
- `src/context/` — Additional context modules
|
||||
- `src/memdir/` — Memory directory system (reads `.claude.md`, `CLAUDE.md` files)
|
||||
- `src/utils/messages.ts` — Message construction helpers
|
||||
|
||||
## Task
|
||||
|
||||
### Part A: Trace the system prompt construction
|
||||
|
||||
Read `src/constants/prompts.ts` and map:
|
||||
1. What is `getSystemPrompt()`'s signature and return type?
|
||||
2. What sections does the system prompt contain?
|
||||
3. How are tools described in the prompt?
|
||||
4. What model-specific variations exist?
|
||||
5. Where does the `MACRO.ISSUES_EXPLAINER` reference resolve to?
|
||||
|
||||
### Part B: Fix the context gathering
|
||||
|
||||
Read `src/context.ts` and:
|
||||
1. Understand `getSystemContext()` and `getUserContext()`
|
||||
2. These collect OS info, shell version, git status, etc.
|
||||
3. Verify they work on Linux (this codebase was likely developed on macOS, so some paths may be macOS-specific)
|
||||
4. Fix any platform-specific issues
|
||||
|
||||
### Part C: Wire up the memory system
|
||||
|
||||
Read `src/memdir/` directory:
|
||||
1. How does it find `.claude.md` / `CLAUDE.md` files?
|
||||
2. How is memory content injected into the system prompt?
|
||||
3. Does it support project-level, user-level, and session-level memory?
|
||||
|
||||
Verify it works by:
|
||||
1. Creating a test `CLAUDE.md` in the project root
|
||||
2. Running the system prompt builder
|
||||
3. Checking the memory appears in the output
|
||||
|
||||
### Part D: Create a prompt inspection script
|
||||
|
||||
Create `scripts/test-prompt.ts`:
|
||||
```ts
|
||||
// scripts/test-prompt.ts
|
||||
// Dump the full system prompt that would be sent to the API
|
||||
// Usage: bun scripts/test-prompt.ts
|
||||
|
||||
import './src/shims/preload.js'
|
||||
|
||||
async function main() {
|
||||
// Import the prompt builder
|
||||
const { getSystemPrompt } = await import('./src/constants/prompts.js')
|
||||
|
||||
// May need to pass tools list and model name
|
||||
// Check the function signature
|
||||
const prompt = await getSystemPrompt([], 'claude-sonnet-4-20250514')
|
||||
|
||||
console.log('=== SYSTEM PROMPT ===')
|
||||
console.log(prompt.join('\n'))
|
||||
console.log('=== END ===')
|
||||
console.log(`\nTotal length: ${prompt.join('\n').length} characters`)
|
||||
}
|
||||
|
||||
main().catch(err => {
|
||||
console.error('Prompt test failed:', err)
|
||||
process.exit(1)
|
||||
})
|
||||
```
|
||||
|
||||
### Part E: Fix MACRO references in prompts
|
||||
|
||||
The prompt system references `MACRO.ISSUES_EXPLAINER`. Make sure our `MACRO` global (from `src/shims/macro.ts`) provides this value. If the prompt references other `MACRO` fields, add them too.
|
||||
|
||||
### Part F: Context module audit
|
||||
|
||||
Check `src/context/` for additional context modules:
|
||||
- Project detection (language, framework)
|
||||
- Git integration (branch, status, recent commits)
|
||||
- Environment detection (CI, container, SSH)
|
||||
|
||||
Verify these work in our dev environment.
|
||||
|
||||
## Verification
|
||||
|
||||
1. `bun scripts/test-prompt.ts` dumps a complete system prompt
|
||||
2. The prompt includes: tool descriptions, OS context, memory content
|
||||
3. No `undefined` or `MACRO.` references in the output
|
||||
4. Memory system reads `.claude.md` from the project root
|
||||
113
prompts/11-mcp-integration.md
Normal file
113
prompts/11-mcp-integration.md
Normal file
@@ -0,0 +1,113 @@
|
||||
# Prompt 11: MCP Client/Server Integration
|
||||
|
||||
## Context
|
||||
|
||||
You are working in `/workspaces/claude-code`. The CLI has built-in MCP (Model Context Protocol) support:
|
||||
- **MCP Client** — connects to external MCP servers (tools, resources)
|
||||
- **MCP Server** — exposes Claude Code itself as an MCP server
|
||||
|
||||
MCP lets the CLI use tools provided by external servers and lets other clients use Claude Code as a tool provider.
|
||||
|
||||
## Key Files
|
||||
|
||||
- `src/services/mcp/` — MCP client implementation
|
||||
- `src/services/mcp/types.ts` — MCP config types
|
||||
- `src/entrypoints/mcp.ts` — MCP server mode entrypoint
|
||||
- `src/tools/MCPTool/` — Tool that calls MCP servers
|
||||
- `src/tools/ListMcpResourcesTool/` — Lists MCP resources
|
||||
- `src/tools/ReadMcpResourceTool/` — Reads MCP resources
|
||||
- `src/tools/McpAuthTool/` — MCP server authentication
|
||||
- `mcp-server/` — Standalone MCP server sub-project (from Prompt 04)
|
||||
|
||||
## Task
|
||||
|
||||
### Part A: Understand MCP client architecture
|
||||
|
||||
Read `src/services/mcp/` directory:
|
||||
1. How are MCP servers discovered? (`.mcp.json` config file?)
|
||||
2. How are MCP server connections established? (stdio, HTTP, SSE?)
|
||||
3. How are MCP tools registered and made available?
|
||||
4. What is the `ScopedMcpServerConfig` type?
|
||||
|
||||
### Part B: Understand MCP config format
|
||||
|
||||
Search for `.mcp.json` or MCP config loading code. Document:
|
||||
1. Where does the config file live? (`~/.claude/.mcp.json`? project root?)
|
||||
2. What's the config schema? (server name, command, args, env?)
|
||||
3. How are multiple servers configured?
|
||||
|
||||
Example config you might find:
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"my-server": {
|
||||
"command": "node",
|
||||
"args": ["path/to/server.js"],
|
||||
"env": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Part C: Verify MCP SDK integration
|
||||
|
||||
The project uses `@modelcontextprotocol/sdk` (^1.12.1). Check:
|
||||
1. Is it installed in `node_modules/`?
|
||||
2. Does the import work: `import { Client } from '@modelcontextprotocol/sdk/client/index.js'`
|
||||
3. Are there version compatibility issues?
|
||||
|
||||
### Part D: Test MCP client with our own server
|
||||
|
||||
Create a test that:
|
||||
1. Starts the `mcp-server/` we fixed in Prompt 04 as a child process
|
||||
2. Connects to it via stdio using the MCP client from `src/services/mcp/`
|
||||
3. Lists available tools
|
||||
4. Calls one tool (e.g., `list_files` or `search_code`)
|
||||
|
||||
Create `scripts/test-mcp.ts`:
|
||||
```ts
|
||||
// scripts/test-mcp.ts
|
||||
// Test MCP client/server roundtrip
|
||||
// Usage: bun scripts/test-mcp.ts
|
||||
|
||||
import './src/shims/preload.js'
|
||||
|
||||
// TODO:
|
||||
// 1. Spawn mcp-server as a child process (stdio transport)
|
||||
// 2. Create MCP client from src/services/mcp/
|
||||
// 3. Connect client to server
|
||||
// 4. List tools
|
||||
// 5. Call a tool
|
||||
// 6. Print results
|
||||
```
|
||||
|
||||
### Part E: Test MCP server mode
|
||||
|
||||
The CLI can run as an MCP server itself (`src/entrypoints/mcp.ts`). Read this file and verify:
|
||||
1. What tools does it expose?
|
||||
2. What resources does it provide?
|
||||
3. Can it be started with `bun src/entrypoints/mcp.ts`?
|
||||
|
||||
### Part F: Create sample MCP config
|
||||
|
||||
Create a `.mcp.json` in the project root (or wherever the app looks for it) that configures the local MCP server:
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"claude-code-explorer": {
|
||||
"command": "node",
|
||||
"args": ["mcp-server/dist/index.js"],
|
||||
"env": {
|
||||
"CLAUDE_CODE_SRC_ROOT": "./src"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Verification
|
||||
|
||||
1. MCP client code in `src/services/mcp/` loads without errors
|
||||
2. MCP server mode (`src/entrypoints/mcp.ts`) starts without crashing
|
||||
3. A roundtrip test (client → server → response) works
|
||||
4. `.mcp.json` config file is created and parseable
|
||||
123
prompts/12-services-layer.md
Normal file
123
prompts/12-services-layer.md
Normal file
@@ -0,0 +1,123 @@
|
||||
# Prompt 12: Wire Up Services Layer (Analytics, Policy, Settings, Sessions)
|
||||
|
||||
## Context
|
||||
|
||||
You are working in `/workspaces/claude-code`. The CLI has several background services that run during operation:
|
||||
- **Analytics/Telemetry** — GrowthBook feature flags, OpenTelemetry traces
|
||||
- **Policy Limits** — rate limiting, quota enforcement from Anthropic backend
|
||||
- **Remote Managed Settings** — server-pushed configuration
|
||||
- **Session Memory** — persistent conversation history across invocations
|
||||
- **Bootstrap Data** — initial config fetched from API on startup
|
||||
|
||||
Most of these talk to Anthropic's backend servers and will fail in our dev build. The goal is to make them fail gracefully (not crash the app) or provide stubs.
|
||||
|
||||
## Key Files
|
||||
|
||||
- `src/services/analytics/growthbook.ts` — GrowthBook feature flag client
|
||||
- `src/services/analytics/` — Telemetry, event logging
|
||||
- `src/services/policyLimits/` — Rate limit enforcement
|
||||
- `src/services/remoteManagedSettings/` — Server-pushed settings
|
||||
- `src/services/SessionMemory/` — Conversation persistence
|
||||
- `src/services/api/bootstrap.ts` — Initial data fetch
|
||||
- `src/entrypoints/init.ts` — Where most services are initialized
|
||||
- `src/cost-tracker.ts` — Token usage and cost tracking
|
||||
|
||||
## Task
|
||||
|
||||
### Part A: Map the initialization sequence
|
||||
|
||||
Read `src/entrypoints/init.ts` carefully. Document:
|
||||
1. What services are initialized, in what order?
|
||||
2. Which are blocking (must complete before app starts)?
|
||||
3. Which are fire-and-forget (async, can fail silently)?
|
||||
4. What happens if each one fails?
|
||||
|
||||
### Part B: Make GrowthBook optional
|
||||
|
||||
Read `src/services/analytics/growthbook.ts`:
|
||||
1. How is GrowthBook initialized?
|
||||
2. Where is it called from? (feature flag checks throughout the codebase)
|
||||
3. What happens if initialization fails?
|
||||
|
||||
**Goal**: Make GrowthBook fail silently — all feature flag checks should return `false` (default) if GrowthBook is unavailable. This may already be handled, but verify it.
|
||||
|
||||
### Part C: Stub policy limits
|
||||
|
||||
Read `src/services/policyLimits/`:
|
||||
1. What limits does it enforce? (messages per minute, tokens per day, etc.)
|
||||
2. What happens when a limit is hit?
|
||||
3. Where is `loadPolicyLimits()` called?
|
||||
|
||||
**Goal**: Make the app work without policy limits. Either:
|
||||
- Stub the service to return "no limits" (allow everything)
|
||||
- Or catch and ignore errors from the API call
|
||||
|
||||
### Part D: Make remote settings optional
|
||||
|
||||
Read `src/services/remoteManagedSettings/`:
|
||||
1. What settings does it manage?
|
||||
2. What's the fallback when the server is unreachable?
|
||||
|
||||
**Goal**: Ensure the app works with default settings when the remote endpoint fails.
|
||||
|
||||
### Part E: Handle bootstrap data
|
||||
|
||||
Read `src/services/api/bootstrap.ts`:
|
||||
1. What data does it fetch?
|
||||
2. What uses this data?
|
||||
3. What happens if the fetch fails?
|
||||
|
||||
**Goal**: Provide sensible defaults when bootstrap fails (no API key = no bootstrap).
|
||||
|
||||
### Part F: Verify session memory
|
||||
|
||||
Read `src/services/SessionMemory/`:
|
||||
1. Where is session data stored? (filesystem path)
|
||||
2. How are sessions identified?
|
||||
3. Does it work with the local filesystem?
|
||||
|
||||
**Goal**: Session memory should work out of the box since it's local filesystem.
|
||||
|
||||
### Part G: Wire up cost tracking
|
||||
|
||||
Read `src/cost-tracker.ts`:
|
||||
1. How are costs calculated?
|
||||
2. Where is usage reported?
|
||||
3. Does it persist across sessions?
|
||||
|
||||
**Goal**: Cost tracking should work locally (just display, no remote reporting needed).
|
||||
|
||||
### Part H: Create a services smoke test
|
||||
|
||||
Create `scripts/test-services.ts`:
|
||||
```ts
|
||||
// scripts/test-services.ts
|
||||
// Test that all services initialize without crashing
|
||||
// Usage: bun scripts/test-services.ts
|
||||
|
||||
import './src/shims/preload.js'
|
||||
|
||||
async function main() {
|
||||
console.log('Testing service initialization...')
|
||||
|
||||
// Try to run the init sequence
|
||||
try {
|
||||
const { init } = await import('./src/entrypoints/init.js')
|
||||
await init()
|
||||
console.log('✅ Services initialized')
|
||||
} catch (err: any) {
|
||||
console.error('❌ Init failed:', err.message)
|
||||
// Document which service failed and why
|
||||
}
|
||||
}
|
||||
|
||||
main()
|
||||
```
|
||||
|
||||
## Verification
|
||||
|
||||
1. `bun scripts/test-services.ts` completes without crashing (warnings are fine)
|
||||
2. Missing remote services log warnings, not crashes
|
||||
3. Session memory reads/writes to the local filesystem
|
||||
4. Cost tracking displays locally
|
||||
5. The app can start even when Anthropic's backend is unreachable (with just an API key)
|
||||
75
prompts/13-bridge-ide.md
Normal file
75
prompts/13-bridge-ide.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# Prompt 13: Bridge Layer (VS Code / JetBrains IDE Integration)
|
||||
|
||||
## Context
|
||||
|
||||
You are working in `/workspaces/claude-code`. The "Bridge" is the subsystem that connects Claude Code to IDE extensions (VS Code, JetBrains). It enables:
|
||||
- Remote control of Claude Code from an IDE
|
||||
- Sharing file context between IDE and CLI
|
||||
- Permission approvals from the IDE UI
|
||||
- Session management across IDE and terminal
|
||||
|
||||
The Bridge is **gated behind `feature('BRIDGE_MODE')`** and is the most complex optional subsystem (~30 files in `src/bridge/`).
|
||||
|
||||
## Key Files
|
||||
|
||||
- `src/bridge/bridgeMain.ts` — Main bridge orchestration
|
||||
- `src/bridge/bridgeApi.ts` — Bridge API endpoints
|
||||
- `src/bridge/bridgeMessaging.ts` — WebSocket/HTTP messaging
|
||||
- `src/bridge/bridgeConfig.ts` — Bridge configuration
|
||||
- `src/bridge/bridgeUI.ts` — Bridge UI rendering
|
||||
- `src/bridge/jwtUtils.ts` — JWT authentication for bridge connections
|
||||
- `src/bridge/types.ts` — Bridge types
|
||||
- `src/bridge/initReplBridge.ts` — REPL integration
|
||||
- `src/bridge/replBridge.ts` — REPL bridge handle
|
||||
|
||||
## Task
|
||||
|
||||
### Part A: Understand the bridge architecture
|
||||
|
||||
Read `src/bridge/types.ts` and `src/bridge/bridgeMain.ts` (first 100 lines). Document:
|
||||
1. What protocols does the bridge use? (WebSocket, HTTP polling, etc.)
|
||||
2. How does authentication work? (JWT)
|
||||
3. What messages flow between IDE and CLI?
|
||||
4. How is the bridge lifecycle managed?
|
||||
|
||||
### Part B: Assess what's needed vs. what can be deferred
|
||||
|
||||
The bridge is a **nice-to-have** for initial build-out. Categorize:
|
||||
1. **Must work**: Feature flag gate (`feature('BRIDGE_MODE')` returns `false` → bridge code is skipped)
|
||||
2. **Can defer**: Full bridge functionality
|
||||
3. **Might break**: Code paths that assume bridge is available even when disabled
|
||||
|
||||
### Part C: Verify the feature gate works
|
||||
|
||||
Ensure that when `CLAUDE_CODE_BRIDGE_MODE=false` (or unset):
|
||||
1. Bridge code is not imported
|
||||
2. Bridge initialization is skipped
|
||||
3. No bridge-related errors appear
|
||||
4. The CLI works normally in terminal-only mode
|
||||
|
||||
### Part D: Stub the bridge for safety
|
||||
|
||||
If any code paths reference bridge functionality outside the feature gate:
|
||||
1. Create `src/bridge/stub.ts` with no-op implementations
|
||||
2. Make sure imports from `src/bridge/` resolve without crashing
|
||||
3. Ensure the REPL works without bridge
|
||||
|
||||
### Part E: Document bridge activation
|
||||
|
||||
For future work, document what would be needed to enable the bridge:
|
||||
1. Set `CLAUDE_CODE_BRIDGE_MODE=true`
|
||||
2. What IDE extension is needed?
|
||||
3. What authentication setup is required?
|
||||
4. What ports/sockets does it use?
|
||||
|
||||
### Part F: Check the Chrome extension bridge
|
||||
|
||||
There's a `--claude-in-chrome-mcp` and `--chrome-native-host` mode referenced in `src/entrypoints/cli.tsx`. Read these paths and document what they do. These can be deferred — just make sure they don't crash when not in use.
|
||||
|
||||
## Verification
|
||||
|
||||
1. CLI works normally with bridge disabled (default)
|
||||
2. No bridge-related errors in stdout/stderr
|
||||
3. `feature('BRIDGE_MODE')` correctly returns `false`
|
||||
4. Bridge architecture is documented for future enablement
|
||||
5. No dangling imports that crash when bridge is off
|
||||
137
prompts/14-dev-runner.md
Normal file
137
prompts/14-dev-runner.md
Normal file
@@ -0,0 +1,137 @@
|
||||
# Prompt 14: Create Development Runner
|
||||
|
||||
## Context
|
||||
|
||||
You are working in `/workspaces/claude-code`. By now you should have:
|
||||
- Bun installed (Prompt 01)
|
||||
- Runtime shims for `bun:bundle` and `MACRO` (Prompt 02)
|
||||
- A build system (Prompt 03)
|
||||
- Environment config (Prompt 05)
|
||||
|
||||
Now we need a way to **run the CLI in development mode** — quickly launching it without a full production build.
|
||||
|
||||
## Task
|
||||
|
||||
### Part A: Create `bun run dev` script
|
||||
|
||||
Bun can run TypeScript directly without compilation. Create a development launcher.
|
||||
|
||||
**Option 1: Direct Bun execution** (preferred)
|
||||
|
||||
Create `scripts/dev.ts`:
|
||||
```ts
|
||||
// scripts/dev.ts
|
||||
// Development launcher — runs the CLI directly via Bun
|
||||
// Usage: bun scripts/dev.ts [args...]
|
||||
// Or: bun run dev [args...]
|
||||
|
||||
// Load shims first
|
||||
import '../src/shims/preload.js'
|
||||
|
||||
// Register bun:bundle module resolver
|
||||
// Since Bun natively supports the module, we may need to
|
||||
// register our shim. Check if this is needed.
|
||||
|
||||
// Launch the CLI
|
||||
await import('../src/entrypoints/cli.js')
|
||||
```
|
||||
|
||||
**Option 2: Bun with preload**
|
||||
|
||||
Use Bun's `--preload` flag:
|
||||
```bash
|
||||
bun --preload ./src/shims/preload.ts src/entrypoints/cli.tsx
|
||||
```
|
||||
|
||||
**Investigate which approach works** with the `bun:bundle` import. The tricky part is that `bun:bundle` is a special Bun module name — at runtime (without the bundler), Bun may not recognize it. You'll need to either:
|
||||
1. Use Bun's `bunfig.toml` to create a module alias
|
||||
2. Use a loader/plugin to intercept the import
|
||||
3. Use a pre-transform step to rewrite imports
|
||||
|
||||
### Part B: Handle the `bun:bundle` import at runtime
|
||||
|
||||
This is the critical challenge. Options to investigate:
|
||||
|
||||
**Option A: `bunfig.toml` alias**
|
||||
```toml
|
||||
[resolve]
|
||||
alias = { "bun:bundle" = "./src/shims/bun-bundle.ts" }
|
||||
```
|
||||
|
||||
**Option B: Bun plugin**
|
||||
Create a Bun plugin that intercepts `bun:bundle`:
|
||||
```ts
|
||||
// scripts/bun-plugin-shims.ts
|
||||
import { plugin } from 'bun'
|
||||
|
||||
plugin({
|
||||
name: 'bun-bundle-shim',
|
||||
setup(build) {
|
||||
build.onResolve({ filter: /^bun:bundle$/ }, () => ({
|
||||
path: resolve(import.meta.dir, '../src/shims/bun-bundle.ts'),
|
||||
}))
|
||||
},
|
||||
})
|
||||
```
|
||||
Then reference it in `bunfig.toml`:
|
||||
```toml
|
||||
preload = ["./scripts/bun-plugin-shims.ts"]
|
||||
```
|
||||
|
||||
**Option C: Patch at build time**
|
||||
If runtime aliasing doesn't work, use a quick pre-build transform that replaces `from 'bun:bundle'` with `from '../shims/bun-bundle.js'` across all files, outputting to a temp directory.
|
||||
|
||||
**Try the options in order** and go with whichever works.
|
||||
|
||||
### Part C: Add npm scripts
|
||||
|
||||
Add to `package.json`:
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"dev": "bun scripts/dev.ts",
|
||||
"dev:repl": "bun scripts/dev.ts --repl",
|
||||
"start": "bun scripts/dev.ts"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Part D: Create a `.env` loader
|
||||
|
||||
If the dev script doesn't automatically load `.env`, add dotenv support:
|
||||
```bash
|
||||
bun add -d dotenv-cli
|
||||
```
|
||||
Then wrap the dev command:
|
||||
```json
|
||||
"dev": "dotenv -e .env -- bun scripts/dev.ts"
|
||||
```
|
||||
|
||||
Or use Bun's built-in `.env` loading (Bun automatically reads `.env` files).
|
||||
|
||||
### Part E: Test the development runner
|
||||
|
||||
1. Set `ANTHROPIC_API_KEY` in `.env`
|
||||
2. Run `bun run dev --version` → should print version
|
||||
3. Run `bun run dev --help` → should print help text
|
||||
4. Run `bun run dev` → should start the interactive REPL (will need working Ink UI)
|
||||
5. Run `ANTHROPIC_API_KEY=sk-ant-... bun run dev -p "say hello"` → should make one API call and print response
|
||||
|
||||
### Part F: Add debug mode
|
||||
|
||||
Add a debug script that enables verbose logging:
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"dev:debug": "CLAUDE_CODE_DEBUG_LOG_LEVEL=debug bun scripts/dev.ts"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Verification
|
||||
|
||||
1. `bun run dev --version` prints the version
|
||||
2. `bun run dev --help` prints help without errors
|
||||
3. The `bun:bundle` import resolves correctly at runtime
|
||||
4. `.env` variables are loaded
|
||||
5. No module resolution errors on startup
|
||||
123
prompts/15-production-bundle.md
Normal file
123
prompts/15-production-bundle.md
Normal file
@@ -0,0 +1,123 @@
|
||||
# Prompt 15: Production Bundle & Packaging
|
||||
|
||||
## Context
|
||||
|
||||
You are working in `/workspaces/claude-code`. By now you should have a working development runner (Prompt 14) and build system (Prompt 03). This prompt focuses on creating a production-quality bundle.
|
||||
|
||||
## Task
|
||||
|
||||
### Part A: Optimize the esbuild configuration
|
||||
|
||||
Update `scripts/build-bundle.ts` for production:
|
||||
|
||||
1. **Tree shaking** — esbuild does this by default, but verify:
|
||||
- Feature-gated code with `if (feature('X'))` where X is `false` should be eliminated
|
||||
- `process.env.USER_TYPE === 'ant'` branches should be eliminated (set `define` to replace with `false`)
|
||||
|
||||
2. **Define replacements** — Inline constants at build time:
|
||||
```ts
|
||||
define: {
|
||||
'process.env.USER_TYPE': '"external"', // Not 'ant' (Anthropic internal)
|
||||
'process.env.NODE_ENV': '"production"',
|
||||
}
|
||||
```
|
||||
|
||||
3. **Minification** — Enable for production (`--minify` flag)
|
||||
|
||||
4. **Source maps** — External source maps for production debugging
|
||||
|
||||
5. **Target** — Ensure compatibility with both Bun 1.1+ and Node.js 20+
|
||||
|
||||
### Part B: Handle chunking/splitting
|
||||
|
||||
The full bundle will be large (~2-5 MB minified). Consider:
|
||||
1. **Single file** — Simplest, works everywhere (recommended for CLI tools)
|
||||
2. **Code splitting** — Multiple chunks, only useful if we want lazy loading
|
||||
|
||||
Go with single file unless it causes issues.
|
||||
|
||||
### Part C: Create the executable
|
||||
|
||||
After bundling to `dist/cli.mjs`:
|
||||
|
||||
1. **Add shebang** — `#!/usr/bin/env node` (already in banner)
|
||||
2. **Make executable** — `chmod +x dist/cli.mjs`
|
||||
3. **Test it runs** — `./dist/cli.mjs --version`
|
||||
|
||||
### Part D: Platform packaging
|
||||
|
||||
Create packaging scripts for distribution:
|
||||
|
||||
**npm package** (`scripts/package-npm.ts`):
|
||||
```ts
|
||||
// Generate a publishable npm package in dist/npm/
|
||||
// - package.json with bin, main, version
|
||||
// - The bundled CLI file
|
||||
// - README.md
|
||||
```
|
||||
|
||||
**Standalone binary** (optional, via Bun):
|
||||
```bash
|
||||
bun build --compile src/entrypoints/cli.tsx --outfile dist/claude
|
||||
```
|
||||
This creates a single binary with Bun runtime embedded. Not all features will work, but it's worth testing.
|
||||
|
||||
### Part E: Docker build
|
||||
|
||||
Update the existing `Dockerfile` to produce a runnable container:
|
||||
|
||||
```dockerfile
|
||||
FROM oven/bun:1-alpine AS builder
|
||||
WORKDIR /app
|
||||
COPY package.json bun.lockb* ./
|
||||
RUN bun install --frozen-lockfile || bun install
|
||||
COPY . .
|
||||
RUN bun run build:prod
|
||||
|
||||
FROM oven/bun:1-alpine
|
||||
WORKDIR /app
|
||||
COPY --from=builder /app/dist/cli.mjs /app/
|
||||
RUN apk add --no-cache git ripgrep
|
||||
ENTRYPOINT ["bun", "/app/cli.mjs"]
|
||||
```
|
||||
|
||||
### Part F: Verify production build
|
||||
|
||||
1. `bun run build:prod` succeeds
|
||||
2. `ls -lh dist/cli.mjs` — check file size
|
||||
3. `node dist/cli.mjs --version` — works with Node.js
|
||||
4. `bun dist/cli.mjs --version` — works with Bun
|
||||
5. `ANTHROPIC_API_KEY=... node dist/cli.mjs -p "hello"` — end-to-end works
|
||||
|
||||
### Part G: CI build script
|
||||
|
||||
Create `scripts/ci-build.sh`:
|
||||
```bash
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
echo "=== Installing dependencies ==="
|
||||
bun install
|
||||
|
||||
echo "=== Type checking ==="
|
||||
bun run typecheck
|
||||
|
||||
echo "=== Linting ==="
|
||||
bun run lint
|
||||
|
||||
echo "=== Building ==="
|
||||
bun run build:prod
|
||||
|
||||
echo "=== Verifying build ==="
|
||||
node dist/cli.mjs --version
|
||||
|
||||
echo "=== Done ==="
|
||||
```
|
||||
|
||||
## Verification
|
||||
|
||||
1. `bun run build:prod` produces `dist/cli.mjs`
|
||||
2. The bundle is < 10 MB (ideally < 5 MB)
|
||||
3. `node dist/cli.mjs --version` works
|
||||
4. `docker build .` succeeds (if Docker is available)
|
||||
5. CI script runs end-to-end without errors
|
||||
125
prompts/16-testing.md
Normal file
125
prompts/16-testing.md
Normal file
@@ -0,0 +1,125 @@
|
||||
# Prompt 16: Add Test Infrastructure & Smoke Tests
|
||||
|
||||
## Context
|
||||
|
||||
You are working in `/workspaces/claude-code`. The leaked source does not include any test files or test configuration (they were presumably in a separate directory or repo). We need to add a test framework and write smoke tests for core subsystems.
|
||||
|
||||
## Task
|
||||
|
||||
### Part A: Set up Vitest
|
||||
|
||||
```bash
|
||||
bun add -d vitest @types/node
|
||||
```
|
||||
|
||||
Create `vitest.config.ts`:
|
||||
```ts
|
||||
import { defineConfig } from 'vitest/config'
|
||||
import { resolve } from 'path'
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
globals: true,
|
||||
environment: 'node',
|
||||
include: ['tests/**/*.test.ts'],
|
||||
setupFiles: ['tests/setup.ts'],
|
||||
testTimeout: 30000,
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
'bun:bundle': resolve(__dirname, 'src/shims/bun-bundle.ts'),
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
Create `tests/setup.ts`:
|
||||
```ts
|
||||
// Global test setup
|
||||
import '../src/shims/preload.js'
|
||||
```
|
||||
|
||||
Add to `package.json`:
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"test": "vitest run",
|
||||
"test:watch": "vitest"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Part B: Write unit tests for shims
|
||||
|
||||
`tests/shims/bun-bundle.test.ts`:
|
||||
- Test `feature()` returns `false` for unknown flags
|
||||
- Test `feature()` returns `false` for disabled flags
|
||||
- Test `feature()` returns `true` when env var is set
|
||||
- Test `feature('ABLATION_BASELINE')` always returns `false`
|
||||
|
||||
`tests/shims/macro.test.ts`:
|
||||
- Test `MACRO.VERSION` is a string
|
||||
- Test `MACRO.PACKAGE_URL` is set
|
||||
- Test `MACRO.ISSUES_EXPLAINER` is set
|
||||
|
||||
### Part C: Write smoke tests for core modules
|
||||
|
||||
`tests/smoke/tools.test.ts`:
|
||||
- Test that `getTools()` returns an array
|
||||
- Test that each tool has: name, description, inputSchema
|
||||
- Test that BashTool, FileReadTool, FileWriteTool are present
|
||||
|
||||
`tests/smoke/commands.test.ts`:
|
||||
- Test that `getCommands()` returns an array
|
||||
- Test that each command has: name, execute function
|
||||
- Test that /help and /config commands exist
|
||||
|
||||
`tests/smoke/context.test.ts`:
|
||||
- Test that `getSystemContext()` returns OS info
|
||||
- Test that git status can be collected
|
||||
- Test that platform detection works on Linux
|
||||
|
||||
`tests/smoke/prompt.test.ts`:
|
||||
- Test that `getSystemPrompt()` returns a non-empty array
|
||||
- Test that the prompt includes tool descriptions
|
||||
- Test that MACRO references are resolved (no `undefined`)
|
||||
|
||||
### Part D: Write integration tests (if API key available)
|
||||
|
||||
`tests/integration/api.test.ts`:
|
||||
- Skip if `ANTHROPIC_API_KEY` is not set
|
||||
- Test API client creation
|
||||
- Test a simple message (hello world)
|
||||
- Test streaming works
|
||||
- Test tool use (calculator-style tool call)
|
||||
|
||||
`tests/integration/mcp.test.ts`:
|
||||
- Test MCP server starts
|
||||
- Test MCP client connects
|
||||
- Test tool listing
|
||||
- Test tool execution roundtrip
|
||||
|
||||
### Part E: Write build tests
|
||||
|
||||
`tests/build/bundle.test.ts`:
|
||||
- Test that `dist/cli.mjs` exists after build
|
||||
- Test that it has a shebang
|
||||
- Test that it's not empty
|
||||
- Test that `node dist/cli.mjs --version` exits cleanly
|
||||
|
||||
### Part F: Add pre-commit hook (optional)
|
||||
|
||||
If the project uses git hooks, add:
|
||||
```bash
|
||||
# In package.json or a git hook
|
||||
bun run typecheck && bun run test
|
||||
```
|
||||
|
||||
## Verification
|
||||
|
||||
1. `bun run test` runs all tests
|
||||
2. Shim tests pass
|
||||
3. Smoke tests pass (tools, commands, context, prompts load)
|
||||
4. Integration tests are skipped when no API key is set
|
||||
5. Integration tests pass when API key is available
|
||||
6. Test output is clear and readable
|
||||
26
server.json
26
server.json
@@ -2,33 +2,11 @@
|
||||
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
||||
"name": "io.github.nirholas/claude-code-explorer-mcp",
|
||||
"title": "Claude Code Explorer MCP",
|
||||
"description": "MCP server for exploring the Claude Code CLI source code — browse 40+ tools, 50+ commands, search the full 512K-line codebase, and get architecture overviews.",
|
||||
"description": "Explore the Claude Code CLI source — browse tools, commands, search the 512K-line codebase.",
|
||||
"repository": {
|
||||
"url": "https://github.com/nirholas/claude-code",
|
||||
"source": "github",
|
||||
"subfolder": "mcp-server"
|
||||
},
|
||||
"version": "1.1.0",
|
||||
"packages": [
|
||||
{
|
||||
"registryType": "npm",
|
||||
"registryBaseUrl": "https://registry.npmjs.org",
|
||||
"identifier": "claude-code-explorer-mcp",
|
||||
"version": "1.1.0",
|
||||
"transport": {
|
||||
"type": "stdio"
|
||||
},
|
||||
"runtimeHint": {
|
||||
"commandLine": {
|
||||
"args": []
|
||||
},
|
||||
"env": {
|
||||
"CLAUDE_CODE_SRC_ROOT": {
|
||||
"description": "Path to the Claude Code src/ directory to explore",
|
||||
"required": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
"version": "1.1.0"
|
||||
}
|
||||
|
||||
@@ -202,6 +202,7 @@ const usageReport: Command = {
|
||||
}
|
||||
import oauthRefresh from './commands/oauth-refresh/index.js'
|
||||
import debugToolCall from './commands/debug-tool-call/index.js'
|
||||
import x402 from './commands/x402/index.js'
|
||||
import { getSettingSourceName } from './utils/settings/constants.js'
|
||||
import {
|
||||
type Command,
|
||||
@@ -317,6 +318,7 @@ const COMMANDS = memoize((): Command[] => [
|
||||
usage,
|
||||
usageReport,
|
||||
vim,
|
||||
x402,
|
||||
...(webCmd ? [webCmd] : []),
|
||||
...(forkCmd ? [forkCmd] : []),
|
||||
...(buddy ? [buddy] : []),
|
||||
|
||||
216
src/commands/x402/x402.ts
Normal file
216
src/commands/x402/x402.ts
Normal file
@@ -0,0 +1,216 @@
|
||||
/**
|
||||
* /x402 command implementation
|
||||
*
|
||||
* Manages x402 wallet configuration for HTTP 402 crypto payments.
|
||||
*
|
||||
* Subcommands:
|
||||
* /x402 setup - Generate a new wallet or import an existing private key
|
||||
* /x402 status - Show wallet address, balance, and payment history
|
||||
* /x402 enable - Enable x402 payments
|
||||
* /x402 disable - Disable x402 payments
|
||||
* /x402 set-limit - Set per-request or session spend limits
|
||||
* /x402 network - Switch blockchain network
|
||||
* /x402 remove - Remove wallet and disable payments
|
||||
* /x402 - Show help
|
||||
*/
|
||||
|
||||
import type { LocalCommandCall } from '../../types/command.js'
|
||||
import {
|
||||
generateX402PrivateKey,
|
||||
getX402Config,
|
||||
getX402WalletAddress,
|
||||
isX402Enabled,
|
||||
removeX402PrivateKey,
|
||||
saveX402Config,
|
||||
saveX402PrivateKey,
|
||||
setX402MaxPayment,
|
||||
setX402MaxSessionSpend,
|
||||
setX402Network,
|
||||
type PaymentNetwork,
|
||||
} from '../../services/x402/index.js'
|
||||
import {
|
||||
formatX402Cost,
|
||||
getX402PaymentCount,
|
||||
getX402SessionSpentUSD,
|
||||
} from '../../services/x402/tracker.js'
|
||||
|
||||
const VALID_NETWORKS: PaymentNetwork[] = [
|
||||
'base',
|
||||
'base-sepolia',
|
||||
'ethereum',
|
||||
'ethereum-sepolia',
|
||||
]
|
||||
|
||||
function showHelp(): string {
|
||||
return `x402 — HTTP 402 Crypto Payment Protocol (USDC on Base)
|
||||
|
||||
Usage:
|
||||
/x402 setup Generate a new wallet for x402 payments
|
||||
/x402 setup <key> Import an existing private key (hex)
|
||||
/x402 status Show wallet info and session payment history
|
||||
/x402 enable Enable automatic x402 payments
|
||||
/x402 disable Disable x402 payments
|
||||
/x402 set-limit <amt> Set max payment per request (USD)
|
||||
/x402 set-session <amt> Set max session spend (USD)
|
||||
/x402 network <name> Switch network (base, base-sepolia, ethereum, ethereum-sepolia)
|
||||
/x402 remove Remove wallet and disable payments
|
||||
/x402 Show this help
|
||||
|
||||
When enabled, x402 automatically handles HTTP 402 Payment Required responses
|
||||
by signing USDC payment authorizations within your configured limits.
|
||||
|
||||
Environment:
|
||||
X402_PRIVATE_KEY Override wallet private key (for CI/automation)
|
||||
|
||||
Learn more: https://github.com/coinbase/x402`
|
||||
}
|
||||
|
||||
function handleSetup(args: string): string {
|
||||
const parts = args.trim().split(/\s+/)
|
||||
const keyArg = parts[1]
|
||||
|
||||
if (keyArg) {
|
||||
// Import existing key
|
||||
try {
|
||||
const address = saveX402PrivateKey(keyArg)
|
||||
saveX402Config({ enabled: true })
|
||||
return `Wallet imported and enabled.\nAddress: ${address}\n\nFund this address with USDC on ${getX402Config().network} to enable payments.`
|
||||
} catch (err) {
|
||||
return `Error importing key: ${err instanceof Error ? err.message : String(err)}`
|
||||
}
|
||||
}
|
||||
|
||||
// Generate new key
|
||||
const privateKey = generateX402PrivateKey()
|
||||
const address = saveX402PrivateKey(privateKey)
|
||||
saveX402Config({ enabled: true })
|
||||
|
||||
return `New wallet generated and enabled.
|
||||
Address: ${address}
|
||||
Network: ${getX402Config().network}
|
||||
|
||||
IMPORTANT: Fund this address with USDC to enable payments.
|
||||
Your private key is stored in ~/.claude/config.json
|
||||
|
||||
To use on testnet first: /x402 network base-sepolia`
|
||||
}
|
||||
|
||||
function handleStatus(): string {
|
||||
const config = getX402Config()
|
||||
const address = getX402WalletAddress()
|
||||
const enabled = isX402Enabled()
|
||||
const sessionSpent = getX402SessionSpentUSD()
|
||||
const paymentCount = getX402PaymentCount()
|
||||
|
||||
const lines: string[] = []
|
||||
lines.push('x402 Payment Status')
|
||||
lines.push('─'.repeat(40))
|
||||
lines.push(`Enabled: ${config.enabled ? 'Yes' : 'No'}`)
|
||||
lines.push(`Wallet: ${address ?? 'Not configured'}`)
|
||||
lines.push(`Network: ${config.network}`)
|
||||
lines.push(`Max per request: $${config.maxPaymentPerRequestUSD.toFixed(2)}`)
|
||||
lines.push(`Max per session: $${config.maxSessionSpendUSD.toFixed(2)}`)
|
||||
lines.push(`Ready: ${enabled ? 'Yes' : 'No (need wallet + enabled)'}`)
|
||||
lines.push('')
|
||||
lines.push('Session:')
|
||||
lines.push(` Payments: ${paymentCount}`)
|
||||
lines.push(` Total spent: $${sessionSpent.toFixed(4)}`)
|
||||
|
||||
const x402Summary = formatX402Cost()
|
||||
if (x402Summary) {
|
||||
lines.push('')
|
||||
lines.push(x402Summary)
|
||||
}
|
||||
|
||||
return lines.join('\n')
|
||||
}
|
||||
|
||||
function handleSetLimit(args: string): string {
|
||||
const parts = args.trim().split(/\s+/)
|
||||
const amount = parseFloat(parts[1] ?? '')
|
||||
|
||||
if (isNaN(amount) || amount <= 0) {
|
||||
return 'Usage: /x402 set-limit <amount>\nAmount must be a positive number (USD).\nExample: /x402 set-limit 0.25'
|
||||
}
|
||||
|
||||
try {
|
||||
setX402MaxPayment(amount)
|
||||
return `Max payment per request set to $${amount.toFixed(2)}`
|
||||
} catch (err) {
|
||||
return `Error: ${err instanceof Error ? err.message : String(err)}`
|
||||
}
|
||||
}
|
||||
|
||||
function handleSetSession(args: string): string {
|
||||
const parts = args.trim().split(/\s+/)
|
||||
const amount = parseFloat(parts[1] ?? '')
|
||||
|
||||
if (isNaN(amount) || amount <= 0) {
|
||||
return 'Usage: /x402 set-session <amount>\nAmount must be a positive number (USD).\nExample: /x402 set-session 10.00'
|
||||
}
|
||||
|
||||
try {
|
||||
setX402MaxSessionSpend(amount)
|
||||
return `Max session spend set to $${amount.toFixed(2)}`
|
||||
} catch (err) {
|
||||
return `Error: ${err instanceof Error ? err.message : String(err)}`
|
||||
}
|
||||
}
|
||||
|
||||
function handleNetwork(args: string): string {
|
||||
const parts = args.trim().split(/\s+/)
|
||||
const network = parts[1] as PaymentNetwork | undefined
|
||||
|
||||
if (!network || !VALID_NETWORKS.includes(network)) {
|
||||
return `Usage: /x402 network <name>\nValid networks: ${VALID_NETWORKS.join(', ')}`
|
||||
}
|
||||
|
||||
setX402Network(network)
|
||||
return `Network switched to ${network}`
|
||||
}
|
||||
|
||||
function handleRemove(): string {
|
||||
removeX402PrivateKey()
|
||||
return 'Wallet removed and x402 payments disabled.\nPrivate key has been deleted from config.'
|
||||
}
|
||||
|
||||
export const call: LocalCommandCall = async (_onDone, _context, args) => {
|
||||
const subcommand = (args ?? '').trim().split(/\s+/)[0]?.toLowerCase()
|
||||
|
||||
let value: string
|
||||
|
||||
switch (subcommand) {
|
||||
case 'setup':
|
||||
value = handleSetup(args ?? '')
|
||||
break
|
||||
case 'status':
|
||||
value = handleStatus()
|
||||
break
|
||||
case 'enable':
|
||||
saveX402Config({ enabled: true })
|
||||
value = isX402Enabled()
|
||||
? 'x402 payments enabled.'
|
||||
: 'x402 enabled but no wallet configured. Run /x402 setup first.'
|
||||
break
|
||||
case 'disable':
|
||||
saveX402Config({ enabled: false })
|
||||
value = 'x402 payments disabled.'
|
||||
break
|
||||
case 'set-limit':
|
||||
value = handleSetLimit(args ?? '')
|
||||
break
|
||||
case 'set-session':
|
||||
value = handleSetSession(args ?? '')
|
||||
break
|
||||
case 'network':
|
||||
value = handleNetwork(args ?? '')
|
||||
break
|
||||
case 'remove':
|
||||
value = handleRemove()
|
||||
break
|
||||
default:
|
||||
value = showHelp()
|
||||
}
|
||||
|
||||
return { type: 'text', value }
|
||||
}
|
||||
Reference in New Issue
Block a user