claude-code-skill
Development conventions and architecture guide for the Claude Code CLI repository.
install
source · Clone the upstream repo
git clone https://github.com/codeaashu/claude-code
Claude Code · Install into ~/.claude/skills/
git clone --depth=1 https://github.com/codeaashu/claude-code ~/.claude/skills/codeaashu-claude-code-claude-code-skill
manifest:
Skill.mdsource content
Claude Code — Repository Skill
Project Overview
Claude Code is Anthropic's CLI tool for interacting with Claude from the terminal. It supports file editing, shell commands, git workflows, code review, multi-agent coordination, IDE integration (VS Code, JetBrains), and Model Context Protocol (MCP).
Codebase: ~1,900 files, 512,000+ lines of TypeScript under
src/.
Tech Stack
| Component | Technology |
|---|---|
| Language | TypeScript (strict mode, ES modules) |
| Runtime | Bun (JSX support, feature flags) |
| Terminal UI | React + Ink (React for CLI) |
| CLI Parser | Commander.js () |
| API Client | |
| Validation | Zod v4 |
| Linter/Formatter | Biome |
| Analytics | GrowthBook (feature flags & A/B testing) |
| Protocol | Model Context Protocol (MCP) |
Architecture
Directory Map (src/
)
src/| Directory | Purpose |
|---|---|
| ~50 slash commands (, , , etc.) |
| ~40 agent tools (Bash, FileRead, FileWrite, Glob, Grep, etc.) |
| ~140 Ink/React UI components for terminal rendering |
| External integrations (API, OAuth, MCP, LSP, analytics, plugins) |
| Bidirectional IDE communication layer |
| React context + custom store (AppState) |
| React hooks (permissions, keybindings, commands, settings) |
| TypeScript type definitions |
| Utilities (shell, file ops, permissions, config, git) |
| Full-screen UIs (Doctor, REPL, Resume, Compact) |
| Bundled skills + skill loader system |
| Plugin system (marketplace + bundled plugins) |
| Multi-agent coordination & supervisor logic |
| Task management (shell tasks, agent tasks, teammates) |
| React context providers (notifications, stats, FPS) |
| Persistent memory system (CLAUDE.md, user/project memory) |
| Initialization logic, Agent SDK, MCP entry |
| Voice input/output (STT, keyterms) |
| Vim mode keybinding support |
| Zod configuration schemas |
| Keybinding configuration & resolver |
| Config migrations between versions |
| Output formatting & theming |
| Query pipeline & processing |
| Server/daemon mode |
| Remote session handling |
Key Files
| File | Role |
|---|---|
| CLI entry point (Commander parser, startup profiling) |
| Core LLM API caller (streaming, tool-call loops) |
| Tool type definitions & factory |
| Tool registry & presets |
| Command registry |
| System/user context collection (git status, memory) |
| Token cost tracking |
Entry Points & Initialization Sequence
— Commander CLI parser, startup profilingsrc/main.tsx
— Config, telemetry, OAuth, MDMsrc/entrypoints/init.ts
— CLI session orchestrationsrc/entrypoints/cli.tsx
— MCP server modesrc/entrypoints/mcp.ts
— Agent SDK (programmatic API)src/entrypoints/sdk/
— REPL session launchersrc/replLauncher.tsx
Startup performs parallel initialization: MDM policy reads, Keychain prefetch, feature flag checks, then core init.
Patterns & Conventions
Tool Definition
Each tool lives in
src/tools/{ToolName}/ and uses buildTool:
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:
{ToolName}.ts or .tsx (main), UI.tsx (rendering), prompt.ts (system prompt), plus utility files.
Command Definition
Commands live in
src/commands/ and follow three types:
- PromptCommand — Sends a formatted prompt with injected tools (most commands)
- LocalCommand — Runs in-process, returns text
- LocalJSXCommand — Runs in-process, returns React JSX
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
Commands are registered in
src/commands.ts and invoked via /command-name in the REPL.
Component Structure
- Functional React components with Ink primitives (
,Box
,Text
)useInput() - Styled with Chalk for terminal colors
- React Compiler for optimized re-renders
- Design system primitives in
src/components/design-system/
State Management
via React context + custom store (AppState
)src/state/AppStateStore.ts- Mutable state object passed to tool contexts
- Selector functions for derived state
- Change observers in
src/state/onChangeAppState.ts
Permission System
- Modes:
(prompt per operation),default
(show plan, ask once),plan
(auto-approve),bypassPermissions
(ML classifier)auto - Rules: Wildcard patterns —
,Bash(git *)FileEdit(/src/*) - Tools implement
returningcheckPermissions(){ granted: boolean, reason?, prompt? }
Feature Flags & Build
Bun's
bun:bundle feature flags enable dead-code elimination at build time:
import { feature } from 'bun:bundle' if (feature('PROACTIVE')) { /* proactive agent tools */ }
Notable flags:
PROACTIVE, KAIROS, BRIDGE_MODE, VOICE_MODE, COORDINATOR_MODE, DAEMON, WORKFLOW_SCRIPTS.
Some features are also gated via
process.env.USER_TYPE === 'ant'.
Naming Conventions
| Element | Convention | Example |
|---|---|---|
| Files | PascalCase (exports) or kebab-case (commands) | , |
| Components | PascalCase | , |
| Types | PascalCase, suffix with Props/State/Context | |
| Hooks | prefix | , |
| Constants | SCREAMING_SNAKE_CASE | , |
Import Practices
- ES modules with
extensions (Bun convention).js - Lazy imports for circular dependency breaking:
const getModule = () => require('./heavy.js') - Conditional imports via feature flags or
process.env
markers for manual import ordering where neededbiome-ignore
Services
| Service | Path | Purpose |
|---|---|---|
| API | | Anthropic SDK client, file uploads |
| MCP | | MCP client, tool/resource discovery |
| OAuth | | OAuth 2.0 auth flow |
| LSP | | Language Server Protocol manager |
| Analytics | | GrowthBook, telemetry, events |
| Plugins | | Plugin loader, marketplace |
| Compact | | Context compression |
| Policy Limits | | Org rate limits, quota checking |
| Remote Settings | | Managed settings sync (Enterprise) |
| Token Estimation | | Token count estimation |
Configuration
Settings locations:
- Global:
,~/.claude/config.json~/.claude/settings.json - Project:
,.claude/config.json.claude/settings.json - System: macOS Keychain + MDM, Windows Registry + MDM
- Managed: Remote sync for Enterprise users
Guidelines
- Read relevant source files before making changes — understand existing patterns first.
- Follow the tool/command/component patterns above when adding new ones.
- Keep edits minimal and focused — avoid unnecessary refactoring.
- Use Zod for all input validation at system boundaries.
- Gate experimental features behind
feature flags or env checks.bun:bundle - Respect the permission system — tools that modify state must implement
.checkPermissions() - Use lazy imports when adding dependencies that could create circular references.
- Update this file as project conventions evolve.