automate publishing posts for the user's astro koharu blog on the same server. use when the user asks to publish, draft, generate, classify, tag, or build ma...
Design & media
astro-sync
Try itConvert and polish a Markdown article into AstroPaper-compatible post format for the astro_journal blog (everbox.io). Use when the user wants to publish or sync an article (e.g. from ai-thoughts/docs/ or history/docs/) to the Astro blog, convert Markdown to Astro format, add AstroPaper frontmatter, or move images into src/assets/images/.
What it does
Convert and polish a Markdown article into AstroPaper-compatible post format for the astro_journal blog (everbox.io). Use when the user wants to publish or sync an article (e.g. from ai-thoughts/docs/ or history/docs/) to the Astro blog, convert Markdown to Astro format, add AstroPaper frontmatter, or move images into src/assets/images/.
The skill document
Astro Sync
Convert a polished Markdown draft into a ready-to-publish AstroPaper post in the astro_journal repo (/home/jeff/pool/git/astro_journal), copying and rewriting image references to match the blog's conventions.
Approval gate — read before anything else
- Never sync, write, or publish anything without explicit user approval. This skill converts on demand only; it does not run automatically.
- The user decides which article is ready to sync and publish from
ai-thoughtstoastro_journaland points it out explicitly. Do not guess, propose candidates, or sync articles on your own. - When the user names an article, still confirm the plan (target category, draft/featured, tags) before writing to the blog repo.
- Never commit or push without explicit user approval. After writing the post, ask for go-ahead first; only then stage the post + new images, commit, and push. The blog repo (
astro_journal) has a single remoteorigin.
Blog conventions (source of truth: astro_journal/AGENTS.md)
- Posts live in
src/data/blog//— categories:tech,travel,photo,philosophy. Notsrc/content/. - Filenames:
yymmdd-lowercase-slug.md— 6-digit date prefix, lowercase, hyphens only. No underscores, camelCase, or 10-digit timestamps. - URLs derive from the filename; never hardcode
/posts/...links. - Frontmatter follows the AstroPaper schema (see below).
- Images live in
src/assets/images/, referenced by literal relative path../../../assets/images/from a post insrc/data/blog//. - Renaming a published post requires adding a redirect (old URL → new URL) to
postRedirectsinastro.config.ts. .origfiles anywhere in the repo are intentional references — never modify or delete them.
Inputs
source— Path to the source Markdown article (e.g.ai-thoughts/docs/260803-ollama-to-llamacpp.md). Required. If the user only names an article, locate it inai-thoughts/docs/by slug or date.category— Blog category:tech,travel,photo, orphilosophy. Optional. Defaulttech.draft—true/false. Optional. Defaultfalse(published).featured—true/false. Optional. Defaultfalse.true: homepage-worthy — a signature/opinion essay, deep dive, or milestone post that defines the blog's voice. Use sparingly (aim ≤ 20% of posts) so the homepage stays curated.false: everything else — how-tos, quick notes, release/changelog posts, and*-chn.mdtranslations of an already-published post.- When the user doesn't specify, ask which it is (per Procedure step 2);
never auto-pick
true.
tags— List of lowercase hyphen-separated tags. Optional. Default derived from the article topic.
Outputs
postPath— Path to the created post, e.g.src/data/blog/tech/260803-ollama-to-llamacpp.md.imagesCopied— List of image files copied intosrc/assets/images/.
Procedure
-
Wait for the user to point out the article to sync. Do not start until they name it explicitly.
-
Confirm the plan with the user: target category,
draft/featured, and tags. Get their go-ahead before writing anything toastro_journal. -
Locate the blog: confirm
astro_journalis checked out at/home/jeff/pool/git/astro_journal. -
Read the source article from
source. If it has no frontmatter, infer the title from the first#/##heading and the date from the filename (or today if none). -
Determine the filename:
yymmdd-lowercase-slug.md. Normalize the slug: lowercase, hyphens only, strip underscores/camelCase and any existing date prefix/timestamp. Keep the 6-digityymmdddate prefix. -
Polish (light): fix grammar/spelling/clarity in English; preserve code blocks, inline code, and technical terms verbatim. Do not rewrite substance.
-
Copy images: for every
../imgs/reference in the source, copy the image fromai-thoughts/imgs/intosrc/assets/images/, normalizing the filename to lowercase-hyphens with a 6-digityymmddprefix. Rewrite the reference in the post to../../../assets/images/. -
Write frontmatter (AstroPaper schema):
--- author: Jeff Yang pubDatetime: title: tags: - - description: featured: false draft: false ---pubDatetimecomes from the source date if present, otherwise now. Always use a UTC time that has already passed — the blog'spostFilterhides posts whosepubDatetimeis in the future (even by minutes). A future time means the post won't appear on the homepage or in recent posts, though search may still index it.modDatetimeis optional and only set when updating an existing post. -
Write the post to
src/data/blog//with the frontmatter followed by the polished body. -
Report
postPathandimagesCopiedto the user. -
Commit & push (only after approval): ask the user explicitly whether to commit. On approval, stage the post and any new images in
astro_journal, commit with a concise message, and push toorigin. Without approval, leave the changes uncommitted and say so.
Verification
- File is in
src/data/blog//and namedyymmdd-lowercase-slug.md(lowercase, hyphens only, 6-digit date prefix). - Frontmatter contains at least
author,pubDatetime,title,tags,description;draft/featuredpresent when applicable. - Every image reference in the post points to an existing file in
src/assets/images/(verify with a glob/ls). - No
../imgs/references remain in the post. - No hardcoded
/posts/...links were introduced. - If committed: the post and new images are staged together, and
origin/mainis up to date. - Optional: run
npx astro checkin the blog repo to confirm no content/config errors. Usenpxdirectly —pnpmis not installed on this machine andpnpm run ...fails with "command not found";npxresolves the localastrobinary fine.
Error Handling
- Source not found: list candidate files in
ai-thoughts/docs/and ask which to use. - Image missing: skip it, note it in
imagesCopiedas missing, and tell the user the reference will be broken. - Category invalid: list
tech,travel,photo,philosophyand ask. - Filename collision: if a post already exists at the target path, stop and ask whether to overwrite, use
modDatetime, or pick a new slug.
Related skills
Read an attached Markdown document, analyze and summarize it, then generate a minimalist image from the summary using the default image model. Ask the user for aspect ratio when needed, and support social-banner formats such as 5:2 and 5:4. Use when the user wants a document turned into a simple tutorial-style visual with handwritten whiteboard aesthetics.
Polish a technical blog draft into an 1000–1200 word, 4-5 section en-US article, preserve technical terms/code, and generate consistent hero + per-section image prompts when the user asks to polish and translate a blog with images.
Translate a specific article from ai-thoughts/docs/ into Simplified Chinese, writing the output to an exactly-same-filename "-chn.md" file. Use when the user names a specific article and asks to translate it (e.g. "translate 260803-ollama-to-llamacpp", "翻译 xxx", "make a -chn.md version"). Never runs automatically; only acts on an explicitly chosen article.
Convert Word (.doc, .docx), PowerPoint (.ppt, .pptx), Excel (.xls, .xlsx), OpenDocument (.odt, .ods, .odp), RTF, EPUB, CSV, and PDF files to GitHub-Flavored Markdown. Use when a task needs the contents of an office document, spreadsheet, presentation, ebook, or PDF you cannot read directly.
Polish a technical blog draft into an 800–1000 word, 3–4 section zh-CN article, preserve technical terms/code, and generate consistent hero + per-section image prompts when the user asks to polish and translate a blog with images.