Write, rewrite, or improve content for the site owner's personal website (this repo). Use when the user asks to write a new writing entry, investing article, stock thesis, portfolio journal, trading lesson, project entry, update about page copy, update homepage copy, write frontmatter, draft an essay, add an image, find an image for a post, or use a user-provided image; or says "write content for," "new blog post," "add a project," "update the about page," "write a writing entry," "draft copy for the site," or "write an investing post." This skill covers MDX content authoring, investing frontmatter, page copy, images, and handing shared writing/project entries off to translation.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
A direct command skips the review prompt. Inspect the source before running it.
Write, rewrite, or improve content for the site owner's personal website (this repo). Use when the user asks to write a new writing entry, investing article, stock thesis, portfolio journal, trading lesson, project entry, update about page copy, update homepage copy, write frontmatter, draft an essay, add an image, find an image for a post, or use a user-provided image; or says "write content for," "new blog post," "add a project," "update the about page," "write a writing entry," "draft copy for the site," or "write an investing post." This skill covers MDX content authoring, investing frontmatter, page copy, images, and handing shared writing/project entries off to translation.
Website Content
Write content for the site in the site owner's voice. The site splits content into two buckets:
Site copy: Locale-scoped JSON only under content/locales/<locale>/site/*.json. The app loads these via src/lib/content.ts; there is no shared content/site/ source for home, about, or UI copy. Supported locales: en, es, zh (see src/lib/locales.ts).
Writing and projects: MDX entries. For each locale, the app uses either that locale’s folder or the shared folder—not both. If content/locales/<locale>/writing exists, that locale sees only files in it; otherwise it uses content/writing. Same for projects: content/locales/<locale>/projects or else content/projects. Shared entries in content/writing and content/projects are the canonical default; use the content-translation skill to produce locale-specific copies after creating or updating them.
Before Writing
Read references/voice-guide.md to internalize the site owner's voice (customize that guide for your own voice if you forked this template).
For every new writing, investing, or project entry, read references/images.md and create a 16:9 raster feature image (.jpg or .png, not .svg) before finalizing the entry.
Content Types
Writing Entry (Essay / Quick Thought)
Choose the file location based on whether the piece is shared or locale-specific:
Default/shared content: create or edit content/writing/[slug].mdx
Locale-specific translation or locale-only piece: create or edit content/locales/<locale>/writing/[slug].mdx
Prefer the locale-specific path when the user explicitly wants translated or locale-specific writing. Use the shared path when the content is the canonical default entry consumed as fallback content.
After creating or updating a shared entry in content/writing/[slug].mdx, immediately read .agents/skills/content-translation/SKILL.md and use it to translate the finished entry into every other locale discovered under content/locales.
Frontmatter requirements (see content-schemas.md for full spec):
title: evocative but honest; not clickbait
publishDate: ISO 8601 datetime
theme: reuse existing themes like Architecture, Developer Tools, Infrastructure, or Workflow when possible
tags: 2-4 lowercase, specific tags
ogImage: absolute site URL for the feature image, for example https://wchen.ai/writing/<slug>/feature.jpg
featured: true only for foundational or especially important pieces
draft: true for work-in-progress
For investing content, use theme: "Investing" and add the investing object described below.
Body guidelines:
200-1500 words
No H1; the title renders from frontmatter
Structure: provocation -> problem reframe -> position -> closing conviction
Keep paragraphs short: 1-3 sentences
Use italics sparingly for emphasis on key reframes
End with a forward-looking conviction, not a summary
Feature image: always create or source one as a 16:9 .jpg or .png (not .svg), save it under public/writing/<slug>/, set ogImage, and include the Markdown image in the body near the opening where it supports the narrative. For sourcing royalty-free images or using a user-provided image, read references/images.md. Mechanics (paths, syntax) in content-schemas.md.
Slug: derive from the core concept in lowercase kebab case, for example context-aware-agents.mdx.
Investing entries are writing entries with theme: "Investing". They render under /investing and use investing-specific cards. Choose the entry kind before writing:
Use a Decision Record only when the entry makes or reviews an investment decision. Set showDecisionRecord: true and include thesis/invalidation/risk fields for stock theses, watchlist notes, postmortems, or decision-heavy portfolio journals. For learning, advice, habit, or general process notes, keep showDecisionRecord omitted or false and provide only kind plus summary unless more fields genuinely help.
investing:kind:"stock-thesis"showDecisionRecord:trueticker:"AAPL"# optionalcompany:"Apple"# optionalstatus:"watching"# watching | open | closed | reviewdirection:"long"# long | short | neutralhorizon:"6-18 months"disclosure:"No current position"summary:"The setup in one sentence."thesis:"What I believe the market is missing."invalidation:"What evidence would prove the thesis wrong."catalysts:-"Upcoming product cycle"decisionTriggers:-"Add if valuation compresses while thesis remains intact."risk:"The main way this can go wrong."lastReviewed:"2026-05-09T02:45:00Z"
Investing body guidelines:
Always include a short disclaimer in the body for public stock/trading posts: Nothing here is financial advice.
For stock theses: answer Why now?, What is the market missing?, What is already priced in?, What would make me add, trim, exit, or avoid?
For learning/advice/habit posts: focus on the behavior, mistake pattern, or operating rule; do not force ticker, status, thesis, or invalidation fields.
Avoid performance theater. Prefer decision quality, thesis integrity, review cadence, and mistake taxonomy over return bragging.
Feature images for investing posts should use the high-contrast editorial thumbnail style in references/images.md: bold headline energy, market charts, red/green risk contrast, and clear visual framing around the trade, watchlist, or investing behavior.
Project Entry
Choose the file location based on whether the project entry is shared or locale-specific:
Default/shared content: create or edit content/projects/[slug].mdx
Locale-specific translation or locale-only entry: create or edit content/locales/<locale>/projects/[slug].mdx
Prefer the locale-specific path when the user asks for a translated or locale-only project entry. Use the shared path for the canonical default entry consumed as fallback content.
After creating or updating a shared entry in content/projects/[slug].mdx, immediately read .agents/skills/content-translation/SKILL.md and use it to translate the finished entry into every other locale discovered under content/locales.
Frontmatter requirements (see content-schemas.md for full spec):
motivation: start with I wanted to... or I needed...
problemAddressed: state the broken status quo vividly and concretely
learnings: honest and specific; optional
type: at least one of app, agent, experiment, skill, library, or tool
status: active, archived, or in-progress
ogImage: absolute site URL for the feature image, for example https://wchen.ai/projects/<slug>/hero.jpg
Body guidelines:
Start with a brief context paragraph, then use structured H2 sections
Common sections: How it works, The Vision, Architecture, Results
Include code snippets only when they add real clarity
Focus on narrative arc, not feature lists
Feature image: always create or source one as a 16:9 .jpg or .png (not .svg), save it under public/projects/<slug>/, set ogImage, and include the Markdown image near the opening. For sourcing royalty-free images or using a user-provided image, read references/images.md. Mechanics (paths, syntax) in content-schemas.md.
Homepage Copy
Do not edit src/app/page.tsx; it is a locale redirect shell. Update locale content instead:
Hero and section copy: content/locales/<locale>/site/home.json
Shared identity and contact labels used on the page: content/locales/<locale>/site/profile.json
See page-patterns.md for the rendered section structure in src/app/[locale]/page.tsx.
Key constraints:
Hero: intro plus two short supporting paragraphs
Current Focus: short description plus two paragraphs
A new visitor should understand who the site owner is, what they are building, and how to reach them within 15 seconds
For route values like the about link, store the unprefixed path such as /about; localization is applied at runtime
About Page Copy
Do not edit src/app/about/page.tsx; it is a locale redirect shell. Update locale content instead:
content/locales/<locale>/site/forms.json: contact/newsletter form labels, placeholders, button copy
content/locales/<locale>/site/system.json: validation, API, and fallback system messages
Do not edit content/site/newsletter-state.json for copy—it is managed by the recurring-newsletter build script and tracks which slugs have been sent.
Translation Handoff
Use the translation handoff only for shared MDX entries:
Trigger it after finishing content/writing/[slug].mdx
Trigger it after finishing content/projects/[slug].mdx
Do not trigger it for content/locales/<locale>/... source files
Do not trigger it for homepage, about, newsletter, UI, forms, or system JSON copy
Audio Publish Handoff
If the task creates or updates writing, investing, or project content that should have audio, do not assume generated audio is committed to Git.
Use this manual handoff after the content and any translations are finished:
Run pnpm audio:generate to create local audio artifacts under public/audio/ (writing, investing, or projects by content type).
Verify the affected page(s) locally if audio playback/highlighting matters to the task.
Run pnpm audio:publish to upload the generated assets and audio-manifest.json to R2.
Remind the user that production builds need AUDIO_SOURCE=r2 and R2_AUDIO_PUBLIC_BASE_URL configured.
Do not silently generate or upload audio as part of every content-writing task unless the user explicitly asks for that step.
Newsletter digest images
Every new writing, investing, and project entry should set ogImage to its feature image. When adding or changing ogImage on writing/project MDX (thumbnails in recurring digests), see docs/newsletter-digest-images.md. The site serves files from public/; CI mirrors eligible images to R2 with pnpm content-images:publish so digest emails do not 404 before deploy.
Voice Checklist
Run this check against every piece of content before finalizing:
First person throughout when the content is narrative copy
No corporate filler like leverage, synergy, innovative, cutting-edge
No hedging language like kind of, sort of, maybe
No exclamation points unless the user explicitly wants that tone
No emojis in body copy
Every paragraph advances one idea
Paragraphs are 1-3 sentences when writing prose
The ending lands on conviction, not recap
New writing, investing, and project entries include a 16:9 .jpg or .png feature image file, body image reference, meaningful alt text, and ogImage
Frontmatter or JSON shape matches the active schema (Zod in src/lib/schemas.ts; invalid content fails the build; see also scripts/validate-links.ts, validate-theme-descriptors.ts, validate-metadata.ts)
File Placement
public/
writing/[slug]/ -> Image assets for writing entry [slug]; feature images use 16:9 .jpg/.png, e.g. /writing/<slug>/feature.jpg
projects/[slug]/ -> Image assets for project entry [slug]; feature images use 16:9 .jpg/.png, e.g. /projects/<slug>/hero.png
content/
writing/[slug].mdx -> Shared/default writing entries (canonical)
projects/[slug].mdx -> Shared/default project entries (canonical)
site/
newsletter-state.json -> Script-managed; do not edit for copy
locales/<locale>/site/ -> Locales: en, es, zh
profile.json -> Site identity, nav, CTA, metadata, contact, not-found
home.json -> Homepage copy
about.json -> About-page copy
newsletter.json -> Newsletter email and flow copy
ui.json -> Shared UI strings (share, search, theme, etc.)
forms.json -> Form labels and placeholders
system.json -> Validation and system messages
locales/<locale>/writing/[slug].mdx -> Locale-specific writing (used when present instead of shared)
locales/<locale>/projects/[slug].mdx -> Locale-specific projects (used when present instead of shared)
src/app/[locale]/
page.tsx -> Homepage renderer
about/page.tsx -> About-page renderer