Homepage Generator logo

Homepage Generator

Community
wanshuiyin
homepage-generator

Generate a fact-checked academic personal homepage from a CV, optionally augmented by an existing manual homepage and an assets directory. Produces editable structured source files (profile.yml + publications.bib + bio.md + news.md) and a single-file HTML page. Uses Codex MCP for independent factual review against DBLP. Optionally uses Gemini multimodal for screenshot critique when available. Use when the user says '做个学术主页', '从CV生成主页', 'aris-homepage', 'generate academic homepage from CV', 'PhD homepage', 'GitHub Pages personal site', or wants a fact-checked academic site.

Overview

Publisherwanshuiyin
RepositoryARIS-in-AI-Offer
Skill namehomepage-generator
Stars
587
Forks
22
Bundled files
5
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 5 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by wanshuiyin on GitHub. Read the source before you install it.

Installation

Install the Homepage Generator AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/wanshuiyin/ARIS-in-AI-Offer/tree/main/skills/homepage-generator
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/wanshuiyin/ARIS-in-AI-Offer.git /tmp/ARIS-in-AI-Offer
mkdir -p .claude/skills
cp -r /tmp/ARIS-in-AI-Offer/skills/homepage-generator .claude/skills/homepage-generator
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Homepage Generator in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Homepage Generator on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Homepage Generator is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

/homepage-generator — fact-checked academic homepage from CV

The only personal-site generator that fact-checks your CV before publishing. Cross-model adversarial review: the LLM that drafts your homepage never grades it. A deterministic Python pass checks your publication claims against DBLP on every render; an optional fresh Codex thread then reviews the prose and framing.

When to use

Generate a single-file HTML academic homepage. Optimized for PhD candidates, postdocs, and early-career researchers with public publications. v1 ships the theory-minimal persona (text-heavy academic page in the Zhxie / Avicenna lineage); active-researcher (paper thumbnails + news ticker variant) is planned.

Use when the user says 做个学术主页 · from CV generate homepage · aris-homepage · PhD personal site · GitHub Pages homepage.

Do NOT use for: portfolio sites needing image galleries; newsletter-funnel sites needing audience metrics; pure blog sites (use Jekyll/Hugo); tenured-faculty pages with student/teaching as top-level sections (use academicpages).

Public demo

A real-world dogfood example: https://wanshuiyin.github.io/ — homepage generated by this skill from a CV + the maintainer's previous manual page. Use it as a style and capability reference; do not copy any names, affiliations, advisors, awards, paper titles, or filenames into your own examples or tests (see Privacy below).

Quick start

This repo ships no installer — there is no aris-homepage executable on any platform. Every invocation is python <path>/aris_homepage.py, and the path is relative to wherever you are standing (note the cd ./site below). On Windows also read WINDOWS_en.md / WINDOWS.md.

bash
# Step 1 — bootstrap workspace from CV
python tools/aris_homepage.py init --from-cv ./cv.pdf --out ./site
cd ./site

# Step 2 — calling LLM agent (Claude / your agent) reads .aris-homepage/EXTRACTION_HANDOFF.md,
#          then writes the extraction JSON to .aris-homepage/extraction.json.
#          This step is NOT automated by the CLI — it's a designed handoff so the agent
#          can use richer context (manual homepage URL, asset folder, your judgement).

# Step 3 — persist the extracted JSON into editable source files
#          (we cd'd into ./site above, so the script is one level up now)
python ../tools/aris_homepage.py finalize

# Step 4 — review + tweak
$EDITOR profile.yml publications.bib bio.md news.md EXTRACTION_REVIEW.md

# Step 5 — render with fact-check (writes index.html + audit-report.md)
python ../tools/aris_homepage.py render --persona theory-minimal

Windows note. Beyond the invocation form above, Windows has its own traps: the python3 alias stub, silent .py file association, non-ASCII pdftotext paths, and the SSL certificate store. WINDOWS_en.md / WINDOWS.md walk through all of them.

Input model — three sources for the LLM agent

The init CLI only handles the CV → text conversion. The other two inputs are consumed by the calling LLM agent when it fills extraction.json. Recommend supplying all three for best results:

