|
| 1 | +# Cornell Loop — Agent Guide |
| 2 | + |
| 3 | +Loop is an event-discovery dashboard for Cornell student orgs. Students follow clubs, RSVP to events, and browse a feed of upcoming happenings. Convex backs auth + data; a browser extension surface is also planned. |
| 4 | + |
| 5 | +Keep this file concise — it loads every new session. |
| 6 | + |
| 7 | +## Repo layout |
| 8 | + |
| 9 | +- `apps/dashboard/` — Vite + React 19 + TypeScript SPA (the main web app). |
| 10 | +- `shared/ui/` — design system (components, tokens, utils). Imported in the dashboard via the `@app/ui` alias (see `apps/dashboard/vite.config.ts`). |
| 11 | +- `ai/`, `scripts/`, `specs/` — docs, codegen helpers, and visual-QA artefacts. |
| 12 | + |
| 13 | +No other apps today; workspace is set up to grow (e.g. extension). |
| 14 | + |
| 15 | +## Tech stack |
| 16 | + |
| 17 | +- **React 19** + **React Router v7** (see `apps/dashboard/src/App.tsx` for routes). |
| 18 | +- **Convex** (`@convex-dev/auth`) for auth. `ProtectedRoute` has a **dev bypass** — protected routes render without login when `import.meta.env.DEV`. Great for iteration. **Always read `apps/dashboard/convex/_generated/ai/guidelines.md` first** before touching Convex code — its rules override training data. |
| 19 | +- **Tailwind CSS v4** via `@tailwindcss/vite`. No config file; content scanning is via `@source` directives inside `apps/dashboard/src/index.css`. **Important:** `shared/ui/src` is explicitly `@source`'d so design-system classes land in the generated CSS. If a design-system class silently stops working, check that this `@source` is still present. |
| 20 | +- **Design tokens** are plain CSS custom properties in `shared/ui/src/styles/tokens.css` (`--color-*`, `--space-*`, `--font-*`, `--radius-*`, `--shadow-*`, etc.). **Never hardcode colors/spacing/fonts.** Reference tokens with Tailwind arbitrary-value syntax, e.g. `bg-[var(--color-surface)]`, `gap-[var(--space-4)]`. |
| 21 | +- **Fonts**: DM Sans (body), Inter (UI), Manrope (brand wordmark). Loaded in `apps/dashboard/index.html`. |
| 22 | +- **SVG** via `vite-plugin-svgr` (`import Icon from './x.svg?react'`). |
| 23 | + |
| 24 | +## Package manager |
| 25 | + |
| 26 | +- This repo uses **bun** (not pnpm — ignore any older doc that says otherwise). |
| 27 | +- Root scripts forward into the dashboard package: |
| 28 | + - `bun run dev` — start Vite (default 5173, falls back to 5174 if busy). |
| 29 | + - `bun run build` — `tsc -b && vite build`. |
| 30 | + - `bun run type-check` — `tsc --noEmit`. |
| 31 | + - `bun run lint` — ESLint. |
| 32 | + - `bun run format` / `bun run format:check` — Prettier (with tailwind plugin). |
| 33 | +- If bun is unavailable in a sandbox, `node scripts/*.mjs` still works for scripts. |
| 34 | + |
| 35 | +## Automated checks (Claude Stop hook) |
| 36 | + |
| 37 | +A `Stop` hook in `.claude/settings.json` runs `bun run type-check && bun run lint && bun run format:check` at the end of every turn. If it fails, address the errors before finishing — even pre-existing ones. |
| 38 | + |
| 39 | +## Visual QA workflow |
| 40 | + |
| 41 | +- **Screenshot the dashboard** with Playwright: |
| 42 | + - `node scripts/screenshot-home.mjs <label>` — screenshots `/home` at 1280/1440/1920 viewports into `specs/iterations/`. |
| 43 | + - `node scripts/screenshot-scroll.mjs <label>` — screenshots scrolled state to verify sticky sidebar behaviour. |
| 44 | +- Requires the dev server running: `bun run dev &`. The scripts assume `http://localhost:5174/home`; override with `HOME_URL=...`. |
| 45 | +- `specs/iterations/*.png` is gitignored. |
| 46 | +- Design-system gallery route (dev-only): `/design-system` renders every token and component with sample data. Use it as the visual source of truth when the Figma file conflicts with component behaviour. |
| 47 | + |
| 48 | +## Sample data |
| 49 | + |
| 50 | +`apps/dashboard/src/data/sampleHome.ts` exports `SAMPLE_POSTS`, `SAMPLE_RSVP_GROUPS`, `SAMPLE_CLUBS`. These feed `/home` until Convex tables exist. |
| 51 | + |
| 52 | +## Coding rules |
| 53 | + |
| 54 | +- **Ask clarifying questions** when a prompt or approach is unclear — don't guess. |
| 55 | +- **Default to delegating** cohesive / repetitive / multi-file tasks to subagents. Reserve the main conversation for decision-making, proposals, and review. Brief subagents with: files to touch, pattern to follow, and "run type-check/lint/format when done". |
| 56 | +- **Fix pre-existing warnings** in files you touch, regardless of origin. |
| 57 | +- **Never use `any` or `as` casts.** Fix the type or schema properly. |
| 58 | +- **Never leave TODOs.** Implement everything. |
| 59 | +- **Never hardcode design values.** Reference `tokens.css` via `var(--…)`. |
| 60 | +- When adding files, prefer editing existing ones. Don't create docs or READMEs unless asked. |
| 61 | + |
| 62 | +## Figma MCP rules |
| 63 | + |
| 64 | +Required flow for any Figma-driven change: |
| 65 | + |
| 66 | +1. `get_design_context` with the exact node id(s). |
| 67 | +2. If truncated, `get_metadata` → re-fetch specific nodes. |
| 68 | +3. `get_screenshot` for the visual reference. |
| 69 | +4. Download assets only after you have both context + screenshot. Start implementation then. |
| 70 | +5. Translate the Tailwind output into **this repo's** tokens and existing components. Do not import icon packages — assets come from Figma. Reuse `Button`, `Tag`, `Avatar`, `DashboardPost`, `SearchPanel`, etc. from `@app/ui`. |
| 71 | +6. Validate against the Figma screenshot. |
| 72 | + |
| 73 | +The Figma MCP output is a representation, not final code. Use localhost image URLs directly when provided; never invent placeholders when one exists. |
| 74 | + |
| 75 | +**When Figma and the design system disagree, the design system is the source of truth.** Confirm by checking `/design-system` or `shared/ui/src/components/*`. |
0 commit comments