5.7 KiB
5.7 KiB
AGENTS.md
This file provides guidelines for AI agents operating in this repository.
Project Overview
This is a bilingual personal portfolio site built with Astro 5, React 19, and Tailwind CSS 4.
Current project capabilities from codebase:
- EN/ZH localized site with Astro i18n routing (
endefault,zhunder/zh) - Portfolio pages: home, projects, services, now, hire, about
- Blog system with posts, tag pages, and category pages in both locales
- React interactive islands for header/theme switch, typewriter effect, back-to-top, comments, and animations
- Waline comment integration (
@waline/client) and Umami analytics script in production - SEO/sitemap integration via
@astrojs/sitemap
Package Manager Rule (Mandatory)
Use pnpm only for dependency and script commands.
- Always use
pnpmcommands in documentation, scripts, and instructions - Do not use
npm,yarn, orbuncommands in this repo - If existing text shows
npm run ..., replace withpnpm ...
Examples:
pnpm install
pnpm dev
pnpm build
pnpm preview
Build Commands
# Install dependencies
pnpm install
# Development server
pnpm dev
# Build for production
pnpm build
# Preview production build locally
pnpm preview
No lint or test commands are configured. Run pnpm 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 intsconfig.json) - Order imports: React → libraries → components → utilities
- Use named exports for components and utilities
// 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 strict TypeScript config
- Use explicit types for component props
- Avoid
any, useunknownor specific types
// Good
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean;
}
// Avoid
const handleClick = (e: any) => { ... }
Components
Astro Components (.astro):
- Use frontmatter fence
---at top - Separate imports, props, and logic
- Use
client:only="react"for React components needing browser APIs - Use
client:loadfor interactive components that should hydrate on load - Static content should not have client directives
React Components (.tsx):
- Use
React.forwardReffor components that need refs - Use class-variance-authority (CVA) for component variants where applicable
- Use Radix UI primitives when available
- Prefer named exports (unless file already follows a default-export pattern)
Styling (Tailwind CSS)
- Use Tailwind utility classes as the primary styling approach
- Use
cn()utility to merge classes with conditional logic - Avoid inline style objects unless strictly necessary
- Dark mode styles should use
dark:variants and existing tokens
i18n (Internationalization)
- All UI text must be in
src/i18n/translations.ts(and related i18n helpers) - Use translation helpers (
useTranslations(lang)) - Avoid hardcoded strings in
.astroand.tsxwhen user-facing text is localized - Keep EN/ZH content parity for shared pages/components
Naming Conventions
- Components: PascalCase (e.g.,
GlassHeader) - Files: kebab-case for Astro routes, PascalCase for React components
- Variables/functions: camelCase
- Constants: SCREAMING_SNAKE_CASE
- Types/Interfaces: PascalCase, with
Propssuffix for component props
Error Handling
- Use TypeScript types to prevent runtime errors
- Handle null/undefined explicitly
- Prefer optional chaining (
?.) and nullish coalescing (??) - Avoid broad
try/catchunless handling known async boundaries
Astro-Specific Conventions
- Pages use file-based routing under
src/pages/ - English routes are root-level; Chinese routes are under
src/pages/zh/ - Blog content uses markdown posts in:
src/pages/blog/posts/src/pages/zh/blog/posts/
- Layouts are in
src/layouts/ - Reusable UI/components are in
src/components/ - Data source modules are in
src/lib/data/
Project Structure
src/
├── components/ # UI components (React & Astro)
│ ├── blog/ # Blog-specific components (meta, lists, comments)
│ ├── layout/ # Layout helper components (TOC, blog nav)
│ ├── markdown/ # Markdown rendering components
│ └── ui/ # Reusable UI primitives
├── layouts/ # Shared page layouts
├── pages/ # Routes (including blog and locale routes)
│ ├── blog/
│ └── zh/
├── lib/
│ ├── data/ # Personal info, projects, services
│ └── utils.ts
├── i18n/ # Locale constants, translation maps, helpers
├── styles/ # Global and integration styles
├── types/ # Type definitions
└── utils/ # Utility functions for blog and helpers
Important Notes
- This is a bilingual site (EN/ZH); maintain both locales
- Default language is English (
defaultLang = 'en') - Use
Astro.currentLocaleto detect language context - Keep
servicessemantics as capabilities/skill offerings - Components depending on
window,document, orlocalStoragemust use proper client directives - Preserve existing integrations: MDX, sitemap i18n, Waline comments, and analytics behavior