A sleek RAG chat UI — index any website, ask questions, get cited answers.
| Layer | Technology |
|---|---|
| Framework | SvelteKit (Svelte 5, runes) |
| Language | TypeScript |
| Styling | Tailwind CSS v4 |
| Components | shadcn-svelte (bits-ui) |
| Icons | Lucide Svelte |
| Data fetching | TanStack Query for Svelte |
| Markdown | marked |
| Package manager | Bun |
| Build tool | Vite |
scraped_websites/support_squadcast_com/adding_a_schedule.txt) back to the real URL (https://support.squadcast.com/adding-a-schedule).conversation_id is persisted per conversation and re-sent on every message for full context continuity.healthy / degraded / offline), polled every 60 seconds..ai-bubble.Enter sends, Shift+Enter inserts a newline.bun install
bun run dev
The app is served at http://localhost:5173 by default.
bun run build
bun run preview
bun run check
Install Vitest if it is not yet present:
bun add -D vitest
Run all tests:
bunx vitest run
Watch mode:
bunx vitest
hivemind/
├── src/
│ ├── lib/
│ │ ├── api.ts # Typed fetch wrappers for all backend endpoints
│ │ ├── chat.svelte.ts # Svelte 5 rune-based chat store (conversations, messages)
│ │ ├── source-url.ts # sourceHref / sourceLabel helpers (scraped path to URL)
│ │ ├── api.test.ts # Vitest unit tests for api.ts
│ │ ├── chat.test.ts # Vitest unit tests for the chat store
│ │ ├── sourceUrl.test.ts # Vitest unit tests for source-url.ts
│ │ ├── components/ # shadcn-svelte UI primitives (Button, Badge, Textarea, ...)
│ │ ├── hooks/ # Svelte hooks
│ │ ├── utils.ts # cn() class-name helper
│ │ └── index.ts # Barrel re-exports
│ └── routes/
│ ├── +layout.svelte # QueryClientProvider wrapper
│ ├── +page.svelte # Main chat page (sidebar + chat thread + input bar)
│ └── layout.css # Global styles and font imports
├── .doc/
│ └── API_INFO.md # Backend API reference
├── package.json
├── svelte.config.js
├── vite.config.ts
├── vitest.config.ts
└── tsconfig.json
The frontend communicates exclusively with the hosted backend at:
https://hivemind-2f75.onrender.com
All API calls are centralised in src/lib/api.ts.
| Function | Method | Endpoint | Description |
|---|---|---|---|
fetchHealth |
GET | /health |
Deep health check; returns healthy or degraded |
sendQuery |
POST | /api/v1/query |
Ask a question; returns answer, sources, and conversation_id |
fetchFAQs |
GET | /api/v1/faqs |
Fetch auto-generated FAQs (up to 5) |
crawlURL |
POST | /api/v1/crawl |
Submit a URL for background crawling and indexing |
All non-2xx responses are thrown as ApiError instances that carry a status code. The UI handles the following cases explicitly:
/api/v1/query — the requested URL has not been indexed yet./api/v1/crawl — the URL is already indexed; the UI accepts this silently and scopes the conversation.When a user indexes a website, its URL is stored on the active conversation via chat.setScopeUrl. All subsequent sendQuery calls in that conversation include url in the request body, which tells the backend to search only that site's Pinecone namespace.
The conversation_id UUID returned by the first sendQuery response is stored on the conversation and sent with every follow-up message, giving the LLM full history access.
Add screenshots here once the UI is deployed.
| View | Screenshot |
|---|---|
| Empty state | (placeholder) |
| Chat thread with sources | (placeholder) |
| Indexing panel — crawling | (placeholder) |
| Indexing panel — already indexed | (placeholder) |
| Mobile sidebar | (placeholder) |
Private — all rights reserved.