docs: refresh AGENTS and add Claude instructions

This commit is contained in:
zguiyang
2026-03-13 14:11:57 +08:00
parent a208bab7ea
commit 30b097cc74
2 changed files with 91 additions and 78 deletions

162
AGENTS.md
View File

@@ -4,22 +4,50 @@ This file provides guidelines for AI agents operating in this repository.
## Project Overview ## 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). 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 (`en` default, `zh` under `/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 `pnpm` commands in documentation, scripts, and instructions
- Do not use `npm`, `yarn`, or `bun` commands in this repo
- If existing text shows `npm run ...`, replace with `pnpm ...`
Examples:
```bash
pnpm install
pnpm dev
pnpm build
pnpm preview
```
## Build Commands ## Build Commands
```bash ```bash
# Install dependencies
pnpm install
# Development server # Development server
npm run dev pnpm dev
# Build for production # Build for production
npm run build pnpm build
# Preview production build locally # Preview production build locally
npm run preview pnpm preview
``` ```
No lint or test commands are configured. Run `npm run build` to verify changes. No lint or test commands are configured. Run `pnpm build` to verify changes.
## Code Style Guidelines ## Code Style Guidelines
@@ -30,7 +58,7 @@ No lint or test commands are configured. Run `npm run build` to verify changes.
- Prioritize readability over cleverness - Prioritize readability over cleverness
### Imports ### Imports
- Use `@/` alias for src imports (configured in tsconfig.json) - Use `@/` alias for src imports (configured in `tsconfig.json`)
- Order imports: React → libraries → components → utilities - Order imports: React → libraries → components → utilities
- Use named exports for components and utilities - Use named exports for components and utilities
@@ -47,8 +75,8 @@ import { useState, useEffect } from 'react';
``` ```
### TypeScript ### TypeScript
- Use TypeScript for all new files (.ts, .tsx) - Use TypeScript for all new files (`.ts`, `.tsx`)
- Extend Astro's strict TypeScript config - Extend Astro strict TypeScript config
- Use explicit types for component props - Use explicit types for component props
- Avoid `any`, use `unknown` or specific types - Avoid `any`, use `unknown` or specific types
@@ -60,109 +88,87 @@ interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>,
} }
// Avoid // Avoid
interface ButtonProps { ... } // too verbose const handleClick = (e: any) => { ... }
const handleClick = (e: any) => { ... } // no type
``` ```
### Components ### Components
**Astro Components (.astro)**: **Astro Components (`.astro`)**:
- Use frontmatter fence `---` at top - Use frontmatter fence `---` at top
- Separate imports, props, and logic - Separate imports, props, and logic
- Use `client:only="react"` for React components that need browser APIs - Use `client:only="react"` for React components needing browser APIs
- Use `client:load` for interactive components - Use `client:load` for interactive components that should hydrate on load
- Static content should not have client directives - Static content should not have client directives
**React Components (.tsx)**: **React Components (`.tsx`)**:
- Use `React.forwardRef` for components that need refs - Use `React.forwardRef` for components that need refs
- Use class-variance-authority (CVA) for component variants - Use class-variance-authority (CVA) for component variants where applicable
- Use Radix UI primitives when available - Use Radix UI primitives when available
- Export components as named exports - Prefer named exports (unless file already follows a default-export pattern)
### Styling (Tailwind CSS) ### Styling (Tailwind CSS)
- Use Tailwind utility classes exclusively - Use Tailwind utility classes as the primary styling approach
- Use `cn()` utility to merge classes with conditional logic - Use `cn()` utility to merge classes with conditional logic
- Avoid custom CSS; use Tailwind equivalents - Avoid inline style objects unless strictly necessary
- Dark mode: prefix colors with `dark:` modifier - Dark mode styles should use `dark:` variants and existing tokens
```tsx
// Good
<div className={cn(
"base-classes",
variant === "primary" && "primary-classes",
className
)} />
// Avoid
<div style={{ display: 'flex', padding: '16px' }}>
```
### i18n (Internationalization) ### i18n (Internationalization)
- All UI text must be in `src/i18n/translations.ts` (and related i18n helpers)
- All UI text must be in `src/i18n/translations.ts` - Use translation helpers (`useTranslations(lang)`)
- Use `useTranslations(lang)` hook for text - Avoid hardcoded strings in `.astro` and `.tsx` when user-facing text is localized
- Avoid hardcoded strings in .astro and .tsx files - Keep EN/ZH content parity for shared pages/components
- 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);
<h1>{t('hero.greeting')} {name}</h1>
```
### Naming Conventions ### Naming Conventions
- **Components**: PascalCase (e.g., `Button`, `GlassHeader`) - **Components**: PascalCase (e.g., `GlassHeader`)
- **Files**: kebab-case for Astro pages, PascalCase for React components - **Files**: kebab-case for Astro routes, PascalCase for React components
- **Variables/functions**: camelCase - **Variables/functions**: camelCase
- **Constants**: SCREAMING_SNAKE_CASE - **Constants**: SCREAMING_SNAKE_CASE
- **Types/Interfaces**: PascalCase with `Props` suffix for component props - **Types/Interfaces**: PascalCase, with `Props` suffix for component props
### Error Handling ### Error Handling
- Use TypeScript types to prevent runtime errors - Use TypeScript types to prevent runtime errors
- Handle null/undefined cases explicitly - Handle null/undefined explicitly
- Use optional chaining `?.` and nullish coalescing `??` - Prefer optional chaining (`?.`) and nullish coalescing (`??`)
- No try-catch unless handling specific async errors - Avoid broad `try/catch` unless handling known async boundaries
### Astro-Specific ## Astro-Specific Conventions
- Pages use file-based routing (`src/pages/**/*.astro`)
- Dynamic routes: `[slug].astro`, `[category].astro` - Pages use file-based routing under `src/pages/`
- Layouts in `src/layouts/` - English routes are root-level; Chinese routes are under `src/pages/zh/`
- Components in `src/components/` - Blog content uses markdown posts in:
- Use Content Collections for blog posts (MDX in `src/pages/blog/posts/`) - `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 ## Project Structure
``` ```text
src/ src/
├── components/ # UI components (React & Astro) ├── components/ # UI components (React & Astro)
│ ├── blog/ # Blog-specific components │ ├── blog/ # Blog-specific components (meta, lists, comments)
│ ├── layout/ # Layout components │ ├── layout/ # Layout helper components (TOC, blog nav)
│ ├── markdown/ # Markdown rendering components │ ├── markdown/ # Markdown rendering components
│ └── ui/ # Reusable UI primitives │ └── ui/ # Reusable UI primitives
├── layouts/ # Page layouts (Layout.astro, BlogLayout, etc.) ├── layouts/ # Shared page layouts
├── pages/ # Routes (auto-routed by filename) ├── pages/ # Routes (including blog and locale routes)
│ ├── blog/ # Blog pages & posts │ ├── blog/
│ └── zh/ # Chinese locale pages │ └── zh/
├── lib/ # Data & utilities ├── lib/
── data/ # Static data (personal-info, projects, services) ── data/ # Personal info, projects, services
├── styles/ # Global CSS │ └── utils.ts
├── i18n/ # Internationalization ├── i18n/ # Locale constants, translation maps, helpers
│ └── translations.ts ├── styles/ # Global and integration styles
├── types/ # TypeScript type definitions ├── types/ # Type definitions
└── utils/ # Utility functions └── utils/ # Utility functions for blog and helpers
``` ```
## Important Notes ## Important Notes
- This is a bilingual site (EN/ZH); maintain both locales - This is a bilingual site (EN/ZH); maintain both locales
- Default language is English (`defaultLang = 'en'`) - Default language is English (`defaultLang = 'en'`)
- Chinese pages are under `/zh/` prefix - Use `Astro.currentLocale` to detect language context
- Use `Astro.currentLocale` to detect current language - Keep `services` semantics as capabilities/skill offerings
- The `services` section shows skills/capabilities, not literal services - Components depending on `window`, `document`, or `localStorage` must use proper client directives
- Include `client:only="react"` for components using browser APIs (localStorage, window, etc.) - Preserve existing integrations: MDX, sitemap i18n, Waline comments, and analytics behavior

7
Claude.md Normal file
View File

@@ -0,0 +1,7 @@
# Claude.md
Please follow [`AGENTS.md`](./AGENTS.md) as the canonical agent-instruction source of truth.
Key requirement reminder:
- Use `pnpm` as the package manager (`pnpm install`, `pnpm dev`, `pnpm build`, `pnpm preview`)
- Do not use `npm`, `yarn`, or `bun` commands in this repository