Personal academic website for Zhuo Cai, built with Astro.
| Layer | Tool |
|---|---|
| Framework | Astro 5 (SSG, island architecture) |
| UI components | Astro + React islands (@astrojs/react) |
| Content | Astro Content Collections (JSON data files) |
| Styles | Scoped CSS + global CSS variables |
| Type-safety | TypeScript (astro check) |
npm run dev # Start local dev server at http://localhost:4321
npm run build # Production build → dist/
npm run preview # Preview production build locally
npm run check # TypeScript + Astro type-check
npm run sync:papers # Download PDFs listed as local-pdf in publications
npm run sync:research # Sync private research registry → src/content/Each file is a .json conforming to the publications schema in src/content/config.ts. Key fields:
| Field | Description |
|---|---|
title |
Full paper title |
authors |
Array of author name strings |
venue / venueShort |
Full and abbreviated venue |
year |
Publication year |
type |
conference | journal | workshop | manuscript |
status |
Free string (e.g., "Accepted", "Under submission") |
tags |
Keyword tags for filtering |
selected |
Pin to homepage featured section |
abstract |
Abstract text |
contentAvailability |
local-pdf | external-pdf | abstract-only |
links |
Object with optional paper, preprint, doi, code, slides, video, scholar URLs |
Generated by npm run sync:research from research/directions/*.md. Each file is a .json conforming to the directions schema:
| Field | Description |
|---|---|
title |
Direction title |
summary |
1–2 sentence pitch |
description |
Full paragraph for the homepage card |
tags |
Keyword tags |
status |
planned | active | under-submission |
relatedPublications |
Array of publication IDs (filename stems from src/content/publications/) |
links |
Object with optional preprint and code URLs |
The research/ folder is gitignored. It stores private manuscripts and research directions as structured Markdown files with YAML frontmatter. Nothing in this folder is committed or publicly accessible.
research/
manuscripts/ ← papers under submission or in preparation
tx-order.md
no-tx-fee.md
directions/ ← ongoing/planned research without a paper yet
dynamic-snarks.md
tfm-delayed-inclusion.md
tfm-dag-sharding.md
parallel-execution-incentive.md
README.md ← detailed field reference (this folder)
.sync-manifest.json ← auto-generated by sync script; do not edit
Every entry has a visibility field in its YAML frontmatter:
| Value | Effect |
|---|---|
private |
Entry stays entirely local. Nothing written to website. |
public |
Sync script writes a .json into src/content/. Entry appears on website after rebuild. |
To publish an entry:
- Open the relevant
.mdfile inresearch/manuscripts/orresearch/directions/. - Change
visibility: private→visibility: public. - Run
npm run sync:research. - Restart the dev server (
npm run dev) or rebuild (npm run build).
To retract an entry:
- Change
visibility: public→visibility: private. - Run
npm run sync:research— the previously generated.jsonis deleted automatically.
---
title: "Full paper title"
type: manuscript
visibility: private # 'private' | 'public'
tags:
- consensus
- incentive-design
status: "Under submission" # shown verbatim on website
venue: "ACM Symposium on Principles of Distributed Computing"
venueShort: "PODC 2026"
year: 2026
authors:
- "Zhuo Cai"
- "Co-Author Name"
localRepoPath: ~/research-writing/tx-order # path to LaTeX writeup
selected: false # true → pin to homepage featured section
abstract: >
Abstract text (shown on website when visibility: public).
note: "Under review. Do not circulate."
---
## Notes
Free-form Markdown — personal notes, open problems, related work pointers.
AI reads this body when you ask for help with the manuscript.---
title: "Research direction title"
type: direction
visibility: private # 'private' | 'public'
tags:
- transaction-fee-mechanisms
- blockchain
status: active # 'planned' | 'active' | 'under-submission'
summary: >
1–2 sentence homepage preview pitch.
description: >
Full paragraph shown on the homepage card.
relatedPublications: # IDs from src/content/publications/ (filename stem)
- rogue
links:
preprint: "" # optional public URL
code: "" # optional public URL
---
## Notes
Free-form Markdown context for personal use and AI assistance.# Manuscript
cp research/manuscripts/tx-order.md research/manuscripts/new-paper.md
# edit frontmatter and notes
# Direction
cp research/directions/dynamic-snarks.md research/directions/new-direction.md
# edit frontmatter and notesThe JSON slug is derived from the filename stem (e.g., new-paper.md → src/content/publications/new-paper.json).
When asking GitHub Copilot (or any AI) to help with a research entry:
- Open the relevant
.mdfile inresearch/manuscripts/orresearch/directions/. - The free-form Notes body provides AI with full context.
- For manuscripts, AI can read the LaTeX writeup at
localRepoPathfor precise assistance (abstract rewriting, related-work checks, proof gap identification). - After AI edits the
abstractordescriptionfrontmatter field, runnpm run sync:researchto push the update to the website.
Example prompt: "Read the manuscript at localRepoPath in research/manuscripts/tx-order.md and rewrite the abstract field to be suitable for a PODC audience."
src/
components/ Astro + React UI components
content/
config.ts Zod schemas for all collections
publications/ JSON files (committed or sync-generated)
directions/ JSON files (sync-generated from research/)
data/
site.ts Profile metadata, hero copy, quick links
projects.ts Research theme descriptions
layouts/
BaseLayout.astro HTML shell, <head>, nav, footer
lib/
publications.ts getCollection helpers + serialize
directions.ts getCollection helpers + serialize
publication-ui.ts Primary action + secondary links logic
pages/ Astro page routes
styles/
global.css Design tokens + all utility classes
public/
papers/ Static PDF files (synced by sync:papers)
scripts/
sync-paper-assets.mjs Download PDFs referenced as local-pdf
sync-research.mjs Sync research/ registry → src/content/
research/ Gitignored private registry (see above)