# Investibook — Code Structure

## Architecture

Investibook is a **workspace-based AI research platform** with a NotebookLM-style three-column layout (Sources | Chat | Studio). It consists of two services:

- **Frontend** — Next.js 16 App Router (`frontend/app/`), React 18, TypeScript. Uses `@tidbcloud/uikit` (Mantine-based) as primary UI library alongside Ant Design for specific widgets (e.g., `Button` in workspace header). Styled with inline styles (not CSS modules or Tailwind utility classes in components).
- **Backend** — Python FastAPI (`backend/investibook/main.py`) with a pluggable agent runtime layer. OpenCode/Claude use **ACP (Agent Client Protocol)** and Pi uses JSONL RPC; all transports normalize events to **SSE (Server-Sent Events)**.

### Key data flow

1. User sends a message -> `ChatPanel` opens an `EventSource` to `GET /api/chat/stream?message=...&session_id=...`
2. Backend spawns/reuses the selected agent runtime, forwards the prompt, and normalizes runtime events into flat SSE JSON objects
3. Frontend parses SSE events (`text`, `thought`, `tool`, `complete`, `error`) defined in `frontend/components/ChatPanel/types.ts` and renders them as interleaved message parts

### State management

All client-side state flows through `WorkspaceProvider` (`frontend/lib/workspace.tsx`) — a React Context providing sources, artifacts, and view state. **Persistence is in the backend** (SQLite at `DATA_DIR/db/investibook.db`); `frontend/lib/workspace.tsx` and `frontend/lib/workspaces.ts` make REST API calls to read/write. Only the auth token (`investibook_token`) and email are stored in browser `localStorage` via `frontend/lib/auth.ts`.

## Project Layout

| Path | Purpose |
|------|---------|
| `frontend/app/page.tsx` | Home page — workspace list/create |
| `frontend/app/workspace/[id]/page.tsx` | Workspace detail — three-column layout |
| `frontend/lib/workspace.tsx` | `WorkspaceProvider` context + types (`Source`, `Artifact`, `SourceType`) |
| `frontend/lib/workspaces.ts` | REST CRUD helpers for workspace metadata (`/api/workspaces`) |
| `frontend/lib/auth.ts` | `fetchWithAuth()` wrapper + token storage (`investibook_token` in localStorage) |
| `frontend/lib/types.ts` | Domain types for insight/diagnostic data (`InsightData`, `Metric`, etc.) |
| `frontend/components/ChatPanel/` | SSE-based chat with ACP backend |
| `frontend/components/SourcesPanel/` | Source management + file tree browser |
| `frontend/components/StudioPanel/` | Artifact list/detail view, renders `InsightReport` and `AnomaliesPanel` |
| `frontend/components/InsightReport/` | Rich diagnostic report (metrics, events, summaries) |
| `backend/investibook/main.py` | FastAPI app — thin wiring: registers routers, middleware, lifespan |
| `backend/investibook/api/` | Route handlers by domain: `auth.py`, `workspaces.py`, `chat.py`, `sources.py`, `files.py`, `admin.py` |
| `backend/investibook/core/` | Business logic: `agent_runtime.py` (runtime registry, sessions, event bridge, ACP/Pi adapters), `workspace_setup.py`, `pubsub.py`, `system_prompt.py` |
| `backend/investibook/db/queries.py` | All SQLite query functions |
| `backend/investibook/models/requests.py` | Pydantic request/response models |
| `backend/investibook/config.py` | Path constants and env var resolution (`DATA_DIR`, `TEMPLATES_DIR`, `AGENTKIT_SKILLS_DIR`) |
| `backend/data/` | Runtime DATA_DIR: `db/investibook.db` + `workspaces/{id}/` session dirs (gitignored) |
| `backend/templates/` | Workspace templates copied into new workspace dirs on creation |
| `agentkit/config/` | Agent runtime config templates (e.g. `opencode.json.template`) |
| `agentkit/skills/` | Agent skills: `builtin/` (e.g. grafana-panel-finder, github-issue-search) and `nutshell-skills/` |
| `agentkit/plugins/` | OpenCode runtime plugins (e.g. `ya-opencode-telemetry/`) |
| `cli/` | Go CLI client — thin REST+SSE client for terminal/agent workflows. See `cli/skills/investibook-cli/SKILL.md` for agent usage |
| `deployment/` | Docker Compose + Kustomize manifests |
