This file gives Codex (and other coding agents) a source-of-truth guide for working in this repository quickly and safely.
- Primary LLM workflow doc:
docs/LLM_GUIDE.md. - Keep
AGENTS.md,README.md, anddocs/CONTEXT_HANDOFF.mdaligned when commands, paths, or repository layout changes. - If a workflow detail is uncertain, verify from code/scripts first, then update docs to match implementation.
- We use TDD by default for feature work and bug fixes.
- Workflow:
Red: add/update a failing test first (Vitest for logic/helpers, Playwright for user flows/API contracts).Green: implement the minimal code change to pass.Refactor: clean up while keeping tests green.
- Minimum validation before handoff:
pnpm run testpnpm run test:unitpnpm run test:e2e(or targetedpnpm run test:e2e:ui/pnpm run test:e2e:apiwhile iterating)
- Use Conventional Commits for all git commit messages.
- Format:
<type>(<optional scope>): <description> - Common types:
feat,fix,docs,test,refactor,chore,build,ci. - Keep the subject concise and imperative (example:
feat(landing): add hero CTA and footer). - If a change is breaking, include
!after type/scope and noteBREAKING CHANGE:in the body.
- Commit as you go for meaningful checkpoints instead of batching everything into one final commit.
- Use a dedicated branch for applicable feature/fix work before merging.
- Branch names must use
feature/...orfix/.... - Do not use
codex/...orcopilot/...as branch prefixes.
- Project:
CrisisLens - Monorepo layout:
apps/web: Next.js 14 (App Router), React 18, TypeScript, Three.js viareact-globe.glapps/ml: Python/ML training code and model artifacts
- Frontend tests: Vitest unit tests + Playwright e2e tests in
apps/web/tests - Data pipeline: CSV aggregation script in
apps/web/scripts/generate-country-metrics.mjs
- Use pnpm for JS workflow commands.
pnpm run testruns lint + typecheck only. Unit tests are separate (pnpm run test:unit).- There is no formal Python lint/test harness configured in-repo yet.
pnpm install
pnpm run generate:data
pnpm run devApp URL: http://localhost:3000
python3 -m venv .venv
source .venv/bin/activate
pip install -r apps/ml/requirements.txt
cd apps/ml/models && python train_model.pypnpm run dev: start Next.js dev server (apps/web)pnpm run build: production build (apps/web)pnpm run lint: ESLint (apps/web)pnpm run typecheck: TypeScript compile check (apps/web)pnpm run test:unit: run Vitest tests (apps/web)pnpm run test:e2e: run Playwright end-to-end tests (apps/web)pnpm run test:e2e:headed: run Playwright e2e tests in headed mode (cd apps/web && pnpm run test:e2e:headed)pnpm run test:e2e:ui: run only dashboard UI Playwright tests (apps/web)pnpm run test:e2e:api: run only API contract Playwright tests (apps/web)pnpm run playwright:install: install Chromium for Playwright (cd apps/web && pnpm run playwright:install)pnpm run test: lint + typecheck (apps/web)pnpm run test:all: lint + typecheck + unit + e2e (apps/web)pnpm run generate:data: regenerateapps/web/public/data/*.jsonfrom CSVs inapps/web/data/
Run this sequence for frontend changes:
pnpm run test:unit
pnpm run test
pnpm run buildFor UI-flow changes, also run:
pnpm run test:e2eFor ML/backend-only changes, there is no formal Python test/lint setup in-repo yet; at minimum run:
cd apps/ml/models && python train_model.pyML training caveat:
apps/ml/models/train_model.pycurrently relies on relative paths and local data availability; validate input/output paths in your environment before using outputs.
- Unit tests live in:
apps/web/tests/lib/metrics.test.tsapps/web/tests/components/summary-utils.test.tsapps/web/tests/lib/cv-globe-bridge.test.tsapps/web/tests/lib/globe-picking.test.ts
- Playwright e2e tests live in:
apps/web/tests/e2e/landing.spec.jsapps/web/tests/e2e/dashboard.spec.jsapps/web/tests/e2e/api-routes.spec.js
- Playwright config:
apps/web/playwright.config.mjs - Playwright note: e2e scripts use
pnpm exec playwright ...; first run requires network access to fetch package/browsers if they are not already installed. - Vitest config:
apps/web/vitest.config.ts(Node environment, alias@ -> apps/web root) - ESLint config:
apps/web/.eslintrc.json - TypeScript config:
apps/web/tsconfig.json(strict mode enabled)
- App shell + landing route (
/):apps/web/app/layout.tsx,apps/web/app/page.tsx - Landing UI components:
apps/web/components/landing/LandingHero.tsxapps/web/components/landing/LandingGlobe.tsxapps/web/components/landing/LandingFeatures.tsxapps/web/components/landing/LandingWorkflow.tsxapps/web/components/landing/LandingFootprint.tsxapps/web/components/landing/LandingFooter.tsx
- Dashboard route (
/dashboard):apps/web/app/dashboard/page.tsx - Main dashboard UI:
apps/web/components/GlobeDashboard.tsx - Dashboard layout/theme controls:
apps/web/components/dashboard/HeroSection.tsxapps/web/components/dashboard/LayerSelector.tsxapps/web/components/dashboard/ThemeToggle.tsxapps/web/components/dashboard/DatabricksChatPopup.tsx
- Dashboard panel cards:
apps/web/components/dashboard/CountryPanel.tsxapps/web/components/dashboard/AgentStatePanel.tsxapps/web/components/dashboard/PriorityRankingPanel.tsxapps/web/components/dashboard/OciPanel.tsxapps/web/components/dashboard/ProjectOutliersPanel.tsxapps/web/components/dashboard/SimulationPanel.tsxapps/web/components/dashboard/CvPanel.tsx
- 3D globe + hand controls:
apps/web/components/Globe3D.tsx - API route stubs:
apps/web/app/api/globe/heatmap/route.tsapps/web/app/api/country/[iso3]/route.tsapps/web/app/api/project/[project_id]/route.tsapps/web/app/api/agent/country/[iso3]/route.tsapps/web/app/api/genie/query/route.tsapps/web/app/api/cv/detect/route.ts
- Frontend API client/types:
apps/web/lib/api/crisiswatch.ts - Domain helpers/types:
apps/web/lib/types.ts,apps/web/lib/metrics.ts,apps/web/lib/countries.ts - Integration seams (mock providers):
apps/web/lib/databricks/client.tsapps/web/lib/databricks/genie.tsapps/web/lib/cv/provider.tsapps/web/lib/cv/globeBridge.ts
apps/web/data/contains large CSV inputs required bypnpm run generate:data.- Generated artifacts consumed by the app:
apps/web/public/data/country-metrics.jsonapps/web/public/data/snapshot.json
- If changes affect
apps/web/lib/types.tsmetrics fields or API projections, regenerate data and run full validation.
- Optional:
NEXT_PUBLIC_GLOBE_WS_URL- Used by
apps/web/components/GlobeDashboard.tsxfor WebSocket anomaly/highlight events. - If unset, WebSocket subscription is skipped.
- Used by
- Preserve API response shapes used by
apps/web/lib/api/crisiswatch.tsunless updating both server routes and client types together. - Keep globe-related browser APIs in client components (
"use client").apps/web/components/Globe3D.tsxis loaded dynamically withssr: falsefor SSR safety. - Prefer extending provider interfaces (
DatabricksProvider,GenieClient,CVCountryDetector) rather than wiring external services directly into UI components. - When touching metric formulas, update corresponding unit tests in
apps/web/tests/lib/metrics.test.ts. - Styling policy (strict): use Tailwind utility classes for all component/page styling.
- Do not introduce or expand semantic CSS utility wrappers (for example
dbx-*,landing-*,chip-*) inglobals.css. - Use
apps/web/app/globals.cssonly for global/base styles, CSS variables, or hard-to-express third-party selectors (for example, canvas internals or browser-wide resets).
- Keep components small and composable; extract logic/helpers instead of growing monolithic UI files.
- Prefer explicit domain types for API payloads/state over
Record<string, unknown>shapes. - Remove unused CSS hook class names after Tailwind migration; avoid adding non-semantic class tokens when utilities already express the style.
- Avoid duplicate state updates/effects and keep side effects contained in
useEffect/callbacks with clear cleanup.
- No Python linting (
ruff/flake8) or Python test suite configured. - ML scripts/artifacts are evolving quickly; verify assumptions from code, not stale docs.