Skip to content

Commit 8cefcde

Browse files
shantanu patilclaude
authored andcommitted
feat: add interactive diagram system — tech logos, structured data, click-to-explain
Phase 1: Tech stack logos in Mermaid diagrams - Icon registry with 67 tech icons from simple-icons (tree-shaking friendly) - Post-render SVG injector adds 18x18 logos to diagram nodes - Fuzzy matching with 112 aliases (postgres->postgresql, k8s->kubernetes, etc.) - Auto-adjusts icon colors for light/dark theme contrast Phase 2: Structured JSON diagram data from AI - TypeScript + Pydantic schemas for DiagramNode, DiagramEdge, DiagramData - AI prompt suffix outputs structured JSON in HTML comment markers alongside Mermaid - Backend extraction + validation pipeline (diagram_extract.py) - Backward-compatible: Optional fields, existing caches unaffected Phase 3: Click-to-explain with AI - Clickable Mermaid nodes with hover highlights and selection state - DiagramDetailPanel slide-out with node info, file links, connections - /ws/diagram/explain WebSocket endpoint streaming AI explanations via RAG - Supports all providers (Google, OpenAI, OpenRouter, Azure, Ollama, Bedrock) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent a337c18 commit 8cefcde

20 files changed

Lines changed: 2148 additions & 86 deletions

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ downloads/
2323
eggs/
2424
api/logs/
2525
.eggs/
26-
lib/
27-
lib64/
26+
/lib/
27+
/lib64/
2828
parts/
2929
sdist/
3030
var/

CLAUDE.md

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## What This Is
6+
7+
BetterCodeWiki auto-generates interactive wikis for GitHub/GitLab/Bitbucket repos. It's a fork of DeepWiki-Open with an overhauled UI, 3D landing page, enhanced diagrams, MCP server, and multi-provider AI support.
8+
9+
## Commands
10+
11+
### Frontend (Next.js 15 + React 19)
12+
```bash
13+
yarn install # install deps (yarn 1.x — enforced via packageManager)
14+
yarn dev # dev server on :3000 (turbopack)
15+
yarn build # production build
16+
yarn lint # eslint (next/core-web-vitals + next/typescript)
17+
```
18+
19+
### Backend (Python — FastAPI)
20+
```bash
21+
python -m pip install poetry==2.0.1 && poetry install -C api
22+
python -m api.main # API server on :8001
23+
```
24+
25+
### Tests (pytest)
26+
```bash
27+
pytest test/ # all tests (testpaths = test/)
28+
pytest test/test_extract_repo_name.py # single test file
29+
pytest -m unit # by marker: unit, integration, slow, network
30+
```
31+
There's also a `tests/` directory with api/unit/integration subdirs — these are run via `python tests/run_tests.py` or by pointing pytest at them directly.
32+
33+
### Docker
34+
```bash
35+
docker-compose up # runs everything (frontend :3000, API :8001, MCP :8008)
36+
```
37+
38+
### MCP Server (standalone)
39+
```bash
40+
python api/mcp/server.py # stdio mode (Claude Desktop/Code)
41+
python api/mcp/server.py --http # HTTP mode on :8008
42+
mcp dev api/mcp/server.py # browser-based inspector
43+
```
44+
45+
## Architecture
46+
47+
### Two-process system
48+
- **Frontend**: Next.js app in `src/`. Proxies API calls to the backend via `next.config.ts` rewrites (routes like `/api/wiki_cache/*`, `/export/wiki/*`, `/api/auth/*`).
49+
- **Backend**: FastAPI app in `api/api.py`, entry point `api/main.py`. Handles repo cloning, embedding, wiki generation, RAG chat, and export.
50+
51+
### Wiki generation flow
52+
1. User submits a repo URL on the landing page (`src/app/page.tsx`)
53+
2. Frontend navigates to `src/app/[owner]/[repo]/page.tsx` — the main wiki viewer
54+
3. Backend clones the repo, creates embeddings via adalflow + FAISS, generates wiki pages using the configured AI provider
55+
4. Wiki data is cached in `~/.adalflow/wikicache/` and served back as JSON
56+
57+
### Real-time communication
58+
- **WebSocket** (`/ws/chat`): Used for Ask/chat and DeepResearch features. Client in `src/utils/websocketClient.ts`, server handler in `api/websocket_wiki.py`.
59+
- Wiki generation itself streams via the same WebSocket infrastructure.
60+
61+
### AI provider abstraction
62+
The backend supports multiple providers through client wrappers in `api/`:
63+
- `api/config.py` — loads API keys from env, reads JSON configs from `api/config/`
64+
- Each provider has its own client: `openai_client.py`, `openrouter_client.py`, `azureai_client.py`, `bedrock_client.py`, `dashscope_client.py`
65+
- Google Gemini uses adalflow's `GoogleGenAIClient` directly
66+
- Ollama uses adalflow's `OllamaClient` with patches in `ollama_patch.py`
67+
- Embeddings: configurable via `DEEPWIKI_EMBEDDER_TYPE` env var; implementation in `api/tools/embedder.py`
68+
69+
### RAG pipeline
70+
`api/rag.py` implements retrieval-augmented generation using adalflow. Prompts live in `api/prompts.py`. The data pipeline (`api/data_pipeline.py`) handles repo file processing and token counting.
71+
72+
### Frontend routing
73+
- `/` — Landing page with 3D hero (Three.js via `@react-three/fiber`, dynamically imported to avoid SSR)
74+
- `/[owner]/[repo]` — Wiki viewer (main app surface)
75+
- `/[owner]/[repo]/slides` — Presentation mode
76+
- `/[owner]/[repo]/workshop` — Workshop mode
77+
- `/wiki/projects` — Cached project browser
78+
79+
### Key frontend patterns
80+
- **Theming**: `next-themes` with `darkMode: 'selector'` in Tailwind. Theme toggle in `src/components/theme-toggle.tsx`.
81+
- **i18n**: `src/contexts/LanguageContext.tsx` wraps the app. Translations in `src/messages/{locale}.json` (en, ja, zh, es, kr, vi, pt-br, ru, fr, zh-tw). Manual `t()` function in page components, not next-intl's `useTranslations`.
82+
- **Animations**: GSAP + Framer Motion. GSAP registered in `src/lib/gsap.ts`. Smooth scroll via Lenis (`src/lib/smooth-scroll.ts`).
83+
- **Mermaid diagrams**: Custom renderer in `src/components/Mermaid.tsx` with fullscreen expand, SVG pan-zoom, and theme-aware styling.
84+
- **Path alias**: `@/*` maps to `./src/*`
85+
86+
### MCP server
87+
`api/mcp/server.py` is fully standalone — no imports from the main codebase. Reads cached wikis from `~/.adalflow/wikicache/`. Provides 5 tools: `list_projects`, `get_wiki_overview`, `get_wiki_page`, `search_wiki`, `ask_codebase`.
88+
89+
## Environment
90+
91+
Required env vars depend on which AI provider you use. At minimum set `GOOGLE_API_KEY` or `OPENAI_API_KEY` in `.env` at project root. See README for the full table. The backend defaults to `http://localhost:8001`; override with `SERVER_BASE_URL`.

