Skip to content

Latest commit

 

History

History
197 lines (160 loc) · 5.27 KB

File metadata and controls

197 lines (160 loc) · 5.27 KB

AGENTS.md - Codebase Guidelines

Build, Lint, and Test Commands

npm run dev          # Start development server
npm run build        # Build for production (verifies production readiness)
npm run start        # Start production server
npm run lint         # Run ESLint

Type Checking

npx tsc --noEmit     # Run TypeScript type checking

Tech Stack

  • Framework: Next.js 14 (App Router)
  • Language: TypeScript 5 (strict mode)
  • UI Library: React 18, Shadcn UI & Radix UI
  • Styling: Tailwind CSS 3.4+ with CSS variables
  • Icons: Lucide React
  • Database: Supabase (PostgreSQL)
  • State: React hooks / URL search params

Project Structure

app/                    # Next.js App Router pages and components
  components/           # Page-specific components
  globals.css           # Global styles with CSS variables
components/
  ui/                   # Shadcn UI base components
lib/
  supabase/             # Supabase client configuration
  utils.ts              # Utility functions (cn() for class merging)
types/
  index.ts              # TypeScript interfaces and types

Code Style

General Principles

  • Write concise, technical TypeScript code
  • Use functional and declarative patterns; avoid classes
  • Prefer iteration and modularization over duplication
  • Structure files: imports, types/interfaces, component, export

Naming Conventions

  • Directories: lowercase-kebab-case (e.g., components/hero-section)
  • Files: kebab-case.tsx (e.g., prompt-card.tsx)
  • Components: PascalCase with named exports (e.g., export function PromptCard)
  • Variables/functions: camelCase
  • Constants: UPPER_SNAKE_CASE
  • Types/interfaces: PascalCase

TypeScript Usage

  • Use TypeScript for all code; prefer interfaces over types
  • Avoid any; use unknown when unsure
  • Enable strict type checking
  • Use explicit return types for functions where helpful

Imports

  • Use absolute imports with @/ alias (configured via tsconfig.json)
  • Organize: external deps first, then internal modules
  • Group: React imports, third-party, internal imports
  • Avoid default imports for components; use named exports

Example:

import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { cva, type VariantProps } from "class-variance-authority"

import { cn } from "@/lib/utils"
import { Button } from "@/components/ui/button"

UI and Styling

Tailwind CSS

  • Style exclusively with Tailwind utilities
  • Mobile-first responsive design
  • Use cn() utility (@/lib/utils) for conditional classes

Shadcn UI

  • Use Shadcn UI for core components (located in components/ui/)
  • Customize via cn() utility
  • Extend components rather than modifying source
  • Components use CSS variables for theming (see tailwind.config.ts)

Component Pattern

Follow the Shadcn UI pattern for components:

import * as React from "react"
import { cn } from "@/lib/utils"

export interface ComponentProps {
  className?: string
}

export function Component({ className, ...props }: ComponentProps) {
  return (
    <div className={cn("base-styles", className)} {...props} />
  )
}

'use client' Directive

  • Add 'use client' at the top of files with:
    • React hooks (useState, useEffect, etc.)
    • Event handlers
    • Browser APIs
    • Client-side interactivity

Example from prompt-card.tsx:

'use client';

import { useState } from 'react';
// Component uses useState and event handlers

Error Handling

  • Implement error boundaries for data fetching
  • Check client vs server component issues
  • Validate environment variables
  • Use try/catch for async operations

Environment Variables

  • Never commit .env files
  • Required variables (document in .env.example):
    • NEXT_PUBLIC_SUPABASE_URL
    • NEXT_PUBLIC_SUPABASE_ANON_KEY

Key Patterns

Supabase Client

Located at lib/supabase/client.ts:

import { createClient } from '@supabase/supabase-js';

const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!;
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!;

export const supabase = createClient(supabaseUrl, supabaseAnonKey);

Database Types

Defined in types/index.ts:

export interface Category {
  id: string;
  name: string;
  slug: string;
  created_at: string;
}

export interface Prompt {
  id: string;
  title: string;
  content: string;
  category_id: string | null;
  image_url: string | null;
  created_at: string;
  category?: Category | null;
}

Class Merging Utility

Located at lib/utils.ts:

import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs))
}

Performance Optimization

  • Minimize 'use client'; favor Server Components by default
  • Only add 'use client' for hooks, event handlers, browser APIs
  • Wrap client components in Suspense with fallbacks
  • Use next/image with explicit width/height

Git Conventions

  • Follow conventional commits: feat:, fix:, chore:, docs:, refactor:
  • Keep commits atomic and focused

Resources