Claude
Skills
Sign in
Back

new-post-mmw

Included with Lifetime
$97 forever

Create a new blog post via guided interview.

Writing & Docs

What this skill does


<references>
  <reference name="media-guide" path="../add-media/references/media-guide.md" />
</references>

<purpose>
You are creating a new blog post for the user. Use a structured interview to gather requirements, then generate a well-crafted post following their platform's conventions.
</purpose>

<steps>

  <step id="load-config" number="1">
    <description>Load Configuration</description>

    <load-config>
      <action>Resolve the user's home directory.</action>
      <command language="bash" output="home" tool="Bash">echo $HOME</command>
      <constraint>Never pass `~` to the Read tool.</constraint>

      <read path="<home>/.things/config.json" output="config" />
      <if condition="config-missing">Tell the user: "Run `/things:setup-things` first." Then stop.</if>

      <read path="<home>/.things/mark-my-words/preferences.json" output="preferences" />
      <if condition="preferences-missing">Tell the user: "Run `/setup-mmw` first." Then stop.</if>
    </load-config>

    <action>Read `platform` from preferences.json (default to `quartz` if not set). Read the platform template from `../../platforms/<platform>.md` (relative to this skill's directory). This template defines all platform-specific formatting rules -- frontmatter fields, content syntax, image format, callouts, code blocks, and file naming conventions. Follow the template's rules throughout post generation.</action>

    <action>Load voice profile.</action>
    <if condition="default-voice-set">
      <read path="<home>/.things/mark-my-words/voices/<default_voice>.md" output="voice" />
      <if condition="voice-file-missing">Warn the user that their default voice profile is missing and continue without a voice.</if>
    </if>
    <action>Also check if any voice profiles exist in `<home>/.things/mark-my-words/voices/` using Glob. Store this for the interview step.</action>

    <action>Resolve media directory.</action>
    <if condition="media-dir-set">Resolve the full media path as `<content_root>/<media_dir>` and ensure the directory exists (`mkdir -p`). Store this path for use in the writing and media processing steps.</if>
  </step>

  <step id="resolve-content-location" number="2">
    <description>Resolve Content Location</description>

    <if condition="source-type-remote">
      <action>Check if the repo is already cloned at `<workdir>` (read `workdir` from preferences.json, default `<home>/.mark-my-words`).</action>
      <if condition="not-cloned">
        <command language="bash" tool="Bash">git clone --branch <repo_branch> <repo_url> <workdir></command>
      </if>
      <if condition="already-cloned">Pull latest changes.</if>
      The content root is `<workdir>/<content_dir>/`.
    </if>
    <if condition="source-type-local">The content root is `<local_path>/<content_dir>/`.</if>
  </step>

  <step id="scan-existing-posts" number="3">
    <description>Scan Existing Posts</description>

    <action>Use Glob and Grep to scan the content directory:</action>
    - Find all `.md` files in the target subdirectory
    - Extract existing tags from frontmatter across posts (look for `tags:` in YAML frontmatter, or `tags = [` for TOML platforms like Zola)
    - Note the directory structure for suggesting where to place the new post
    - This informs tag suggestions and helps maintain consistency
  </step>

  <step id="interview-user" number="4">
    <description>Interview the User</description>

    Use AskUserQuestion for each of these, adapting based on `$ARGUMENTS` if provided:

    <ask-user-question>
      <question>Post title</question>
      <if condition="arguments-provided">Suggest a title based on it.</if>
      Let the user accept, modify, or provide their own. Keep it concise and engaging.
    </ask-user-question>

    <ask-user-question>
      <question>Target length</question>
      <option>Short (~500 words) -- quick tip, TIL, brief note</option>
      <option>Medium (~1000 words) -- tutorial, explanation, walkthrough</option>
      <option>Long (~2000+ words) -- deep dive, comprehensive guide</option>
    </ask-user-question>

    <ask-user-question>
      <question>Key points/sections: What should the post cover? What are the main things the reader should learn or take away?</question>
      Let the user describe in their own words.
    </ask-user-question>

    <ask-user-question>
      <question>Tags</question>
      Present a combined list of:
      - Tags found in existing posts
      - The user's `default_tags` from preferences.json
      - Allow the user to pick multiple and/or add custom tags
    </ask-user-question>

    <ask-user-question>
      <question>Target directory</question>
      Show the default from preferences.json (`default_subdirectory`). Let them override if they want to put it elsewhere.
    </ask-user-question>

    <action>Voice selection (only if voice profiles exist in `<home>/.things/mark-my-words/voices/`).</action>
    <if condition="default-voice-set">Show it and ask if they want to use it, pick a different one, or skip voice for this post.</if>
    <if condition="no-default-voice">List available voices and let them pick one or skip.</if>
    <if condition="only-one-voice">Just confirm they want to use it.</if>

    <ask-user-question>
      <question>Draft status</question>
      <option>Publish immediately (`draft: false`, or platform-specific equivalent like `published: true` for Jekyll)</option>
      <option>Save as draft (`draft: true`, or place in `_drafts/` for Jekyll)</option>
    </ask-user-question>

    <if condition="media-dir-configured">
      <ask-user-question>
        <question>Visuals</question>
        <option>I have specific images (file paths or URLs)</option>
        <option>Find relevant images for me</option>
        <option>Generate Mermaid diagrams for visual concepts (only if the platform template indicates Mermaid support)</option>
        <option>No visuals for this post</option>
        <option>Decide as we write</option>
      </ask-user-question>
      <if condition="user-provides-images">Collect paths/URLs and descriptions for processing in Step 5.5.</if>
      <if condition="user-web-search">Note topics to search during writing.</if>
      <if condition="user-mermaid">Actively generate diagrams where they fit during Step 5.</if>
      <if condition="user-decide-as-we-write">Activate auto-suggest behavior for this post regardless of the `auto_suggest_visuals` config setting.</if>
    </if>
  </step>

  <step id="write-post" number="5">
    <description>Write the Post</description>

    <action>Generate the blog post following the platform template loaded in Step 1.</action>

    <action>Generate platform-compatible frontmatter following the template:</action>
    - Use the platform's frontmatter format (YAML `---` or TOML `+++`)
    - Use the platform's field names (e.g., `pubDate` for Astro, `date` for most others)
    - `title`: From the interview
    - Date: Today's date in the platform's expected format
    - `description`: 1-2 sentence preview for SEO/social
    - Tags: From the interview, using the platform's tag format
    - Draft status: From the interview (or platform equivalent)
    - Author: From professional profile or config.json

    <if condition="voice-profile-selected">Follow its guidance for tone, sentence patterns, vocabulary, rhetorical habits, structure, and things to avoid. The voice profile takes precedence over generic style defaults -- write as the profile describes, not in a generic "natural, engaging" voice.</if>
    <if condition="no-voice-profile">Write in a natural, engaging voice.</if>
    <action>Use clear heading hierarchy (h2 for sections, h3 for subsections). Include code blocks with language identifiers when relevant.</action>

    <action>Use the platform's native content features as documented in the template.</action>
    <if condition="platform-supports-callouts">Use them where they add value.</if>
    <if condition="platform-no-callouts">Use em

Related in Writing & Docs