InputHow to supplyPurpose
CV--from-cv cv.docx/pdf/txt on the CLIThe factual source — identity, education, jobs, publications, awards
GitHub repos (v1.1)--from-repos owner/repo,owner/repo2 on the CLIThe project-evidence source — stars / releases / topics / README per repo; merged into News + featured projects (issue #2)
Manual homepageProvide URL in the prompt; the agent uses WebFetchThe editorial source — section ordering, topic groupings, tone, link priorities, photo URL
Assets directoryProvide path in the prompt; the agent inspects + copies into assets/The visual source — headshot, paper thumbnails, project logos

Reconciliation rule: the CV is authoritative for facts (paper venues, dates, author lists), the manual homepage is authoritative for how you present yourself (what to group, what to surface, what voice), and the assets folder provides visuals. If the three sources conflict, do not silently merge — write the conflict to EXTRACTION_REVIEW.md for user resolution.

If you have no manual homepage yet: skip it. The generator falls back to CV-only structure with sensible academic defaults.

Coming in v1.1: native CLI flags --manual-homepage URL and --assets-dir PATH will fetch + stage these inputs automatically. For v1, the calling agent handles them.

Commands

init and doctor run from anywhere; the paths below assume the repo root. finalize, render and check act on the site workspace — cd into it first, which is why the script is one level up in those lines.

bash
python tools/aris_homepage.py init --from-cv <file> [--from-repos owner/repo,...] [--include-private] [--out DIR] [--force|--merge]
  # Step 1. Extract CV to plain text (via textutil / python-docx / pdftotext).
  # Step 1b. (v1.1) If --from-repos given, snapshot each repo via `gh` CLI
  #          (GraphQL metadata + REST README, truncated 20KB) →
  #          .aris-homepage/github_repos.json. Private repos skipped unless
  #          --include-private.
  # Step 2.  Emit .aris-homepage/EXTRACTION_HANDOFF.md describing what the calling
  #          LLM agent should write to .aris-homepage/extraction.json
  #          (handoff doc auto-includes guidance on github_repos.json if present).
  # --force: backup *.bak-TIMESTAMP and overwrite.
  # --merge is parsed but not implemented — it exits with a clear message.
  # NOTE: --manual-homepage / --assets-dir do not exist yet; for now the
  #       calling agent handles those sources via prompt context.

python ../tools/aris_homepage.py finalize        # or from elsewhere: --out DIR
  # Ingest .aris-homepage/extraction.json → profile.yml + publications.bib +
  # bio.md + news.md + EXTRACTION_REVIEW.md.

python ../tools/aris_homepage.py render --persona theory-minimal [--out index.html] [--override-all] [--no-audit] [--offline]
  # Run fact-check (unless --no-audit) and render. Hard-fail blocks ship unless
  # --override-all (loudly logged in audit-report.md).

python ../tools/aris_homepage.py check [--strict]
  # Fact-check only; updates audit-report.md. --strict treats WARN as FAIL.

python tools/aris_homepage.py doctor
  # Environment + dependency diagnostic (Python, pyyaml, textutil, DBLP reachability).

Generated editable source files

After finalize, your working dir contains these editable files. Edit them in your IDE; they are the source of truth — re-run render after each change.

FileRole
profile.ymlStructured facts: identity, affiliations, education, research, links, awards, talks, teaching, featured projects, publication metadata, audit overrides
publications.bibBibTeX entries — paper truth source
bio.md1-3 paragraph self-introduction in Markdown
news.mdReverse-chronological news bullets; supports inline <img> for embedded badges
assets/Optional local images (photo, paper thumbnails) — remote https:// URLs also accepted in profile.yml
EXTRACTION_REVIEW.mdLLM extraction confidence flags — read this before the first render
.aris-homepage/Internal cache (DBLP responses, extraction handoff JSON); safe to delete
audit-report.mdGenerated by render / check — your evidence trail

Schema reference

profile.yml has many optional fields; the complete reference lives in PROFILE_SCHEMA.md in this skill directory. Keep that as the single source of truth for fields.

Core schema groups (read PROFILE_SCHEMA.md for the exact field shapes):

  • identity: name, name_native (bilingual), title, email, wechat, office, photo (local path or remote URL)
  • affiliations: current + past arrays with role / institution / department / start / end
  • education · research (summary + interests) · links (scholar / github / dblp / orcid / etc.)
  • featured_projects: first-class section for flagship OSS work — logo, stats grid, link cluster, sub-projects, open problems
  • awards · talks · teaching · blogs_tutorials (rendered combined with talks)
  • professional_services: conference reviewer / journal reviewer / editorial board list
  • selected_publications: flat list OR ordered topic groups ([{group: "Topic Title", keys: [bibkey1, ...]}])
  • publications: preamble (intro sentence before first H3)
  • publications_meta.<bibkey>: thumbnail, description (blue blurb box), awards (list of badges), co_first (equal-contribution markers), links (arXiv / paper / code / slides / openreview / etc. — any key supported)
  • audit.overrides.<bibkey>: per-paper bypass — any non-empty, unexpired object skips that paper's DBLP checks. reason is recorded, not enforced; expires: YYYY-MM-DD becomes a hard failure once past
  • ship: persona, accent_color, lang, awards_heading (override "Awards" → custom string)

Fact-check protocol

Runs automatically during every render (unless --no-audit). Three outcomes per claim:

OutcomeTriggerEffect
PASSTitle hits DBLP and nothing below fires. Year and venue are only compared when both the BibTeX entry and the DBLP hit carry themListed under ## ✅ Verified in audit-report
WARN (soft)DBLP returns 0 hits OR ≥2 ambiguous; entry has an arXiv eprint but no DBLP record; BibTeX entry has no titleRender proceeds; logged in audit-report
FAIL (hard)DBLP venue ≠ the BibTeX booktitle/journal; year mismatch; a best paper / spotlight / oral / outstanding badge with no arxiv/paper/pdf/project/openreview link; bibkey in selected_publications missing from publications.bib; expired overrideVerdict = BLOCKED and render exits without writing the HTML; audit-report.md is still written. --override-all to ship anyway

Override two-layer:

  • Per-paper in profile.yml: audit.overrides.<bibkey> — any non-empty, unexpired override object skips the DBLP checks for that paper entirely (it is not enforced per-field). reason: is recorded in the report but not required; expires: is, once past, a hard failure
  • CLI emergency: python ../tools/aris_homepage.py render --override-all (every override loudly logged)

Honest scope of fact-check: DBLP lookups cover only the papers listed in selected_publications; the award-badge sweep covers every entry in publications_meta. It catches venue/year mismatch and award badges asserted without a link. It does not check author lists at all, and it never compares the title DBLP returned — the title is only the search query. Does NOT verify: workshop papers without DBLP entries, industry tech reports, blog/talk content, OSS star counts, or arbitrary claims in the bio. Treat the audit as a diagnostic floor, not a guarantee.

Cross-model review — what's automated vs optional

Two distinct review layers; do not confuse them:

Layer 1 — automated factual audit (default; skipped only with --no-audit) render and check run a deterministic Python pipeline that queries DBLP (with a 4-attempt backoff + local cache at .aris-homepage/dblp-cache.json). Nothing queries arXiv: a DBLP miss is a WARN either way, and an eprint / archiveprefix field already in your BibTeX only changes how that warning is labelled. No external LLM needed. This is the floor of fact-check, and it works with zero AI-runtime dependencies beyond Python + the calling shell.

Layer 2 — optional adversarial LLM review (recommended for high-stakes) If the calling agent has access to Codex MCP (mcp__codex__codex), run a fresh-thread Codex review after render to scrutinize: bio prose tone, claim phrasing, sub-project list, schema consistency. Codex acts as the cross-family reviewer (ARIS's adversarial-review invariant).

If the calling agent has access to Gemini (mcp__gemini__analyzeFile or mcp__gemini-cli__ask-gemini with model: auto-gemini-3), additionally use it to critique a Chrome-headless screenshot of the rendered HTML for visual issues (layout collisions, font sizes, image proportions).

Minimum required runtime: Python + the calling shell. The skill renders + fact-checks fully without Codex or Gemini. Codex strengthens the review; Gemini adds visual-design feedback. Neither is required to generate or ship the homepage.

RuntimeWhat you get
Python onlyLayer-1 DBLP fact-check; full render
+ Codex MCP+ Adversarial LLM review of prose / claims / schema
+ Gemini multimodal+ Visual-design critique of rendered screenshot

Pipeline

                ┌────────────────────────────────────────────┐
cv.{pdf,docx} ─►│ Step 1: extract → cv.txt                   │
                │ Step 1b: if --manual-homepage, WebFetch    │
                │ Step 1c: if --assets-dir, link to workspace│
                └─────────────────┬──────────────────────────┘
                                  ▼
                ┌──────────────────────────────────────────┐
                │ Step 2: LLM agent fills extraction.json  │
                │   (JSON-schema-constrained output)       │
                └─────────────────┬────────────────────────┘
                                  ▼
                ┌──────────────────────────────────────────┐
                │ Step 3: aris_homepage.py finalize        │
                │   → profile.yml + publications.bib       │
                │   + bio.md + news.md + EXTRACTION_REVIEW │
                └─────────────────┬────────────────────────┘
                                  │
                       ✋ USER EDITS IN IDE ✋
                                  │
                                  ▼
                ┌──────────────────────────────────────────┐
                │ Step 4: render (with Layer-1 DBLP audit) │
                │   ↳ Python DBLP fact-check               │
                │   ↳ Python builds per-section HTML       │
                │   ↳ inject into homepage-<persona>.html  │
                │   ↳ (optional) Codex MCP adversarial pass│
                │   ↳ (optional) Gemini screenshot critique│
                └─────────────────┬────────────────────────┘
                                  ▼
                ┌──────────────────────────────────────────┐
                │ index.html + audit-report.md             │
                └──────────────────────────────────────────┘

Pipeline: dependencies

  • Python 3.10+, pyyaml (pip install pyyaml, may need --break-system-packages on modern macOS)
  • BibTeX: parsed by a bundled stdlib parser — no bibtexparser dependency
  • DOCX: textutil on macOS (bundled) OR python-docx (pip install python-docx)
  • PDF: pdftotext (install via brew install poppler / apt install poppler-utils)
  • DBLP: official https://dblp.org/search/publ/api (rate-limited 4-attempt backoff + local cache in .aris-homepage/dblp-cache.json)
  • Codex MCP: optional, for the Layer-2 adversarial review only. The Layer-1 DBLP audit is pure Python and needs no LLM.

python tools/aris_homepage.py doctor checks all of the above.

Privacy and generic examples

All examples in this skill must be generic unless explicitly marked as the public demo URL (wanshuiyin.github.io).

Never include in examples, schema docs, or tests:

  • maintainer / collaborator / advisor / student names
  • institution-specific names (university, department, lab)
  • local filesystem paths (/Users/..., ~/...)
  • private CV filenames
  • email addresses, phone numbers, WeChat IDs, office locations
  • copied publication lists, awards, employment history, unpublished project names
  • API keys or credentials

Use placeholders:

  • Dr. Example Researcher · Jane Doe
  • Example University · Department of CS
  • cv.pdf · assets/photo.jpg
  • https://example.github.io/
  • example2026paper (bibkey)
  • advisor@example.edu

The public demo at wanshuiyin.github.io is the only exception — it's an authorized, named real-world example of generator output, not a source to copy data from.

Acceptance criteria (v1 done)

  1. python tools/aris_homepage.py init --from-cv produces editable scaffolding from any user's CV (single-file .docx or .pdf).
  2. python ../tools/aris_homepage.py render --persona theory-minimal (from the site workspace) produces a single HTML file ≤500KB (no images) or ≤2MB (with photo + thumbnails inline), or smaller still when images are referenced via remote URLs.
  3. Fact-check correctly hard-fails on a corrupted profile.yml (e.g., venue swap NeurIPS↔ICML) and passes when corrected.
  4. The HTML is publishable on GitHub Pages / Netlify / S3 / any static host without a build step.
  5. python tools/aris_homepage.py doctor accurately reports environment readiness.
  6. No personal info from the maintainer's dogfood leaks into shipped examples or tests.

What's deferred (v1.1+)

  • active-researcher template (placeholder exists; theory-minimal is the only fully-shipping persona)
  • Builder-Engineer / PM personas (v2 — these target non-academic users)
  • Multi-page output (sidebar nav for sites with 50+ pubs)
  • Bilingual side-by-side mode (lang: bilingual)
  • Automated --manual-homepage editorial-extraction helpers (currently the calling LLM agent reads the fetched HTML and reconciles)
  • Auto-thumbnail downscaling and WebP conversion

Related

  • skills/interview-cheatsheet/SKILL.md — sister skill for ML interview cheat sheets (shared cross-model review pattern)
  • skills/render-html/SKILL.md — Markdown → single-file HTML primitive
  • tools/aris_homepage.py — implementation
  • tools/templates/homepage-theory-minimal.html — template
  • PROFILE_SCHEMA.md (sibling file) — complete schema reference

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the Homepage Generator AI skill do?

Generate a fact-checked academic personal homepage from a CV, optionally augmented by an existing manual homepage and an assets directory. Produces editable structured source files (profile.yml + publications.bib + bio.md + news.md) and a single-file HTML page. Uses Codex MCP for independent factual review against DBLP. Optionally uses Gemini multimodal for screenshot critique when available. Use when the user says '做个学术主页', '从CV生成主页', 'aris-homepage', 'generate academic homepage from CV', 'PhD homepage', 'GitHub Pages personal site', or wants a fact-checked academic site.

Why use Homepage Generator on TypingMind?

Because you install it once and use it with any model. Homepage Generator is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Homepage Generator in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/wanshuiyin/ARIS-in-AI-Offer/tree/main/skills/homepage-generator. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use Homepage Generator?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Homepage Generator?

As many as you like. As long as a model supports skills, you can use Homepage Generator with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Homepage Generator AI skill free?

Yes. It is published on GitHub by wanshuiyin under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