# Agent Instructions WireGuard UI — a self-hosted web admin for WireGuard hosts and clients. The app runs **as root** and executes system commands (`wg`, `ip`, `iptables`, `wg-quick`, firewall managers). Treat every API route and every value that reaches a shell or a WireGuard config as security-sensitive. ## Stack - **Runtime:** Bun — not Node. Use `bun` commands, never `npm`/`npx`. - **Framework:** `@moduletrace/bunext` — not Next.js. Routing is filesystem-based under `src/pages/`, served by `Bun.serve` in `src/server.ts`. - **Database:** `@moduletrace/bun-sqlite` — SQLite. Schema in `db/schema.ts`, generated types in `db/types/db.ts`. Config in `bun-sqlite.config.ts` (DB name `wgui` in `./db`). Import its types from `@moduletrace/bun-sqlite/types` (not `/dist/types`). - **UI:** Tailwind CSS v4 + local `twui` components (`src/components/twui`). Global styles in `src/styles/main.css`. - **Icons:** `lucide-react`. ## MCP Tool Usage Guidelines When building, refactoring, styling, or auditing UI components and layouts, actively invoke these configured MCP servers: ### 1. `design-mcp` (UI/UX Engineering & Design Standards) - **When to call:** Before constructing new page layouts, design systems, empty/loading states, or interactive UI flows. - **Instruction:** Query `design-mcp` to ensure accessibility (a11y), proper layout hierarchy, visual balance, and consistent interaction patterns across application workflows. ### 2. `design-systems` (Design System Specs & Reference Patterns) - **When to call:** When creating or extending reusable component interfaces, verifying design token structures, or inspecting component composition patterns. - **Instruction:** Query `design-systems` to pull canonical UI patterns, atomic component guidelines, and standard prop naming conventions before creating custom components. ## Entrypoint `src/server.ts` — runs `bunextInit()`, starts `Bun.serve` on `0.0.0.0` (port from `SiteData.ServerPort`), serves `/media/*` via `handleMediaServer`, then runs `syncWireguardHosts()` to bring host tunnels in line with the DB. On-disk state: WireGuard keys/configs/iptables scripts live under `/var/lib/wgui` (`grabDirNames()` in `src/utils/grab-dir-names.ts`); uploaded media under `DATA_DIR` (default `./.data`). ## Commands | Purpose | Command | | --------------- | ------------------------------------------------------- | | Dev server | `bun run dev` (runs `sudo bun src/server.ts`) | | Production | `bun run start` | | Build | `bun run build` | | Type-check | `bun run typecheck` (`bunx tsc --noEmit`) | | Tests | `bun run test` (`bun test`) | | DB schema | `bun run db:schema` | | DB admin UI | `bun run db:admin` | No linter or formatter configured. Type-check and `bun test` are the verification steps. ## Architecture - `src/pages/__root.tsx` — picks the layout (`src/layouts/main` or `src/layouts/admin`, or `LoginShell` for auth pages) and provides `AppContext`. - **Pages:** `/` + `about`, `privacy`, `terms`; `/auth/{login,logout,signup}`; `/admin` (dashboard), `/admin/setup`, `/admin/settings`, `/admin/clients`, `/admin/hosts/*` (add/edit hosts, `[host_id]/clients/*` add/edit/view clients). - **API:** `src/pages/api/admin/*` (host/client setup, network info, firewall status, service restart/update, media), generic CRUD at `src/pages/api/admin/crud/[[...paths]].ts` with per-table handlers in `crud/(tables)//{get,post,put,del}.ts`, plus `api/auth/login.ts` and `api/create-first-user.ts`. - **Every `/api/admin/*` route must authenticate** — nothing guards the prefix globally. Use `adminApiGuard({ req })` (`src/functions/backend/auth/admin-api-guard.ts`) or `userAuth` + `checkUserAccess`. - **Shell safety:** never interpolate request/DB values into `execSync` strings. Use `execFileSync` with an args array or `node:fs` APIs, and validate values before they reach a WireGuard config (newlines there can inject `PostUp` commands). Validators live in `src/utils/` (`validate-ipv4`, `validate-ipv4-cidr`, `validate-allowed-ips`, `validate-endpoint-host`, `validate-interface-name`). ## Path Alias `@/*` resolves from repo root. Import like `@/src/components/general/admin-card`, `@/db/types/db`. ## Page Directory Rules For route-local code under `src/pages`, use non-routed meta folders: - `(sections)` — page sections - `(partials)` — components used by sections - `(data)` — page-local data - `(functions)` — page-local functions - `(utils)` — page-local utilities - `(hooks)` — page-local hooks Keep route files (e.g. `index.tsx`) thin — compose from route-local meta folders. Dynamic routes use `[param]` syntax (e.g. `[id]`, `[user_type]`, `[key]`). Catch-all routes use `[[...paths]]`. Server functions use `index.server.ts` alongside `index.tsx` (e.g. `single-document/[id]/index.server.ts`). ## Shared Code Organization - **`src/functions/backend/`** — Server-only: `auth/`, `db/`, `firewall/` (firewalld/ufw rules, status), `media/`, `setup/` (host/client setup, iptables script builder, network detection). - **`src/functions/frontend/`** — Client-safe: CRUD/fetch handlers, media upload/delete, client rule label formatting. - **`src/functions/server/`** — Request-level server handlers (media server). - **`src/hooks/`** — `use-admin-crud-get`, `use-client-rules-map`, `use-fetch-get`, `use-form-init`, `use-users-get`. - **`src/utils/`** — Cookies, crypto, dir names, IP/CIDR/port/interface validators, WireGuard interface naming. Most have `.test.ts` files. - **`src/dict/`**, **`src/data/`** — Constants (`app-data.ts`, `site-data.ts`), user types, client rules, links. - **`src/scripts/`** — Shell scripts: `install-wg-ui.sh`, `setup-wireguard.sh`, `wg-quick-manage.sh`. - **`src/components/general/`** — Shared app components (admin cards/buttons, clients table, host IP field, login shell, user form). ## Conventions - Prefer one function/component per file over monolithic files with multiple exports. - **Every rendered array must have a separate component for each array item.** Always extract the item JSX into its own component and render it via `items.map((item) => )` — never inline the item's JSX inside the map callback. - Always use object parameters (`{ foo, bar }`) instead of comma-separated positional parameters. - Prefer existing patterns over new abstractions. - **Modularization is non-negotiable: prioritize modularization over monolithic functions/components.** Repeated UI blocks must be extracted into their own reusable components driven by props (e.g. an info row component taking `{ icon, text }`), never repeated inline markup. - **UNCHANGEABLE RULE — twui components always win over raw JSX elements.** ALWAYS use twui components (`H1`–`H5`, `P`, `Span`, `List`, `Img`, `Row`, `Stack`, `Container`, `Section`, `Border`, `Card`, `Button`, `Tag`, `Link`, etc.) before basic JSX elements (`

`–`

`, `

`, ``, `