How the pi-web Project Structure Powers the π AI Agent Framework
The pi-web project structure follows a clear separation between Next.js frontend components, server-side API routes, and shared TypeScript utilities to implement a full-stack web UI for the π AI agent framework.
The pi-web repository (agegr/pi-web) delivers a comprehensive web interface for interacting with the π AI agent framework. Its architecture enforces strict boundaries between client-side React components, server logic, and core libraries, enabling secure file browsing and hot-reload-safe session management. Understanding the pi-web project structure reveals how the codebase orchestrates complex agent lifecycles while maintaining extensibility for custom plugins and skills.
Top-Level Directory Organization
The repository root organizes code into distinct functional zones that separate concerns between the frontend, backend, and tooling:
app/– Contains the Next.js "app router" implementation, including page components (page.tsx,layout.tsx), global styles (globals.css), and the Progressive Web App manifest (manifest.ts).components/– Houses reusable React UI pieces such asChatWindow,SessionSidebar, file explorers, markdown renderers, and configuration dialogs.hooks/– Provides custom React hooks includinguseAgentSessionfor managing agent connections,useAudiofor voice interactions, and viewport management utilities.lib/– Core TypeScript utilities shared between client and server, handling session management (rpc-manager.ts), file access security, worktree resolution, and tool-call normalization.public/– Static assets including service-worker scripts, offline pages, and application icons.bin/– Node.js CLI scripts (pi-web.js) that handle option parsing and Node version verification.docs/– Markdown documentation covering worktree handling, internationalization, and release notes.AGENTS.md– High-level design documentation describing the architecture, session lifecycle, and implementation details.
Core Architecture Components
AgentSession Lifecycle Management
Session persistence and state management are centralized in lib/rpc-manager.ts. This module maintains a global registry (globalThis.__piSessions) that stores session wrappers by ID, ensuring sessions survive Next.js hot-reloads during development. The implementation handles idle timeouts, prevents concurrent session starts with locking mechanisms, and manages cleanup after process forks.
Server-Side API Routes
All backend functionality resides under app/api/ as Next.js API routes. These endpoints expose:
- Session browsing via
GET /api/sessionsandGET /api/sessions/[id] - Agent creation through
POST /api/agent/new(defined inapp/api/agent/new/route.ts) - Command execution via
POST /api/agent/[id] - Event streaming through
GET /api/agent/[id]/eventsusing Server-Sent Events (SSE) - Worktree management at
/api/worktrees - Plugin and skill handling, authentication, and model configuration endpoints
These routes leverage shared helpers in lib/ for path normalization, file-access security, and π SDK integration.
Frontend UI Layer
The user interface is built from modular React components orchestrated by custom hooks:
components/AppShell.tsxserves as the main layout container hostingSessionSidebar(session file trees) andChatWindow(message streaming).hooks/useAgentSession.tsmanages SSE connections, polling for active sessions, and state reconciliation after page visibility changes.components/ChatInput.tsxandcomponents/ChatMinimap.tsxprovide message composition and conversation navigation.components/MarkdownBody.tsxrenders assistant messages with support for Mermaid diagrams and front-matter cards.
Worktree and File Security
The project implements strict file access controls through lib/worktree.ts and lib/file-access.ts. The worktree resolver maps git worktrees to UI sessions, allowing simultaneous work on multiple branches. File access enforces an allow-list restricting reads to the session working directory, project roots, and ~/pi-cwd-* paths, protecting the underlying filesystem when serving content via GET /api/files/[...path].
Tool Call Normalization
Incoming tool-call payloads from the π framework use a different schema than the UI expects. The lib/normalize.ts utility converts between these formats, processing data both when loading historical session files (session-reader.ts) and handling live streaming events.
Implementation Examples
The following snippets demonstrate typical interactions with the pi-web architecture from frontend components.
Starting a new agent session requires invoking the RPC manager with configuration options:
import { startRpcSession } from '@/lib/rpc-manager';
async function createSession(cwd: string, message: string) {
const session = await startRpcSession({
cwd,
initialMessage: message,
toolNames: ['readFile', 'writeFile'], // optional tool allow‑list
});
return session.id; // session id can be used with other API routes
}
React components interact with active sessions through the useAgentSession hook, which abstracts SSE streaming and command sending:
import { useAgentSession } from '@/hooks/useAgentSession';
function Chat({ sessionId }: { sessionId: string }) {
const { state, send } = useAgentSession(sessionId);
const handleSend = async (text: string) => {
await send({ cmd: 'message', content: text });
};
return (
<>
<ChatWindow messages={state.messages} />
<ChatInput onSend={handleSend} disabled={state.isStreaming} />
</>
);
}
File contents are retrieved through the secure API layer using the agent client utilities:
import { fetch } from '@/lib/agent-client';
async function loadFile(path: string) {
const response = await fetch(`/api/files/${encodeURIComponent(path)}`);
const { content } = await response.json();
return content;
}
Summary
- The pi-web project structure separates Next.js frontend code (
components/,hooks/,app/) from server-side API routes (app/api/) and shared utilities (lib/). - Session management relies on
lib/rpc-manager.tsto maintain persistent agent connections across hot-reloads usingglobalThis.__piSessions. - Security is enforced through
lib/file-access.ts, which restricts file system access to allowed directories and git worktrees. - API routes handle session lifecycle, streaming events, and worktree operations while delegating business logic to shared library functions.
- Tool normalization in
lib/normalize.tsbridges the gap between π framework payloads and UI expectations.
Frequently Asked Questions
What is the role of lib/rpc-manager.ts in the pi-web project structure?
The lib/rpc-manager.ts file serves as the central nervous system for agent session management. It exports startRpcSession to initialize new sessions and maintains a global registry (globalThis.__piSessions) that preserves session state across Next.js hot-reloads. This module handles critical lifecycle concerns including idle timeouts, concurrent start prevention, and cleanup after session forks.
How does pi-web ensure secure file access?
Security is implemented through lib/file-access.ts, which enforces an allow-list restricting file reads to specific paths: the current session working directory, configured project roots, and temporary ~/pi-cwd-* directories. This prevents the UI from accessing sensitive system files when rendering file contents via the /api/files/[...path] endpoint, while lib/worktree.ts safely resolves git worktree mappings.
Which frontend technologies power the pi-web interface?
The frontend is built on Next.js using the App Router architecture, with React components organized in components/ and state management handled through custom hooks in hooks/. Key UI elements include ChatWindow for message rendering, SessionSidebar for file navigation, and useAgentSession for managing Server-Sent Event streams and polling logic.
Where are server-side endpoints defined in the pi-web codebase?
All API endpoints reside under app/api/ following Next.js conventions. Critical routes include app/api/agent/new/route.ts for session creation, app/api/agent/[id]/route.ts for command execution, and app/api/sessions/route.ts for session listing. These routes import utilities from lib/ to handle file system operations, worktree resolution, and π SDK interactions.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →