一键导入
add-blog-post
Create blog posts — from a topic (writes content) or with provided content (scaffolding). Use proactively when creating new blog posts or articles.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Create blog posts — from a topic (writes content) or with provided content (scaffolding). Use proactively when creating new blog posts or articles.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | add-blog-post |
| description | Create blog posts — from a topic (writes content) or with provided content (scaffolding). Use proactively when creating new blog posts or articles. |
| disable-model-invocation | false |
| allowed-tools | Read, Write, Edit, Glob, Grep, Bash |
| model | sonnet |
| argument-hint | [topic, brief, or content] |
| tier | 2 |
| intent | create |
| max-files | 6 |
| max-loc | 1200 |
Create multilingual blog posts (currently English + Spanish) for XergioAleX.com using Astro Content Collections. Supports two modes:
The skill auto-detects the mode based on the inputs provided.
This skill is the mandatory workflow for creating new blog posts in this repository.
/add-blog-post when creating new posts in src/content/blog/./add-blog-post before writing files.src/content/tags/)content-writer agent for rewrites, doc-edit for minor edits)add-page skill)/optimize-image skill or pnpm run images:optimize)Tier: 2 - Standard
Reasoning: Writing quality multilingual articles requires moderate reasoning for tone calibration, narrative structure, and natural translation. Content mode (scaffolding) is simpler but shares the same multilingual creation flow.
| If provided | Mode | What happens |
|---|---|---|
$TOPIC (no $CONTENT) | Topic mode | Researches, plans, and writes the article from scratch |
$CONTENT (with $TITLE) | Content mode | Scaffolds files using the provided content |
Both $TOPIC and $CONTENT | Content mode | Uses provided content, topic as context |
$TOPIC: Article topic, brief, or description (required for topic mode)$TITLE: Post title (required for content mode, auto-generated in topic mode)$DESCRIPTION: Post excerpt/description (required for content mode, auto-generated in topic mode)$CONTENT: Pre-written post content in markdown (triggers content mode)$TAGS: Array of tag names — both primary and secondary in one array (must exist in src/content/tags/)$HERO_IMAGE: Hero image path (from public/). If the image contains text, provide a language-specific variant for ES (see Multilingual Hero Images)$SLUG: Custom slug (default: kebab-case of title)$LANG: Primary language, en or es (default: en). The other language version will be translated.$PUB_DATE: Publication date in YYYY-MM-DD format (default: today's date). Scheduled posts: If set to a future date, the post will be hidden from production builds but visible in dev with an amber "Scheduled" badge. See Blog Posts — Scheduled Posts.$TYPE: Article type — blog, portfolio, tutorial (default: blog, topic mode only)Source of truth for all blog post conventions:
File naming: YYYY-MM-DD_{slug}.md (date prefix stripped from URLs)
Directories: src/content/blog/en/ and src/content/blog/es/
Frontmatter fields: title (required), description (required), pubDate (required), updatedDate, heroImage, heroLayout, tags, keywords, series, seriesOrder
updatedDate: When the author asks to "mark that the post was updated on <date>" (ES: "pon que se actualizó el blog post en <fecha>"), set updatedDate: '<date>' — it renders an "Updated/Actualizado {date}" badge in the header. Set the same value in BOTH locales; must be on/after pubDate. See BLOG_POSTS.md — Marking a Post as Updated.
heroLayout: banner for landscape, side-by-side for square, minimal for secondary, none for text-only
Image path: /images/blog/posts/{slug}/hero.{ext} (ES variant: hero-es.{ext} when image has localized text)
Tags (unified array): All tags go in a single tags array. The tier (primary / secondary / subtopic) is resolved at build time from the tags collection — NOT by position in the array.
Primary tags (1-3 per post): tech, personal, talks, trading, portfolio, dailybot (do NOT use demo — that tag is only for demo posts in _demo/ folders).
Secondary tags (0-10 per post): web-development, javascript, ai, blockchain, devops, python, university, database, iot, design, mobile.
Subtopic tags (0-15 per post — tier 3, fine-grained technology handles): kotlin (parent: mobile), astro/svelte/graphql (parent: web-development), cloudflare/docker (parent: devops), django (parent: python), openclaw (parent: ai).
Caps: per post — 1-3 primary, 0-10 secondary, 0-15 subtopic. At least 1 primary required. No fixed total cap — but only tag what the post genuinely covers (no tagging for the sake of tagging).
When to use a subtopic tag: the post is FOCUSED on that specific technology/framework/product (not just mentions it in passing). If you're unsure whether a candidate qualifies, run /audit-taxonomy to see the data.
Examples:
tags: ["tech", "portfolio", "python", "database"] — primary + secondary only.tags: ["tech", "web-development", "astro", "svelte"] — primary + secondary + 2 subtopics (Astro+Svelte tech post).tags: ["tech", "mobile", "kotlin"] — primary + secondary + subtopic (mobile post focused on Kotlin).Full taxonomy reference: see Tag Taxonomy in BLOG_POSTS.md for the complete tier table, governance, and visual rendering rules.
Series (optional): If the post belongs to a series, add series: "{series-slug}" and seriesOrder: {n}. Available series are defined in src/content/series/. The SeriesNavigation panel and SeriesIndicator floating button render automatically — no component imports or page changes needed.
Series workflow (when adding to an existing series):
ls src/content/series/cat src/content/series/{slug}.mdgrep -r 'series: "{slug}"' src/content/blog/en/ to determine the next seriesOrder valueseries and seriesOrder to frontmatter in BOTH en/ and es/ versionsSeriesNavigation (TOC + prev/next links) and SeriesIndicator (floating chapter progress button) appear automatically at build timeCreating a NEW series: Create src/content/series/{slug}.md with name, title, description, order fields. Then add the series fields to each post's frontmatter.
Author (optional): If the post belongs to an author other than the default, add author: "{author-slug}" to the frontmatter. Available authors are YAML files in src/content/authors/. When omitted, the post defaults to sergio-florez. Both EN and ES versions of a post must use the same author slug — authorship doesn't translate. The AuthorCard renders automatically at the end of the post and pulls localized role and bio from the author's YAML.
Author workflow (when adding a new author):
src/content/authors/{slug}.yaml with name, slug, avatar, role.{en,es}, bio.{en,es}, and optional social (x, linkedin, github, instagram, website)public/images/authors/{slug}.webp (WebP, ~160x160 px)author: on both EN and ES versions of the post/internal/authors in dev modeFull reference: features/AUTHORS.md
Content lifecycle:
_demo/ folder: demo posts (accessible only by direct URL in local dev mode, never in production or listings)src/content/blog/en/ for voice reference and to avoid overlapsrc/content/blog/en/_demo/ as structural references — these are example articles showcasing different hero layouts (banner, side-by-side, minimal, none), MDX features, rich markdown formatting, and code syntax highlighting. Use them as templates when deciding article structure and formatting.src/content/tags/ — note which are tier: primary and which are tier: secondarytags array. Add every tag the post genuinely covers, but never tag for the sake of tagging.public/images/blog/posts/ or public/images/blog/shared/# Check existing articles
ls src/content/blog/en/
# Check available tags
ls src/content/tags/
# Verify image assets if referenced
ls public/images/blog/posts/ public/images/blog/shared/ 2>/dev/null
$SLUG)YYYY-MM-DD_{slug}.md (use pubDate as date prefix)heroLayout based on image aspect ratioTopic mode only — plan article structure:
Series independence principle: Each post in a series should read well on its own. Avoid explicit "In chapter N..." references. Instead: weave in context naturally with inline links, or simply state the fact without referencing which chapter covered it. A reader who lands on chapter 5 from a search engine should not feel lost.
Create src/content/blog/{$LANG}/YYYY-MM-DD_{slug}.md
Image setup: If a hero image is provided:
public/images/blog/posts/{slug}//images/blog/posts/{slug}/hero.{ext} in frontmatterhero-es.{ext} in the same folder, generate WebP, and use the variant path in the ES frontmatterTopic mode — voice rules:
Formatting rules:
--- horizontal rules between major sections## for section headings, ### for subsections<div style="background:#0F1124;border-radius:12px;padding:2rem;text-align:center">

