# Zui Node-based visual editor (React Flow) for composing configs, variables, templates, and AI-generated content. Three views per workspace: **Flux** (graph canvas), **Logos** (rich text), and **Katalogos** (artifact gallery). Optional Node.js backend for AI agent calls. ## Project layout ```text zui/ ├── frontend/ # React SPA (Vite, TypeScript) │ ├── src/ │ │ ├── main.tsx # Entry point: registers node/config types, mounts React │ │ ├── app/ │ │ │ ├── canvas/ # Core graph editor (React Flow + Zustand) │ │ │ ├── kosmos/ # Platform shell: sidebar, recollection list, AI settings │ │ │ └── recollections/ # Logos (rich text), Flux (canvas), Katalogos (gallery) │ │ ├── components/ │ │ │ ├── graph/ # AnimatedEdge, BaseNode, handles, keyboard shortcuts │ │ │ ├── nodes/ # One folder per node type (agent, config, variable, …) │ │ │ └── ui/ # Shadcn-based primitives │ │ ├── hooks/ # Custom React hooks │ │ └── lib/ │ │ └── graph/ # Registry, types, state, rendering pipeline, Nunjucks utils │ ├── Dockerfile # Multi-stage: Vite build → Nginx │ ├── Dockerfile.dev # Dev with hot reload │ ├── nginx.conf │ └── package.json ├── backend/ # Node.js/Express API │ ├── src/ │ │ ├── index.ts # Express entry: registers routes, CORS, error handler │ │ ├── routes/agentRoutes.ts │ │ ├── services/agentService.ts │ │ ├── repositories/cacheRepository.ts │ │ ├── models/index.ts │ │ └── middleware/rateLimiter.ts │ └── package.json ├── docs/ │ ├── ARCHITECTURE.md │ ├── PERFORMANCE.md │ ├── NODE_TYPE_EXTENSIBILITY_PROPOSAL.md │ └── CODE_REVIEW_CHECKLIST.md ├── docker-compose.yml └── .gitignore ``` Ignored by git: `node_modules`, `dist`, `.env`, `.env.*`. Local Docker overrides: `docker-compose.override.yml` (optional, not committed). --- ## Run locally (dev) **Frontend only** (no AI agent): ```bash cd frontend && npm install && npm run dev # → http://localhost:3000 ``` **Frontend + backend** (for AI agent and health check): ```bash # Terminal 1 – backend cd backend && npm install && npm run dev # → http://localhost:8080 # Terminal 2 – frontend cd frontend && npm install && npm run dev # → http://localhost:3000 (Vite proxies /api/* and /health to backend) ``` --- ## Run with Docker ```bash docker compose up --build ``` - **Frontend**: (Nginx; `/api/*` proxied to backend). - **Backend**: (Express). Environment variables (backend service): | Variable | Default | Description | |------------------|---------------------------|--------------------------------------------| | `PORT` | `8080` | Backend listen port. | | `CORS_ORIGIN` | `http://localhost:3000` | Allowed origin for CORS. | | `AI_BASE_URL` | *(unset)* | OpenAI-compatible base URL (local LLMs). | | `AI_MODEL` | `gpt-4o-mini` | Model ID for the AI agent. | | `OPENAI_API_KEY` | *(unset)* | Required when using OpenAI directly. | For self-hosting (e.g., Tailscale/HTTPS): set `CORS_ORIGIN` to your frontend URL and put Caddy or Nginx in front for TLS. --- ## Scripts | Command | Description | |--------------------------------------|----------------------------------------| | `cd frontend && npm run dev` | Vite dev server (port 3000). | | `cd frontend && npm run build` | Build frontend for production. | | `cd frontend && npm run preview` | Preview production build. | | `cd frontend && npm run test` | Run tests in watch mode (Vitest). | | `cd frontend && npm run test:run` | Run tests once (CI). | | `cd backend && npm run dev` | Backend with `tsx --watch`. | | `cd backend && npm start` | Backend production run. | | `docker compose up --build` | Run full stack in Docker. | --- ## Backend API | Method | Path | Body / Response | |--------|-----------------------|---------------------------------------------------------------------------------| | GET | `/health` | `{ ok: true, timestamp: number }` — health check for Docker/orchestration. | | POST | `/api/agent` | Body `{ prompt, context?, contextNodes? }` → `{ markdown }` (one-shot). | | POST | `/api/agent/stream` | Body `{ prompt, context?, contextNodes? }` → SSE text stream (streaming). | --- ## Agent node (local LLM or OpenAI) AI connection settings are configured **directly in the UI** — open the sidebar and go to **AI Settings**. You can switch between providers without restarting the server. The backend reads its AI config from environment variables as a fallback: ### Local LLM (e.g. LM Studio) 1. Install [LM Studio](https://lmstudio.ai/), load a model, and start the local server (default: `http://localhost:1234`). 2. Set env vars (backend): ```bash export AI_BASE_URL=http://localhost:1234/v1 export AI_MODEL=your-model-name # optional; matches the name shown in LM Studio ``` ### OpenAI ```bash export OPENAI_API_KEY=sk-... export AI_MODEL=gpt-4o-mini # optional; defaults to gpt-4o-mini ``` --- ## Contribute - [ARCHITECTURE.md](ARCHITECTURE.md) — architecture overview, key patterns, module map - [CONTRIBUTING.md](CONTRIBUTING.md) — coding standards, branch workflow, test commands - [PERFORMANCE_IMPROVEMENTS.md](PERFORMANCE_IMPROVEMENTS.md) — bottleneck analysis and improvement plan - [docs/CODE_REVIEW_CHECKLIST.md](docs/CODE_REVIEW_CHECKLIST.md) — PR review checklist - [docs/NODE_TYPE_EXTENSIBILITY_PROPOSAL.md](docs/NODE_TYPE_EXTENSIBILITY_PROPOSAL.md) — node plugin system design *Thank you for contributing!*