Imported from Ron-RONZZ-org/ronPortfolio (
AGENTS.md). Install upstream withnpx skills add Ron-RONZZ-org/ronPortfolio. Copyright stays with the author.
AGENTS.md — Root Project Rules for ronPortfolio
This is the canonical, repo-wide instruction file for AI agents working on ronPortfolio.
Hierarchical Context Model
Agents must follow this rule:
When working inside a directory, load the nearest
AGENTS.mdfile and merge it with parentAGENTS.mdfiles up to root.
Local rules override global rules.
Context resolution order (highest priority first):
AGENTS-[module].mdin module directories — module-specific contextAGENTS.mdin current working directory (if present)- Root
AGENTS.md— global project rules
Project Overview
ronPortfolio is Ron's personal portfolio website — a static site built with Astro. It showcases Ron's professional journey, achievements, education, personal projects, and a blog. The site supports four languages (EN/FR/ZH/EO) via client-side i18n switching.
Language and Naming Conventions
- All code, comments, and commit messages in English
- Variable/function names in camelCase
- Content collection files:
{language}-{slug}.md(e.g.,en-weng.md,fr-weng.md) - Astro components:
PascalCase.astro - Page routes: kebab-case (
/blog/my-first-post) - Static assets: kebab-case (
profile-photo.png)
Tech Stack
| Category | Choice |
|---|---|
| Framework | Astro 5.x (static site generator) |
| Content | Markdown + YAML frontmatter via Astro Content Collections |
| i18n | Client-side JS with build-time inlined JSON translations |
| Blog search | MiniSearch (client-side, embedded index) |
| CSS | Single global stylesheet (src/styles/global.css) |
| Deployment | GitHub Pages via GitHub Actions |
| Package manager | npm |
| Testing | Playwright (e2e, tests/e2e.mjs) |
Dependency management
This project uses npm for dependency management.
package-lock.jsonmust be committed (required for CI reproducibility)- Install:
npm install - Add dependency:
npm install <pkg> - Dev dependency:
npm install --save-dev <pkg>
Project Structure
ronPortfolio/
├── src/
│ ├── content/
│ │ ├── config.ts # Content collection schemas (Zod)
│ │ ├── cv/ # CV milestones (per-language .md files)
│ │ └── blog/ # Blog posts (per-language .md files)
│ ├── layouts/Base.astro # Shared layout (i18n, head, nav)
│ ├── pages/
│ │ ├── index.astro # Landing page (profile + links)
│ │ ├── cv.astro # CV timeline
│ │ ├── contact.astro # Contact page
│ │ ├── portfolio.astro # Portfolio listing
│ │ ├── research.astro # Academic research links
│ │ ├── projects.astro # Programming projects
│ │ ├── blog/
│ │ │ ├── index.astro # Blog listing (search/sort/filter)
│ │ │ └── [slug].astro # Individual blog post
│ │ ├── language/ # Language picker fallback
│ │ └── 404.astro
│ └── styles/global.css
├── public/
│ ├── CNAME # Custom domain (rongzhou.me)
│ └── img/ # Static images
├── examples/blog/ # Sample blog articles (copy to content/)
├── translations/ # i18n string tables (JSON)
├── tests/e2e.mjs # Playwright end-to-end tests
└── astro.config.mjs
Coding Guidelines
- Content-first — CV and blog content lives in
src/content/as Markdown with YAML frontmatter. Content collections validate schemas at build time. - Zero-JS where possible — Pages that don't need interactivity should ship no client JavaScript. Only the i18n system and blog search use client JS.
- i18n via
data-i18n— All user-facing text usesdata-i18n="key"attributes. Translation keys are defined intranslations/translation-strings.json. The inline script inBase.astrohandles language detection and text swapping. - Language-specific content — CV milestones and blog posts with per-language variants use the
languagefield in frontmatter. Client JS shows/hides viadata-lang-contentattributes. - CV milestones — Each milestone is a separate
.mdfile insrc/content/cv/. Use thecategoryfield (education/work/achievement/personal) and numericstart/endyears for sorting. - Blog posts — Each post is a
.mdfile insrc/content/blog/. Required frontmatter:id,title,created,published,tags. The blog landing page auto-generates search index and filter controls. - No redundant dependencies — Prefer Astro-native features and minimal client libraries. Currently only
minisearchis used as a client dependency. - Responsive design — All pages must work on mobile. Breakpoint at 768px. Test with
npm run build && node tests/e2e.mjs. - Semantic HTML — Use
<header>,<main>,<nav>,<article>appropriately. Maintain the dark theme color scheme defined in CSS variables.
Content Collection Schemas
CV entry (src/content/cv/)
CV uses a split content model identical to portfolio — meta.json holds shared fields and translations, per-language .md stubs hold body content only.
meta.json — single source of truth for shared fields and translations:
{
"weng": {
"category": "personal",
"start": 2020,
"icon": "📱",
"logo": "https://...",
"sortOrder": 1,
"translations": {
"en": { "title": "Developed First App : WENG" },
"fr": { "title": "Développement de la première application : WENG" }
},
"body": {
"en": "- Bullet point 1\n- Nested:\n - Sub point",
"fr": "..."
}
}
}
Per-language .md stubs — minimal frontmatter + body:
---
id: "unique-id"
language: "en"
---
- Bullet point 1
- Nested:
- Sub point
Render-time merge: cv.astro imports meta.json and enriches each collection entry with shared fields and translated title.
Portfolio entry (src/content/portfolio/)
Portfolio uses a split content model to avoid duplicating shared fields across language variants:
meta.json — single source of truth for shared fields and translations:
{
"france-stats": {
"category": "software",
"url": "https://france-stats.org",
"priority": 100,
"logo": "/img/logo.svg",
"translations": {
"en": { "title": "Title", "description": "Desc" },
"fr": { "title": "Titre", "description": "Desc" },
"zh": { "title": "标题", "description": "描述" },
"eo": { "title": "Titolo", "description": "Priskribo" }
},
"body": {
"en": "English body...",
"fr": "Corps français..."
}
}
}
Per-language .md stubs — minimal frontmatter + body:
---
id: "unique-id"
language: "en" # en | fr | zh | eo
---
Optional body text...
priority(number, optional): descending sort, higher = shown first- Category values:
software|research|association
Render-time merge: portfolio.astro imports meta.json and enriches each collection entry with shared fields and translated title/description.
Blog post (src/content/blog/*.md)
---
id: "unique-id"
title: "Post Title"
description: "Short summary"
tags: ["tech", "life"]
series: "Series Name" # optional
created: "2025-06-23"
modified: "2025-06-23" # optional
language: "en"
published: true
---
Content in markdown...
Development Workflow
npm install # Install dependencies
npm run dev # Start dev server (localhost:4321)
npm run build # Build to dist/
npm run preview # Preview built site (localhost:4322)
node tests/e2e.mjs # Run e2e tests (requires preview server running)
- CI check:
npm run buildmust succeed before pushing. - Testing: After any structural change, run the e2e tests.
- Deployment: Push to
main→ GitHub Actions auto-deploys.
Documentation Standards
- The
AGENTS.mdin this directory is the single source of truth for project conventions. - Content collection schemas are documented in
src/content/config.ts(Zod schemas with comments). - README.md provides a quickstart for human contributors.
- Module-level AGENTS files should be created when a subdirectory grows to warrant its own rules (e.g., if a CLI tool or API server is added).
Commit Message Format
Use Conventional Commits:
feat:— new feature or capabilityfix:— bug fixchore:— maintenance, config, or cleanupdocs:— documentation onlytest:— adding or fixing testsrefactor:— code restructuring without behavior change
What to Avoid
- Do not add JavaScript frameworks (React, Vue, Svelte) unless a component genuinely needs client-side reactivity
- Do not use external CSS frameworks (Tailwind, Bootstrap) — maintain the custom dark theme
- Do not add server-side rendering (SSR) — the site is fully static (SSG)
- Do not commit
.envfiles, secrets, or API keys - Do not introduce a CMS backend — content is file-based via Content Collections
Module-Level AGENTS Files
No module-level AGENTS files are currently defined. The project is a flat Astro application without standalone submodules.
If a future module (e.g., a CLI tool, API server, or separate build script) is added to a subdirectory, it should get its own AGENTS-[module].md in that directory, following the template.
Dependency and Inheritance Map
Root AGENTS.md (global rules)
│
└── (future: AGENTS.md in any subdirectory — local context)
Local rules override global rules. Module-level files focus on domain-specific behavior, constraints, and invariants.