</div>
<figure> + <figcaption>:
<figure>
<img src="/images/blog/posts/{slug}/image.webp" alt="Alt text" loading="lazy" />
<figcaption>Short caption adding context the image alone doesn't provide.</figcaption>
</figure>
Captions must be short (one line), additive (never repeat alt text), and exist in both EN and ES.Markdown template:
---
title: 'Post Title Here'
description: 'A brief description of what this post is about.'
pubDate: '2026-01-31'
heroImage: '/images/blog/posts/post-title-here/hero.jpg'
heroLayout: 'banner'
tags: ['tech', 'web-development', 'javascript']
keywords: ['specific search phrase 1', 'long-tail keyword phrase 2', 'technology name tutorial', 'how to do X with Y', 'comparison A vs B']
# author: 'sergio-florez' # Optional — slug from src/content/authors/. Defaults to 'sergio-florez'
# series: 'series-slug' # Optional — must match a slug in src/content/series/
# seriesOrder: 1 # Required when series is set — positive integer, unique within the series
# draft: true # Optional — hides post from production
---
## Introduction
Content starts here...
Note: Primary (
tech) and secondary (web-development,javascript) tags go in onetagsarray. Tier is determined by the tags collection, not by position.
See Blog Content Lifecycle for post visibility rules.
MANDATORY: Every blog post must have 5-8 SEO keywords per language version.
Keywords ≠ Tags. Tags are categorical labels from a controlled taxonomy (tech, web-development). Keywords are specific search phrases users type into search engines (replace ESLint with Biome, Biome linter setup).
Keyword generation rules:
English keywords: Natural English search phrases.
Spanish keywords: Adapted to Spanish search behavior (NOT literal translations):
analisis, codigo, introduccionPlacement in frontmatter: keywords array goes AFTER tags and BEFORE series (if present):
tags: ['tech', 'web-development']
keywords: ['keyword phrase 1', 'keyword phrase 2', 'keyword phrase 3', 'keyword phrase 4', 'keyword phrase 5']
series: "optional-series"
MANDATORY: Create the translated version in the other language directory.
src/content/blog/es/YYYY-MM-DD_{slug}.mdsrc/content/blog/en/YYYY-MM-DD_{slug}.mdTranslation rules:
title, description, keywords, all body content, alt textpubDate, updatedDate, heroLayout, tags, author, series, seriesOrder, code blocks, URLsheroImage: Use the same path as EN by default. If a hero-es.{ext} variant exists, use it in the ES frontmatterpequeno (→ pequeño), tamano (→ tamaño), analisis (→ análisis), numero (→ número), codigo (→ código), pagina (→ página), etc. Verify before saving.pnpm run build
Verify:
keywords array with 5-8 entries/add-blog-post workflow was used for creation (no manual bypass)## Blog Post Created (Multilingual)
### Files Created
- English: `src/content/blog/en/YYYY-MM-DD_{slug}.md` -> URL: `/blog/{slug}/`
- Spanish: `src/content/blog/es/YYYY-MM-DD_{slug}.md` -> URL: `/es/blog/{slug}/`
### Details
- **Title (EN):** {title}
- **Title (ES):** {title_es}
- **Mode:** {topic|content}
- **Tags:** {tags}
- **Date:** {pubDate}
- **Hero:** {heroImage or "none"} ({heroLayout})
### Build: Passing
### Commit Message
content: add blog post "{title}" (en + es)
src/content/blog/en/, src/content/blog/es/, public/images/src/pages/, src/components/, src/layouts/SeriesNavigation panel already shows the full TOC below the content.src/content/tags/)[AUTHOR: ...], [TODO: ...], [TBD], or similar in published posts. Replace with real content or remove the section.src/lib/i18n.ts for active languages./translate-sync skill after creating the primary version.Stop and ask if:
src/content/blog/en/ (English version)src/content/blog/es/ (Spanish version)tenés, podés, sabés, querés, etc.pequeno, tamano, numero, codigo)keywords array (5-8 natural search phrases per post)[AUTHOR:, [TODO:, [TBD], [FIXME] — zero in final post)pnpm run build passesEscalate to a higher tier (or ask user) if:
architect first). Adding a single post to an existing series is fine — just set series and seriesOrder in frontmatter.Input:
$TOPIC: Portfolio article about my XergioAleX personal branding. Ninja coder logo designed by Koru.
$TAG: portfolio
$PUB_DATE: 2020-12-31
$HERO_IMAGE: /images/blog/posts/personal-branding-xergioalex/hero.jpg
Creates:
src/content/blog/en/2020-12-31_personal-branding-xergioalex.md (written from scratch)src/content/blog/es/2020-12-31_personal-branding-xergioalex.md (translated)Input:
$TITLE: Getting Started with Astro
$DESCRIPTION: Learn how to build fast websites with Astro
$CONTENT: [pre-written markdown content]
$TAGS: ['tech']
Creates:
src/content/blog/en/2026-02-11_getting-started-with-astro.md (scaffolded)src/content/blog/es/2026-02-11_getting-started-with-astro.md (translated)Input:
$TOPIC: How I built a self-hosted CI/CD pipeline using Docker and GitHub Actions
$TAG: tech
Creates:
Input:
$TOPIC: AI
Result: Stopped — topic too broad. Needs a specific personal experience, project, or angle.
content-writer - Agent persona for complex content projectsdoc-edit - Edit existing postsadd-page - Create pagestranslate-sync - Synchronize translationsi18n-guardian - Translation quality verificationPolicy: Keep only the 3 most recent entries. When adding a new entry, remove the oldest.
| Version | Date | Changes |
|---|---|---|
| 3.0.0 | 2026-03-08 | SEO keywords: added Step 4 for keyword generation (5-8 per post, both EN/ES). Keywords are search phrases distinct from tags. Updated frontmatter template, Definition of Done, and validation. |
| 2.9.0 | 2026-03-03 | Scheduled posts: documented that future $PUB_DATE creates a scheduled post (hidden in prod, amber badge in dev). Updated lifecycle references. |
| 2.8.0 | 2026-03-03 | No placeholder content: never leave [AUTHOR:], [TODO:], [TBD], [FIXME] in published posts. Added to Safety Checks and Definition of Done. |
Pre-publication audit for blog posts — comprehensive final review of SEO, AEO, accessibility, images, content quality, i18n parity, and project conventions before publishing. Use proactively before publishing any blog post.
Pre-publication audit for blog series — validates series definition, post ordering, cross-post consistency, navigation, and runs individual post audits for all posts in the series. Use proactively before publishing any blog series.
Audit the blog tag taxonomy — frequency analysis, orphan detection, hierarchy validation, and proposals for new subtopic tags. Read-only — proposes, never modifies tags or posts. Use proactively before each release cycle or after a content drop of 5+ posts.
Optional DeepWorkPlan addon that connects an AI-first repo to the developer's Dailybot team — installing (with consent) the Dailybot agent skill (DailybotHQ/agent-skill) and/or the Dailybot CLI (DailybotHQ/cli), wiring the plan lifecycle into best-effort agent updates - kickoff when a plan starts, significant task completions, a blocked report when an unattended run halts, and a milestone on plan completion - with payloads derived from the plan's state layer, and optionally committing the Dailybot skill's deterministic hook enforcement (dailybot hook lifecycle hooks, CLI >= 1.12.0) so the agent harness itself reminds agents about unreported work. Opt-in, never required, never blocks the work, reconciles existing setups instead of clobbering them, and defers all auth to the Dailybot skill's own consent flow. Use when the developer or team already uses Dailybot and wants DWP progress visible to humans.
Optional DeepWorkPlan addon that safely upgrades a repo's dependencies — reasoning about the repo's ACTUAL package manager (npm/pnpm/yarn + ncu, pip/poetry/uv, cargo, go mod, bundler, composer, and more) rather than assuming npm — with a batched, validated, revertible workflow that detects the manager and manifests/lockfiles, classifies upgrades (patch/minor/major), upgrades in safe batches, runs the repo's real validation gate after each batch, reverts a failing batch, and summarizes. Opt-in, never required, reconciles with the repo's existing tooling. Use when the developer wants to bring dependencies up to date without breaking the build.
Optional DeepWorkPlan addon that gives a repo with a user-facing interface surface a DESIGN.md (under docs/, indexed from AGENTS.md) — a Markdown design-system file any coding agent reads to generate interface output consistent with the repo's OWN conventions. Covers three profiles detected independently from real files — visual-ui (rendered web/mobile/desktop UI), cli-output (styled terminal output — semantic colors, panels, spinners, prompts, TTY/NO_COLOR degradation), and conversational (chat/email messaging — voice and register, message anatomy, per-platform rendering). Reasons about the repo's ACTUAL design source (CSS custom properties, Tailwind config, token files, component styles, a CLI display/theme module, or message-composition helpers) rather than copying a brand file; checks contrast (WCAG AA), color-is-not-the-only-carrier, plain-text fallbacks, and token integrity. The visual-ui profile is default-on when detected (applied in trust mode, strongly recommended in guided mode); cli-output and con