CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
Dash UI is the Next.js frontend for the Dash data agent. It provides a chat interface for data analysis — fetch URLs, query databases, run Python/R, and create charts. Works with any data source, not just SQL.
Commands
# Install dependencies
npm install
# Run development server (port 3000)
npm run dev
# Build for production
npm run build
# Start production server
npm start
Note: The backend API server (FastAPI) must be running on port 8000. See ../dash-repo/ for backend setup.
Architecture
Single-Page Application
The entire UI is in app/page.js (~1750 lines). Key sections:
| Lines | Component | Purpose |
|---|---|---|
| 1-90 | Utilities | extractChart(), extractD3Chart(), renderMarkdown() |
| 90-270 | Chart Components | ChartImage, D3Chart, ImageModal |
| 270-400 | UI Components | Icons, CopyableCode, CodeBlockItem |
| 400-630 | CodePanel | Slide-out panel showing all executed code, export to .py/.R/.ipynb |
| 630-660 | ContextBox | Collapsible plain text box for data dictionaries/readmes |
| 660-780 | ToolCall | Collapsible tool execution display (SQL, Python, R) |
| 780-940 | Message Components | Message, StreamingMsg with inline charts |
| 940-1750 | Home (main) | State management, SSE streaming, chat flow, sidebar, Kaggle/TidyTuesday tabs |
Data Flow
User Input → POST /chat/stream → SSE Events → UI Updates
↓
tool_start → ToolCall (running)
tool_complete → ToolCall (result) + inline Chart
delta → Streaming text
done → Finalize message
State Management
// In Home component
const [messages, setMessages] = useState([]) // Chat history
const [streamEvents, setStreamEvents] = useState([]) // Current streaming response
const [language, setLanguage] = useState('python') // Python or R preference
const [conversationId, setConversationId] = useState(null) // Current conversation UUID
const sessionIdRef = useRef(generateSessionId()) // Backend session ID (= conversationId)
Session Isolation
Each conversation gets its own backend session — no cross-contamination:
sessionIdRef.currentis set toconversationIdwhen a conversation is created or loaded- New conversation: generates a fresh
sessionIdRef, creates a new conversation viaPOST /conversations - Load old conversation: sets
sessionIdRef.current = convId, calls/restoreto rebuild agent history - Switch conversations: different sessionId = different backend
DashAgentinstance
Message Format
// User message
{ role: 'user', content: 'Who won most championships?' }
// Assistant message with events (tools + context + text interleaved)
{
role: 'assistant',
events: [
{ type: 'tool', tool: { name: 'run_sql', args: {...}, result: '...' } },
{ type: 'context', title: 'Data dictionary', content: '...' }, // collapsible plain text box
{ type: 'text', content: 'Based on the data...' }
]
}
Conversations & Permalinks
- Sidebar lists saved conversations via
GET /conversations - Clicking a conversation loads it, restores backend agent history, and updates URL to
?c=<uuid> - Refreshing or sharing the URL reopens the same conversation
- New conversations get a URL permalink after the first message is sent
- "New conversation" generates a fresh session and clears URL back to
/ - Titles are auto-generated by Haiku on the backend after the first user message
Key Features
Chart Rendering
Charts are embedded in tool results using markers:
- Matplotlib/ggplot2:
[CHART_BASE64]<base64>[/CHART_BASE64]→ renders as<img> - D3.js:
[D3_CHART]{"code":"...","data":[...]}}[/D3_CHART]→ renders in sandboxed iframe
Code Panel
Right sidebar shows all executed code (SQL, Python, R) with:
- Individual copy buttons per block
- Export to
.pyor.Rfile with boilerplate (DB setup, imports) - Export to
.ipynbJupyter notebook with user/AI markdown cells, code cells, and captured outputs (text results + base64 chart images) - Language auto-detection based on tools used
Language Toggle
On home screen, user selects Python or R. This:
- Sends
languagefield in API request - Updates CodePanel export format
- Backend prepends
[USER PREFERS R]to guide tool selection
Dataset Browser (Kaggle & TidyTuesday)
Home screen has three tabs: Presets | Kaggle Datasets | TidyTuesday.
- Kaggle tab: Searchable, sortable grid of dataset cards fetched via
GET /kaggle/datasetsbackend proxy. Supports pagination ("Load more"). - TidyTuesday tab: Year-selectable list of weekly datasets from the R4DS GitHub repo via
GET /tidytuesday/datasets. - Instant-load flow: Clicking a dataset card calls
POST /kaggle/loadorPOST /tidytuesday/load. The backend downloads + explores data directly in CodeInterpreter (no Claude API call), fabricates a conversation with tool events, seeds agent history, and returns pre-populated messages. The frontend sets these as the conversation — user sees results instantly. contextevent type: Dataset descriptions/readmes are returned as{type: 'context', title, content}events, rendered byContextBoxas a collapsible plain text box (no markdown rendering).
API Integration
// Streaming chat (SSE) — session_id ties to conversation
fetch('http://localhost:8000/chat/stream', {
method: 'POST',
body: JSON.stringify({ message, session_id: sessionIdRef.current, language })
})
// Restore agent history when loading a conversation
fetch('http://localhost:8000/restore', {
method: 'POST',
body: JSON.stringify({ session_id: convId, messages })
})
SSE Event Types
| Event | Action |
|---|---|
tool_start | Add collapsible ToolCall in "running" state |
tool_complete | Update ToolCall with result, extract/render charts |
delta | Append to streaming text content |
done | Finalize message, save to backend, refresh sidebar |
error | Display error message |
Styling
- Framework: Tailwind CSS v4 with
@tailwindcss/postcss - Theme: Light/dark mode via CSS custom properties (
--ink,--bg,--red, etc.) and@media (prefers-color-scheme: dark) - Fonts: Newsreader (serif display), Outfit (sans body), JetBrains Mono (code)
- Layout: Max-width 3xl centered, responsive code panel, collapsible sidebar
- User message selection: Uses
[data-user-msg]attribute selector inglobals.cssfor visible text selection on dark bubbles (Tailwind v4 purges class-based selectors from CSS files)
File Structure
dash-ui/
├── app/
│ ├── page.js # All UI components and logic (~1750 lines)
│ ├── layout.js # Root layout, metadata, font loading
│ └── globals.css # Design tokens, dark mode, prose styling, animations
├── package.json # Dependencies: next, react 19, tailwindcss v4
├── postcss.config.js # PostCSS with @tailwindcss/postcss
└── tailwind.config.js
Related Documents
Claude AI Git Workflow Integration
When working with git repositories and suggesting commit workflows, always recommend using the `git-ai-commit` CLI tool for creating commit messages.
Code indexing for AI agents: summarization strategies and evaluation systems
**The most effective code indexing systems combine hierarchical LLM-generated summaries with AST structural data and vector embeddings through hybrid retrieval—achieving up to 80% codebase reduction while maintaining high accuracy for AI coding agents.** Leading tools like Cursor, Sourcegraph Cody, and Continue.dev demonstrate that no single retrieval method suffices; production systems require semantic search, keyword matching, and structural queries working together. For evaluation, the field
Missing Business Agents Research — FLUXION 2026
> Deep Research CoVe 2026 | Date: 2026-03-23
write-script
Write a full video script for @SketchySurvival101 following all rules in CLAUDE.md.