api/api.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ class WikiPage(BaseModel):
4747
filePaths: List[str]
4848
importance: str # Should ideally be Literal['high', 'medium', 'low']
4949
relatedPages: List[str]
50+
diagramData: Optional[List[Dict]] = None
5051

5152
class ProcessedProjectEntry(BaseModel):
5253
id: str # Filename
@@ -145,6 +146,7 @@ class AuthorizationConfig(BaseModel):
145146
code: str = Field(..., description="Authorization code")
146147

147148
from api.config import configs, WIKI_AUTH_MODE, WIKI_AUTH_CODE
149+
from api.diagram_extract import extract_diagram_data
148150

149151
@app.get("/lang/config")
150152
async def get_lang_config():
@@ -393,13 +395,17 @@ def generate_json_export(repo_url: str, pages: List[WikiPage]) -> str:
393395
# Import the simplified chat implementation
394396
from api.simple_chat import chat_completions_stream
395397
from api.websocket_wiki import handle_websocket_chat
398+
from api.diagram_explain import handle_diagram_explain
396399

397400
# Add the chat_completions_stream endpoint to the main app
398401
app.add_api_route("/chat/completions/stream", chat_completions_stream, methods=["POST"])
399402

400403
# Add the WebSocket endpoint
401404
app.add_websocket_route("/ws/chat", handle_websocket_chat)
402405

406+
# Add the diagram explain WebSocket endpoint
407+
app.add_websocket_route("/ws/diagram/explain", handle_diagram_explain)
408+
403409
# --- Wiki Cache Helper Functions ---
404410

405411
WIKI_CACHE_DIR = os.path.join(get_adalflow_default_root_path(), "wikicache")
@@ -428,6 +434,16 @@ async def save_wiki_cache(data: WikiCacheRequest) -> bool:
428434
cache_path = get_wiki_cache_path(data.repo.owner, data.repo.repo, data.repo.type, data.language)
429435
logger.info(f"Attempting to save wiki cache. Path: {cache_path}")
430436
try:
437+
# Extract structured diagram data from page content if present
438+
for page in data.generated_pages.values():
439+
if page.diagramData is None and page.content:
440+
try:
441+
diagram_data = extract_diagram_data(page.content)
442+
if diagram_data:
443+
page.diagramData = diagram_data
444+
except Exception as e:
445+
logger.warning(f"Failed to extract diagram data for page {page.id}: {e}")
446+
431447
payload = WikiCacheData(
432448
wiki_structure=data.wiki_structure,
433449
generated_pages=data.generated_pages,

0 commit comments

Comments
 (0)