diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..505e39b --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,168 @@ +# AGENTS.md + +This file provides guidelines for AI agents operating in this repository. + +## Project Overview + +A modern personal portfolio website built with **Astro 5**, **React 19**, and **Tailwind CSS 4**. Features glassmorphism design, animations via Framer Motion, and full i18n support (EN/ZH). + +## Build Commands + +```bash +# Development server +npm run dev + +# Build for production +npm run build + +# Preview production build locally +npm run preview +``` + +No lint or test commands are configured. Run `npm run build` to verify changes. + +## Code Style Guidelines + +### General Principles +- Write concise, self-documenting code +- Avoid unnecessary comments (only explain complex logic) +- Follow existing patterns in the codebase +- Prioritize readability over cleverness + +### Imports +- Use `@/` alias for src imports (configured in tsconfig.json) +- Order imports: React → libraries → components → utilities +- Use named exports for components and utilities + +```typescript +// Good +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"; + +// Avoid +import utils from '@/lib/utils'; +import { useState, useEffect } from 'react'; +``` + +### TypeScript +- Use TypeScript for all new files (.ts, .tsx) +- Extend Astro's strict TypeScript config +- Use explicit types for component props +- Avoid `any`, use `unknown` or specific types + +```typescript +// Good +interface ButtonProps extends React.ButtonHTMLAttributes, + VariantProps { + asChild?: boolean; +} + +// Avoid +interface ButtonProps { ... } // too verbose +const handleClick = (e: any) => { ... } // no type +``` + +### Components + +**Astro Components (.astro)**: +- Use frontmatter fence `---` at top +- Separate imports, props, and logic +- Use `client:only="react"` for React components that need browser APIs +- Use `client:load` for interactive components +- Static content should not have client directives + +**React Components (.tsx)**: +- Use `React.forwardRef` for components that need refs +- Use class-variance-authority (CVA) for component variants +- Use Radix UI primitives when available +- Export components as named exports + +### Styling (Tailwind CSS) +- Use Tailwind utility classes exclusively +- Use `cn()` utility to merge classes with conditional logic +- Avoid custom CSS; use Tailwind equivalents +- Dark mode: prefix colors with `dark:` modifier + +```tsx +// Good +
+ +// Avoid +
+``` + +### i18n (Internationalization) + +- All UI text must be in `src/i18n/translations.ts` +- Use `useTranslations(lang)` hook for text +- Avoid hardcoded strings in .astro and .tsx files +- Structure translations by section (nav, hero, about, etc.) + +```typescript +// translations.ts +export const translations = { + en: { hero: { greeting: 'Hello, I'm' } }, + zh: { hero: { greeting: '你好,我是' } } +} + +// In component +const t = useTranslations(lang); +

{t('hero.greeting')} {name}

+``` + +### Naming Conventions +- **Components**: PascalCase (e.g., `Button`, `GlassHeader`) +- **Files**: kebab-case for Astro pages, PascalCase for React components +- **Variables/functions**: camelCase +- **Constants**: SCREAMING_SNAKE_CASE +- **Types/Interfaces**: PascalCase with `Props` suffix for component props + +### Error Handling +- Use TypeScript types to prevent runtime errors +- Handle null/undefined cases explicitly +- Use optional chaining `?.` and nullish coalescing `??` +- No try-catch unless handling specific async errors + +### Astro-Specific +- Pages use file-based routing (`src/pages/**/*.astro`) +- Dynamic routes: `[slug].astro`, `[category].astro` +- Layouts in `src/layouts/` +- Components in `src/components/` +- Use Content Collections for blog posts (MDX in `src/pages/blog/posts/`) + +## Project Structure + +``` +src/ +├── components/ # UI components (React & Astro) +│ ├── blog/ # Blog-specific components +│ ├── layout/ # Layout components +│ ├── markdown/ # Markdown rendering components +│ └── ui/ # Reusable UI primitives +├── layouts/ # Page layouts (Layout.astro, BlogLayout, etc.) +├── pages/ # Routes (auto-routed by filename) +│ ├── blog/ # Blog pages & posts +│ └── zh/ # Chinese locale pages +├── lib/ # Data & utilities +│ └── data/ # Static data (personal-info, projects, services) +├── styles/ # Global CSS +├── i18n/ # Internationalization +│ └── translations.ts +├── types/ # TypeScript type definitions +└── utils/ # Utility functions +``` + +## Important Notes + +- This is a bilingual site (EN/ZH); maintain both locales +- Default language is English (`defaultLang = 'en'`) +- Chinese pages are under `/zh/` prefix +- Use `Astro.currentLocale` to detect current language +- The `services` section shows skills/capabilities, not literal services +- Include `client:only="react"` for components using browser APIs (localStorage, window, etc.)