The Problem
Building an AI coding agent from scratch is hard because production agents like pi are dense with engineering detail that obscures the core data flow. Most tutorials either over-simplify or drown the reader in abstractions. This project strips pi down to its essence—a ~600-line TypeScript agent that can read files, edit code, and run commands—and teaches it through a guided, interactive article.
What This Does
This is a dual-purpose repository: a minimal, runnable coding agent (src/) and an interactive educational website (web/) that walks you through building it step-by-step. The agent itself is a functional CLI tool using an OpenAI-compatible API. The website pairs the article text with a live code editor that fills in as you read, plus a trace debugger (web/app/TraceLab.tsx) with breakpoints to step through the agent's execution.
The core agent is deliberately small. src/agent.ts exposes runAgent, src/llm.ts handles streaming and tool calls, src/tools.ts provides built-in file/command tools, and src/cli.ts is the entry point. The web/ app is a Next.js site with pre-generated trace data (web/app/trace-data.generated.ts), so browsing the site makes no model calls.
How It Is Wired
Execution starts at main in src/cli.ts:23, which reaches 11 functions. It loads a session via loadSession (a fs.readFile call on the filesystem) and then runAgent enters the loop. The agent's core loop in src/agent.ts calls stream in src/llm.ts, which handles OpenAI-compatible streaming and tool-call flushing.
The most-connected modules are src/llm (imported by 7 files, imports nothing) and src/agent (imported by 6 files, imports 1). These are the hubs—change them and the most breaks. The call graph shows buildDebugFrames calling push 107 times, making it the hottest internal path for trace generation. src/tools.ts is the only module that reads/writes files in the agent path.
The repo has 30 internal modules with 33 import edges and zero circular dependencies—a clean, acyclic graph that's easy to reason about. The web/ app is where complexity concentrates: Reader.tsx has 24 functions and trace-data.generated.ts is a 1,566-line generated file.
How To Use It
Setup (needs Node.js 22+ and an OpenAI-compatible API):
npm install
export NANOPI_API_KEY=your-api-key
npm run dev
Configuration: Optional env vars are NANOPI_MODEL and NANOPI_BASE_URL (defaults to https://api.openai.com/v1).
Running the teaching site:
cd web
npm install
npm run dev
Real-World Use
This fits as a learning tool or a minimal base for a custom agent. You can extend src/tools.ts with domain-specific tools and src/llm.ts to swap providers. The trace system (web/app/trace-debugger.ts) is genuinely useful for debugging agent loops—you can visualize exactly what the agent sees at each step, which is invaluable when building more complex agents.
Code Health & Issues
Static analysis found 7 issues (1 high, 6 medium). The high finding is an oversized file: web/app/trace-data.generated.ts at 1,566 lines. Two medium findings flag high branching density in src/llm.ts, web/app/NudgeCounter.tsx, and web/app/trace-debugger.ts. Two medium findings flag deep nesting in Reader.tsx and TraceLab.tsx (max indentation depth 7).
SDLC observations: tests exist (8 test files) but there's no CI pipeline, no Dependabot/Renovate config, and no .editorconfig/formatter config. License and lockfiles are present. No committed secrets detected.
The Bottom Line
A well-structured, honest educational project with a genuinely minimal agent and a clever interactive teaching site. The clean module graph and absence of circular dependencies make it easy to extend. The web/ app has some readability debt in its largest files, but the core agent code is small and approachable. Ideal for developers wanting to understand agent internals or build a custom agent from a solid, minimal base.