# AGENTS.md — How to work in this project A guide for AI agents (and humans) contributing to **Pocket Pascal**, a small installable PWA with a React/shadcn frontend and an Express + SQLite backend. ## 1. Overview - **Frontend (`client/`):** Vite + React + TypeScript, Tailwind CSS v4, shadcn/ui, `vite-plugin-pwa` for the service worker + web manifest. - **Backend (`server/`):** Express + TypeScript (`tsx` in dev, `tsc` for the production build) with `better-sqlite3` as the database. - **Workspace:** a single pnpm workspace with two packages: `client` and `server`. ### Runtime model - **Dev:** run `pnpm dev` from the repo root. It starts both packages in parallel. The Vite dev server (default `http://localhost:5173`) proxies `/api/*` to the backend (`http://localhost:3001`), so there are no CORS issues. - **Prod / install test:** run `pnpm build && pnpm start`. The backend serves the built client from `client/dist` (static files + SPA fallback), so a single process on `http://localhost:3001` serves the whole app. This is the easiest way to test PWA "Add to Home Screen". ## 2. Prerequisites - **Node.js >= 22** (developed on Node 22). - **pnpm** (developed on 10.25). The root `package.json` pins the version via `packageManager`. > `better-sqlite3` ships a native module. It is listed under > `pnpm.onlyBuiltDependencies` in the root `package.json`, so a normal > `pnpm install` compiles/fetches it automatically. If it ever fails to load, run > `pnpm rebuild better-sqlite3` (or from its `.pnpm` dir: `npx prebuild-install -r node`). ## 3. First-time setup ```bash pnpm install ``` ## 4. Common commands Run these from the **repo root**: | Command | What it does | | --------------- | ------------------------------------------------------------------- | | `pnpm dev` | Start client + backend in parallel (concurrently). | | `pnpm build` | Build the server (`tsc`) then the client (`tsc -b && vite build`). | | `pnpm start` | Run the production server (`node server/dist/index.js`). | | `pnpm lint` | Lint every workspace package. | | `pnpm typecheck`| Type-check every workspace package (`tsc`). | Run these against a **single package** with the filter flag, e.g.: ```bash pnpm --filter client dev pnpm --filter server dev pnpm --filter client build ``` ## 5. Project layout ``` pocket-pascal/ ├─ package.json # workspace root + orchestration scripts ├─ pnpm-workspace.yaml # packages: client, server ├─ AGENTS.md ├─ README.md ├─ client/ # Vite + React + Tailwind v4 + shadcn/ui (PWA) │ ├─ components.json # shadcn config │ ├─ pwa-assets.config.ts # @vite-pwa/assets-generator config │ ├─ vite.config.ts # react + tailwind + pwa + /api proxy + "@" alias │ └─ src/ │ ├─ App.tsx # Hello World UI (fetches /api/hello) │ ├─ lib/api.ts # typed fetch helpers │ ├─ lib/utils.ts # cn() helper (shadcn) │ └─ components/ui/ # shadcn components live here └─ server/ # Express + better-sqlite3 (ESM, TypeScript) ├─ .env.example └─ src/ ├─ index.ts # express app; serves client/dist in prod ├─ db.ts # opens SQLite, creates schema, exposes helpers └─ routes/hello.ts # GET /api/hello ``` ## 6. Conventions - **Language:** TypeScript everywhere. The server is ESM (`"type": "module"`). - **Path alias (client):** `@/*` maps to `client/src/*` (configured in `tsconfig.json`, `tsconfig.app.json`, and `vite.config.ts`). Prefer `@/components/...`, `@/lib/...`. - **API contract:** all backend endpoints are prefixed with `/api` (e.g. `GET /api/hello`, `GET /api/health`). The frontend calls them with relative URLs (`fetch("/api/hello")`) so the Vite proxy and the prod static server both work without extra config. - **Environment:** the backend reads `process.env.PORT` (default `3001`). See `server/.env.example`. - **Styling:** Tailwind v4 + shadcn theme tokens (CSS variables in `client/src/index.css`). Use shadcn primitives; reach for `cn()` in `@/lib/utils` when composing classes. ## 7. Database - The SQLite file lives at **`server/data/app.db`** (auto-created on first run; the whole `server/data/` directory is gitignored). - There is **no migration tool**. Schema changes use idempotent statements (`CREATE TABLE IF NOT EXISTS ...`) in `server/src/db.ts`, which runs on boot. - The demo `visits` table has a single enforced row (`id = 1`) holding a counter that `GET /api/hello` increments. ## 8. Adding a shadcn/ui component Run from the `client/` directory (it reads `components.json`): ```bash cd client pnpm dlx shadcn@latest add # e.g. card, input, dialog ``` The component is written to `client/src/components/ui/`. shadcn was initialized with the **neutral** base color and the **base-nova** style. ## 9. Regenerating PWA icons Icons are generated from `client/public/icon.svg` via `@vite-pwa/assets-generator`: ```bash cd client pnpm dlx @vite-pwa/assets-generator # uses pwa-assets.config.ts ``` Outputs land in `client/public/` (`pwa-*.png`, `maskable-icon-*.png`, `apple-touch-icon-*.png`). The manifest in `vite.config.ts` references them. ## 10. PWA / install notes - iOS Safari needs the meta tags already in `client/index.html` (`apple-mobile-web-app-capable`, `apple-touch-icon`, etc.) and a valid icon set. - Service worker + manifest are produced by `vite-plugin-pwa`. To verify installability: `pnpm build && pnpm start`, open `http://localhost:3001`, then DevTools → Application → Manifest / Service Workers. Real-device install off localhost requires HTTPS. ## 11. Before you finish a change Always run, from the repo root: ```bash pnpm typecheck pnpm lint pnpm build ``` Then sanity-check `pnpm dev` (or `pnpm build && pnpm start`) end to end.