Post

I Built ShellAgent: An Open-Source Terminal Inspired by Claude Code's Leaked Source

Yesterday the Claude Code CLI source leaked — 512K lines of TypeScript. I analyzed the internals and wrote about the architecture, the custom terminal renderer, the streaming tool executor, and all the unreleased features hiding behind compile-time flags.

Today I built my own version.

ShellAgent

ShellAgent is an open-source interactive terminal inspired by Claude Code. ~1,100 lines of TypeScript. You type a request, the AI streams a response, calls tools when needed, and loops until done.

ShellAgent running in the terminal ShellAgent with the MockProvider — streaming responses, tool calls, and a status bar.

The key idea: bring your own API. ShellAgent ships with a mock provider for demo, but the Provider interface is designed so you can swap it for Anthropic, OpenAI, or any custom REST API in about 30 lines of code.

What I Took from Claude Code

I vibe-coded the whole thing with Claude Code itself, using patterns I found in the leaked source:

Async generators for the query loop. Claude Code’s query.ts is an async generator that yields stream events. ShellAgent does the same — the provider streams events, the query engine consumes them, executes tools, and loops. Natural backpressure, easy to reason about.

Streaming tool execution. Tools start running as the API response streams in. Read-only tools marked isConcurrencySafe run in parallel. Destructive tools (Bash, WriteFile) run serially and ask permission first.

Subscription-based state store. Claude Code uses a simple createStore pattern — no Redux, no Zustand, just getState, setState, subscribe in 23 lines. I ported it directly.

Tool protocol with Zod validation. Each tool defines a Zod schema for its input, an execute function, and metadata flags (isReadOnly, needsPermission, isConcurrencySafe). Clean separation between tool logic and UI rendering.

What I Left Out

Claude Code is 512K lines. ShellAgent is 1,100. The difference:

  • No custom terminal renderer — ShellAgent uses the npm ink package instead of building a React reconciler from scratch
  • No ML permission classifier — just a simple boolean needsPermission flag per tool
  • No multi-agent coordination, no session persistence, no prompt caching
  • No feature gates or dead-code elimination — it’s one build, everything included

The goal isn’t to clone Claude Code. It’s to extract the core patterns into something anyone can pick up, understand, and build on.

The Provider Interface

This is the swap point — the one abstraction that makes ShellAgent useful for real projects:

1
2
3
4
5
6
7
8
interface Provider {
  name: string
  chat(
    messages: Message[],
    tools: ToolDefinition[],
    signal?: AbortSignal,
  ): AsyncGenerator<StreamEvent>
}

Implement that, and you have a working agentic terminal. The README includes examples for Anthropic and OpenAI.

Try It

1
2
3
4
git clone https://github.com/victorantos/shellagent
cd shellagent
npm install
npx tsx src/index.tsx

The mock provider responds to natural language — try “read package.json”, “search for TODO”, or “weather in Zurich”.

GitHub: github.com/victorantos/shellagent

License: GPL-3.0.

This post is licensed under CC BY 4.0 by the author.
SpaceX Launch Countdowns Starship Flight 12 Countdown