An interactive assistant that turns a short project description into a streaming list of relevant technologies, key documentation links, and per-category relationship graphs.
Front‑end is a small React app with a chat UI. Back‑end is an Express server that uses an LLM (OpenRouter) to infer high‑level categories, looks up candidate products/pages (stub datasets), enriches them with Open Graph data, and streams results to the client as NDJSON.
- Category inference via LLM and streaming status updates
- Suggested technologies with docs previews (Open Graph enrichment)
- Toggleable results: list view and an interactive 2D force graph
- Typed, schema‑validated payloads shared between client and server (Zod)
- React 19 + TypeScript
- Express 5 (server) running with Bun
- OpenRouter +
aiSDK for object‑mode generation react-force-graph-2dfor graph visualization- Zod for runtime validation and shared types
- The client posts
{ prompt }to the server at/api/build. - The server:
- generates broad categories from the prompt (
server/llm/openai.ts), - finds products for each category (
server/datasets/products.ts– stub), - finds pages per product (
server/datasets/pages.ts– stub), - enriches products/pages with Open Graph (
server/opengraph.ts), - builds per‑category graphs (
server/datasets/graph.ts).
- generates broad categories from the prompt (
- Events are streamed back as NDJSON and rendered incrementally in the UI.
POST /api/build
Request
{ "prompt": "I’m building a SaaS with subscriptions and dashboards" }Response stream (NDJSON). Each line is a JSON event discriminated by type:
{ "type": "status", "message": "Analyzing your project description..." }
{ "type": "categories", "categories": ["frontend", "authentication", "database", "deployment"] }
{ "type": "product", "category": "frontend", "product": { "id": "react", "name": "React", ... } }
{ "type": "product-detail", "productId": "react", "page": { "title": "Getting Started", "url": "https://react.dev/learn" } }
{ "type": "graph", "category": "frontend", "graph": { "nodes": [...], "links": [...] } }
{ "type": "done" }Schemas are defined in shared/types.ts and used both server‑ and client‑side.
Prerequisites
- Bun installed (
curl -fsSL https://bun.sh/install | bash) - OpenRouter API key available in your environment (e.g.
OPENROUTER_API_KEY=...). Bun auto‑loads.envif present.
Install dependencies
bun installRun in development (frontend + server)
bun run devOr run individually
bun run dev:server # Express on http://localhost:3000
bun run dev:frontend # Vite dev server with /api proxy to 3000Build and preview
bun run build # typecheck + vite build
bun run preview # vite previewserver/index.ts— Express app,/api/buildstreaming endpointserver/llm/openai.ts— category generation with OpenRouter in object modeserver/datasets/{products,pages}.ts— stubbed search dataserver/datasets/graph.ts— per‑category graph constructionserver/opengraph.ts— Open Graph enrichment for products/pagesserver/stream.ts— NDJSON helpers for the streaming protocolshared/types.ts— Zod schemas and shared TypeScript typessrc/chat/Chat.tsx— chat loop, NDJSON reader, event reducersrc/results/*—ResultsPanel,ProductCard,GraphView
- Product/page search is currently stubbed; swap in your vector/database search.
- The frontend reads NDJSON directly using
ReadableStreamand updates state incrementally.