skills/blog-workflow/SKILL.md
Draft SEO-optimized technology blog posts for multiple platforms based on the current project or latest changes
npx skillsauth add nano-step/skill-manager skills/blog-workflowInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
$ARGUMENTS
You MUST consider the user input before proceeding (if not empty).
⚠️ FIRST — check if $ARGUMENTS is exactly the word help (case-insensitive). If yes, jump directly to the Help Output section below and STOP. Do NOT run any other phase.
Parse $ARGUMENTS to extract platform selection, flags, and topic.
Syntax: /blog [platforms] [lang:vi|en] [file] [screenshot] [topic]
All options are plain keywords — no dashes, no -- prefix. This avoids conflict with the chat interface.
If $ARGUMENTS is help (case-insensitive, with or without extra whitespace), output the following help text exactly and then STOP — do not proceed to any other phase:
/blog — SEO-optimized blog post generator for multiple platforms
USAGE
/blog [platforms] [options] [topic]
PLATFORMS (comma-separated, default: all)
devto, dev.to dev.to
linkedin LinkedIn (short post + long-form article)
medium Medium
hashnode Hashnode
blog, hoainho hoainho.info/blog (canonical source)
thnk, thnkandgrow thnkandgrow.com
all All 6 platforms
OPTIONS (plain keywords, no dashes)
lang:en Write in English (default)
lang:vi Write in Vietnamese (tech terms stay in English)
file Save output as .md files in ./blog-output/
screenshot Capture app screenshots via Playwright and embed in posts
help Show this help message
EXAMPLES
/blog help Show this guide
/blog All platforms, English, auto-detect topic
/blog devto,medium My new feature dev.to + Medium only
/blog lang:vi All platforms, Vietnamese
/blog linkedin lang:vi AI Sandbox tips LinkedIn, Vietnamese
/blog file hashnode Deep dive into auth Hashnode, save to file
/blog screenshot file blog,thnk Release v2 Personal blogs, screenshots, files
/blog all lang:vi file screenshot Full combo
OUTPUT (default: inline)
Prints each platform version directly in chat, separated by ---
OUTPUT (file)
./blog-output/
├── index.md Summary with links to all versions
├── {slug}-devto.md dev.to version with frontmatter
├── {slug}-linkedin-post.md LinkedIn short post
├── {slug}-linkedin-article.md LinkedIn long-form article
├── {slug}-medium.md Medium version
├── {slug}-hashnode.md Hashnode version
├── {slug}-hoainho.md hoainho.info/blog version
├── {slug}-thnkandgrow.md thnkandgrow.com version
└── screenshots/ (only with screenshot option)
├── hero.png Main app screenshot
├── feature-1.png Key feature screenshots
└── mobile.png Mobile viewport
NOTES
• Canonical URL is always hoainho.info/blog unless overridden
• Posts include SEO keywords, meta descriptions, and platform-native formatting
• Cross-platform publishing schedule included in output
• Screenshots require a running dev server or build output
Do NOT proceed with any other phase after printing help.
Case-insensitive, comma-separated, no spaces:
| Identifier | Platform |
|------------|----------|
| devto or dev.to | dev.to |
| linkedin | LinkedIn (both short post + long-form article) |
| medium | Medium |
| hashnode | Hashnode |
| blog or hoainho | hoainho.info/blog |
| thnk or thnkandgrow | thnkandgrow.com |
| all | All 6 platforms (default when no platform specified) |
Plain keywords (no dashes) — can appear anywhere in $ARGUMENTS:
| Option | Default | Description |
|--------|---------|-------------|
| lang:vi | en | Generate all content in Vietnamese. Tech terms (React, Docker, API...) stay in English. |
| lang:en | en | Generate all content in English (default). |
| file | off | Save each platform version as a separate .md file in ./blog-output/ directory. File naming: {slug}-{platform}.md (e.g., moodtrip-v2-devto.md). Also creates an index.md with links to all versions. |
| screenshot | off | Include screenshots of the project. The agent will: (1) detect if the project has a running dev server or build output, (2) launch the app in a browser via Playwright, (3) capture key screens (homepage, main features, mobile view), (4) save screenshots to ./blog-output/screenshots/, (5) embed image references in the blog content with descriptive alt text. If no UI is available (CLI tool, library), capture terminal output or architecture diagrams instead. |
| help | — | Display usage guide and exit. No content is generated. |
help first — if $ARGUMENTS is exactly help (case-insensitive), print help and stop immediately$ARGUMENTS for recognized platform identifiers (first comma-separated token)lang:vi, lang:en, file, screenshot) from anywhere in the argumentsall/blog help → show usage guide
/blog → all platforms, English, console output
/blog devto,medium Building a mood-based trip planner → dev.to + Medium, English
/blog lang:vi → all platforms, Vietnamese, auto-detect topic
/blog linkedin lang:vi Chia sẻ hành trình xây dựng MoodTrip → LinkedIn only, Vietnamese
/blog file devto,hashnode Introducing MoodTrip V2 → dev.to + Hashnode, save to files
/blog screenshot file blog,thnk MoodTrip V2 deep dive → personal blogs, with screenshots, save to files
/blog all lang:vi file screenshot → everything: all platforms, Vietnamese, files, screenshots
CRITICAL: Only generate content for the selected platform(s). Skip all Phase 2 subsections for unselected platforms. Phase 3-5 output must also only reference selected platforms.
Generate high-quality, SEO-optimized technology blog posts for selected platforms (default: all six — dev.to, LinkedIn, Medium, Hashnode, hoainho.info/blog, thnkandgrow.com). Only generate content for platforms specified in the argument parsing step. Each platform version must respect native formatting, optimal length, audience expectations, and discovery mechanics. Content is derived from the current project context and/or recent changes.
hoainho.info/blog is always the canonical URL unless user overrides.--lang flag. --lang=en (default) for English, --lang=vi for Vietnamese. When Vietnamese: use natural Vietnamese tech writing style, keep code/tech terms in English (React, Docker, API, etc.). If no --lang flag and user writes topic in Vietnamese, auto-set to --lang=vi.Read project metadata — load in parallel:
README.md (project overview, features, value prop)AGENTS.md (structure, conventions, tech stack)package.json or equivalent manifest (dependencies, scripts, version)CHANGELOG.md or SESSION-SUMMARY.md if presentAnalyze recent changes (run from repo root):
git log --oneline --no-decorate -20
git diff HEAD~5..HEAD --stat
git log --format="%s" -10
Determine content source:
$ARGUMENTS → use that as the primary angle$ARGUMENTS is empty → auto-detect the most interesting angle from recent git activityExtract key facts into an internal model (do not output this):
Select blog post angle — choose the most fitting type: | Type | When to use | |------|-------------| | Tutorial / How-to | New feature with clear usage steps | | Announcement | Major release, new tool, milestone | | Deep-dive | Complex architecture, design decisions | | Changelog / What's New | Multiple recent updates | | Case Study | Real-world usage, performance results | | Opinion / Lessons Learned | Insights from building the project |
SEO keyword research — generate:
Craft titles — generate exactly 3 variants:
Plan content structure — outline with H2/H3 headings:
Generate separate, complete versions for each platform below. Each version must be self-contained and copy-paste ready.
Format: Markdown with Liquid tags
Required frontmatter:
---
title: "[Your Title]"
published: false
tags: [tag1, tag2, tag3, tag4] # max 4 tags
cover_image: "" # suggest dimensions: 1000x420
canonical_url: "https://hoainho.info/blog/[slug]"
description: "[150-160 char meta description with primary keyword]"
series: "" # optional, suggest if part of a series
---
Writing rules:
bash, typescript, etc.)## TL;DR section immediately after the intro## What's Next? and a clear CTA (star the repo, try the tool, comment)Generate two versions:
Version A — Short Post (1300-2000 characters):
[Hook line — must grab attention before "see more" fold]
[Second line — amplify the hook]
[3-5 bullet points or short paragraphs with key insights]
[Call-to-action: question to drive comments]
[3-5 hashtags, mix of broad (#AI, #DevTools) and niche (#AISandbox)]
Writing rules for short post:
Version B — Long-form Article (1000-2000 words):
Format: Rich Markdown
Structure:
Writing rules:
Format: Markdown with frontmatter
Required frontmatter:
---
title: "[Your Title]"
slug: "[seo-optimized-slug-with-primary-keyword]"
cover: "" # suggest dimensions: 1600x840
tags: [tag1, tag2, tag3, tag4, tag5]
canonical: "https://hoainho.info/blog/[slug]"
enableToc: true
---
Writing rules:
Format: Markdown or MDX (detect from project structure if possible, default to MDX)
Frontmatter (adapt to detected blog engine):
---
title: "[Your Title]"
date: "[YYYY-MM-DD]"
description: "[150-160 char meta description]"
tags: [tag1, tag2, tag3]
author: "Hoai Nho"
slug: "[seo-optimized-slug]"
image: "" # og:image recommendation
draft: true
---
Writing rules:
Format: Markdown/MDX
Frontmatter:
---
title: "[Your Title — growth/learning angle]"
date: "[YYYY-MM-DD]"
description: "[meta description with growth/learning angle]"
tags: [tag1, tag2, tag3]
category: "Tech & Growth"
draft: true
---
Writing rules:
After drafting all versions, run this checklist on each:
| Check | Criteria | |-------|----------| | Title | Contains primary keyword in first 30 chars | | Meta description | 150-160 chars, includes keyword, has CTA verb | | H2 headings | At least 2 contain keyword variants | | First paragraph | Contains primary keyword naturally | | Image alt text | Descriptive, includes keyword where natural | | Internal links | Suggest 1-2 links to related content | | External links | Include 1-3 authoritative external references | | Reading level | Grade 8-10 (use short sentences, common words) | | Word count | Meets platform-specific optimal range | | Code blocks | All have language identifiers for syntax highlighting |
Output a publishing plan:
Canonical URL: https://hoainho.info/blog/[slug]
Posting schedule (stagger for maximum reach): | Day | Platform | Why this order | |-----|----------|----------------| | Day 1 | hoainho.info/blog | Canonical source, let Google index first | | Day 1 | thnkandgrow.com | Second owned property | | Day 2 | dev.to | Developer community, high engagement potential | | Day 2 | Hashnode | Technical community, SEO boost | | Day 3 | Medium | Broader audience, delayed for indexing | | Day 3-4 | LinkedIn (short post) | Professional network, drives traffic | | Day 5-7 | LinkedIn (article) | Long-form for sustained engagement |
Cross-linking: Each platform version links back to canonical. Mention other platforms where natural (e.g., "Read the full deep-dive on my blog").
Repurposing ideas:
--file flag)Present results directly in chat in this order:
--- horizontal rules, only selected platforms:
[ ] Publish to hoainho.info/blog (canonical)
[ ] Publish to thnkandgrow.com
[ ] Submit to dev.to (set canonical_url)
[ ] Submit to Hashnode (set canonical)
[ ] Submit to Medium (import or paste, set canonical)
[ ] Post LinkedIn short version
[ ] Schedule LinkedIn long-form article
[ ] Share on social media (Twitter/X, Reddit if relevant)
[ ] Submit to relevant aggregators (Hacker News, Reddit communities)
[ ] Monitor analytics after 24h and 7d
--file flag)Create a ./blog-output/ directory in the project root and write files:
Generate slug from the title: lowercase, hyphens, no special chars (e.g., introducing-moodtrip-v2)
Write platform files — one per selected platform:
| File | Content |
|------|---------|
| {slug}-devto.md | dev.to version with full frontmatter |
| {slug}-linkedin-post.md | LinkedIn short post (plain text) |
| {slug}-linkedin-article.md | LinkedIn long-form article |
| {slug}-medium.md | Medium version with kicker/subtitle |
| {slug}-hashnode.md | Hashnode version with full frontmatter |
| {slug}-hoainho.md | hoainho.info/blog version |
| {slug}-thnkandgrow.md | thnkandgrow.com version |
Write index.md — a summary file containing:
Screenshots (only if --screenshot flag):
./blog-output/screenshots/hero.png, feature-{n}.png, mobile.png./screenshots/hero.pngPrint summary in chat:
✅ Blog output saved to ./blog-output/
Files created:
• blog-output/index.md
• blog-output/{slug}-devto.md
• blog-output/{slug}-linkedin-post.md
• ...
Next: review files, then follow the publishing checklist in index.md
These standards apply to ALL platform versions:
tools
Humanization layer for LLM conversation — makes the model sound and respond like a real, thoughtful, embodied human rather than an assistant or chatbot. Use whenever the reply will be read by a human and warmth, presence, or texture matter more than machine-readability. Triggers on any of: "human", "humans", "humanize", "humanization", "be human", "more human", "feel human", "people", "person", "real person", "real human", "friend", "friendly", "like a friend", "respond like a friend", "buddy", "talk", "talking", "talk to me", "talk like a person", "chat", "chatting", "conversation", "converse", "discuss", "discussion", "communication", "communicate", "listen", "just listen", "sit with me", "vent", "venting", "I just want to vent", "company", "presence", "stop being an AI", "stop sounding like a bot", "less corporate", "less robotic", "less formal", "warmer", "warm tone", "empathy", "empathetic", "comfort", "support me", "emotional support", "be honest with me", "be real with me", "real talk", "heart-to-heart", "deep conversation", "casual", "casual chat", "small talk", "chitchat", "say something", "tell me something", and on any emotional / relational / personal-decision / interpersonal context — grief, joy, anger, fear, shame, doubt, loneliness, dating, breakup, conflict, family, parents, sibling, friendship, marriage, divorce, in-laws, kids, parenting, work stress, burnout, career decision, quitting, firing, layoff, anxiety, depression, panic, sleep, dreams, identity, faith, doubt, meaning, mortality, celebration, milestone, achievement, gratitude, apology, forgiveness. Also loads when the user writes in non-English (any language) with emotional weight, when the user's message is shorter than 8 words and affect-laden, when the user types in lowercase fragments, when the user types in ALL CAPS with excitement, or when the user explicitly asks for a friend / mentor / older-sibling / wise-listener voice. Do NOT use for code generation, tool calls, structured data output, SQL, API contracts, or any task where machine-readability matters more than human warmth.
tools
Use this skill whenever the user mentions open-design, od_generate_design, OD daemon, BYOK design generation, generating HTML mockups from a PRD, creating or managing Open Design projects, saving design artifacts, linting generated HTML, or any of the 10 `od_*` MCP tools (od_list_projects, od_get_project, od_create_project, od_update_project, od_delete_project, od_save_artifact, od_save_project_file, od_lint_artifact, od_compose_brief, od_generate_design). Also trigger on phrases like "generate a design", "create a mockup", "make a landing page", "list my OD projects", "the design daemon", "the streaming design tool", and on any 401/404/422 error coming from an `od_*` tool call. Covers env-var setup (`OD_DAEMON_URL`, auth modes, BYOK), the full PRD → generate → save → lint workflow, error diagnosis, and the safety rails (lint before save, never commit BYOK keys). Triggers even if the user doesn't explicitly say "open-design-mcp" — keyword matches on `od_*` tool names or "design generation" workflows are enough.
tools
Use this skill whenever a user wants the **full Open Design experience** — discovery questions asked first, brand-spec extraction from URLs/files, TodoWrite planning with live updates, 5-dimensional self-critique, polished artifact at the end. Trigger phrases include "design with questions first", "OD-style workflow", "full interactive design brief", "make me a complete landing page" (when the user wants quality over speed), "design my pitch deck", "brand-aware multi-page site", "follow the Open Design playbook", or any request where the user is starting a new design project rather than tweaking an existing artifact. Also trigger on any request that mentions wanting brand consistency across multiple pages or that provides a brand URL/spec. Pair with the `open-design-mcp` tool-reference skill — both loaded together give an LLM the full picture (this skill = workflow choreography; that skill = tool catalog + errors). This skill explicitly does NOT trigger for one-off tweaks ("make the nav stickier", "swap slide 3 image") — use od_generate_design directly for those.
development
Sync a locally-developed OpenCode skill to the skill-manager npm package and (if private) the private-skills GitHub repo. Handles per-skill version bumps, public/private classification, build verification, and conventional-commit-style git push. Auto-publish to npm is handled downstream by nano-step/shared-workflows@v1 when the push to master lands. Use this skill whenever the user says 'sync skill', 'publish skill', 'push skill to manager', '/sync-skill-to-manager <name>', or asks to release/distribute a skill they just edited.