Skip to content

Repository files navigation

BetterClaude

A single-user AI chat workspace with router-selected session styling, resumable NDJSON streaming, conversation branching, interactive UI blocks, and VM-backed tool execution.

Purpose

BetterClaude is a local-first AI assistant interface designed around the idea that different questions deserve different response styles. Instead of a one-size-fits-all chat, every session is classified on first message — selecting both a shape (response structure) and style (tone/voice) from a library of skillpacks. Conversations support branching and forking, so you can explore alternative directions without losing context. An integrated VM space provides real execution capabilities: file I/O, bash, Python, web search, and persistent memory.

The assistant is backed by multiple LLM providers (Anthropic Claude and OpenAI GPT) and streams responses over a resumable NDJSON protocol that survives reconnects.

Architecture

betterclaude/
├── apps/
│   ├── api/               Fastify backend — sessions, streaming, tools, spaces
│   └── web/               React 19 + Vite SPA — chat UI, brain mode, sidebar
├── packages/
│   ├── pi-runtime/        Agent runtime — tool registration, prompt composition, event emission
│   └── ui-catalog/        JSON-render component registry + Zod validation schemas
├── shared/                TypeScript contracts shared between API and web
├── docs/                  Phase-by-phase implementation specs
└── scripts/               Dev tooling (startup scripts)

Tech stack

Layer Technology
Backend Fastify, TypeScript, SQLite + Drizzle ORM
Frontend React 19, Vite 7, React Router v7
Agent runtime pi-agent-core, pi-ai
UI rendering json-render + shadcn component catalog
Data viz Recharts (charts), Leaflet (maps), TanStack Table
Search Exa Web Search API
Session routing Cerebras API (fast classification)
VM execution OrbStack (macOS) — per-user Linux space
Package manager pnpm workspaces

Data model

Sessions, branches, and entries form a tree:

Session (model, title, router decision)
  └─ Branch (root entry, leaf entry)
       └─ Entry (role, content, parent → child chain)
            └─ Run (status, model, token usage, memory access log)

Entries link via parentEntryId, enabling transcript reconstruction by walking from any branch's leaf back to its root. Forking creates a new branch that shares parent entries up to the fork point.

Stream protocol

Chat responses stream over POST /v1/chat/stream as newline-delimited JSON. Event types:

  • delta — incremental text tokens
  • thinking_start / thinking_delta / thinking_end — extended thinking
  • tool_start / tool_progress / tool_end — tool execution lifecycle
  • ui / ui_patch — interactive UI block specs
  • sync — reconnect recovery (textSoFar + sequence number)
  • final — completion with metadata
  • error / ping — error reporting and keepalive

On reconnect, clients pass the last runId to receive a sync event with buffered state, enabling seamless resumption.

Features

Session routing and skillpacks

On the first message of every session, a fast classifier (Cerebras) selects:

  • Shape skillpack — controls response structure (e.g., "Balanced Answer", "Deep Dive")
  • Style skillpack — controls tone and voice (e.g., "Professional", "Warm")
  • Voice and emotion profiles — JSON personality descriptors locked for session lifetime

Skillpacks are Markdown files with YAML frontmatter, stored in apps/api/skillpacks/ and hot-reloaded into SQLite via Chokidar. The router runs once per session; all subsequent messages inherit the locked style.

Conversation branching

  • Fork from any entry to create a new branch exploring an alternative direction
  • Branches share parent history up to the fork point — no duplication
  • Each branch maintains independent leaf state and run history
  • Branch tabs in the UI allow switching between parallel explorations

Explore options

Every assistant response includes contextual follow-up suggestions (2-4 options) generated via the response_meta_emit tool. Options are grounded in the specific content of the turn — not generic prompts — and branch the conversation in genuinely different directions.

Interactive UI blocks

The assistant can emit structured UI components inline:

  • Tables — sortable, filterable, with column definitions
  • Charts — line, bar, area, pie via Recharts
  • Maps — markers, polylines, polygons via Leaflet
  • Cards, badges, lists, buttons — general layout primitives

UI blocks are defined as JSON specs (json-render format) and rendered client-side with the shadcn-based catalog. Buttons can trigger actions that feed back into the conversation.

Brain mode

The default landing view — an infinite chronological timeline of all sessions. New messages are routed intelligently: the brain resolver decides whether to create a new session or continue an existing one based on content classification.

VM-backed tool execution

Each user gets an OrbStack Linux VM ("space") with:

  • File operations — read, write, edit files in /home/space/
  • Bash execution — full shell access with Python, DuckDB, Polars
  • Public file serving — nginx serves /home/space/public/ for generated assets
  • File upload/download — via API endpoints
  • Skills index — auto-generated SKILLS.md listing available CLI tools

Memory system

  • Documents written to the space are chunked and indexed into SQLite FTS5
  • memory_get retrieves specific documents by path
  • memory_search performs full-text search across all memory
  • Memory access is logged per-run for observability
  • Manual consolidation via the /v1/sleep endpoint

Multi-model support

Sessions can target different LLM backends:

  • Anthropic — Claude Opus 4.5
  • OpenAI — GPT 5.2

Model selection is per-session and can be changed between runs.

API overview

Endpoint Description
POST /v1/sessions Create session with model
GET /v1/sessions List sessions (paginated)
GET /v1/sessions/:id Get session + branches
POST /v1/chat/stream Send message, stream response (NDJSON)
POST /v1/runs/:id/cancel Cancel active run
POST /v1/branches Fork branch from entry
GET /v1/branches/:id/entries Get transcript (root to leaf)
POST /v1/brain/resolve-target Route message to new or existing session
GET /v1/brain/sessions List all sessions for brain timeline
GET /v1/brain/space/files Browse space filesystem
POST /v1/brain/space/uploads Upload file to space
GET /v1/brain/space/download Download file from space
POST /v1/sleep Trigger memory consolidation
GET /v1/models List available models

Getting started

Prerequisites

  • Node.js >= 20
  • pnpm (corepack enable && corepack prepare)
  • OrbStack (macOS, for VM space features)

Environment

Copy apps/api/.env.example to apps/api/.env and fill in:

  • ANTHROPIC_API_KEY — for Claude models
  • OPENAI_API_KEY — for GPT models
  • CEREBRAS_API_KEY — for session routing
  • EXA_API_KEY — for web search

Install and run

pnpm install
pnpm db:migrate
pnpm dev

This starts both services:

  • API: http://localhost:8787
  • Web: http://localhost:5173

Other commands

pnpm dev:api       # API only
pnpm dev:web       # Web only
pnpm typecheck     # Type-check all packages
pnpm lint          # Lint with oxlint
pnpm db:seed       # Seed database (optional)

Project structure

apps/api/src/
  ├── config/           Constants, base system prompt
  ├── db/               Drizzle schema, migrations, seed
  ├── routes/           Fastify route handlers
  ├── runs/             Chat runner orchestration
  ├── services/         Session router, skillpack sync
  └── spaces/           VM space management, tooling, settings

apps/web/src/
  ├── components/
  │   ├── brain/        Brain mode timeline, space settings, file browser
  │   ├── chat/         Transcript, message bubbles, streaming, UI blocks
  │   └── sidebar/      Session list, navigation
  ├── hooks/            Zustand stores (session, branch, stream, brain)
  └── lib/              API client, markdown rendering

packages/pi-runtime/    Agent creation, tool schemas, prompt composition
packages/ui-catalog/    Component registry, Zod validation, json-render integration
shared/src/contracts/   TypeScript types shared across API and web

About

Experimental chat behaviors

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages