Skill: geoly-geo/geo-content-publisher-2 (version 0.1.0)

--- name: geo-content-publisher description: > End-to-end GEO content publishing and distribution orchestrator. Use this skill whenever the user mentions publishing or distributing GEO-optimized content across multiple channels (blog, docs, landing pages, social, newsletter, app updates, etc.), wants to turn one core piece into many channel-specific variants, or wants to make new or updated content highly visible to AI crawlers and generative engines. Always consider this skill when the user combines content optimization, multi-platform distribution, and AI search visibility in the same request. --- # GEO Content Publisher An orchestration skill for **GEO content publishing automation** that connects the full pipeline: 1. Content optimization (often using other GEO skills) 2. Multi-platform publishing & distribution 3. AI crawler and generative engine signaling This skill focuses on **workflow design, orchestration, and packaging**, not on replacing the specialized GEO skills (like optimizers or schema generators). It should **coordinate** them. --- ## When to use this skill Invoke this skill **whenever**: - The user has (or plans to have) GEO-optimized content and asks to: - Publish it to multiple channels (website, blog, docs, product pages, social media, newsletter, etc.) - Turn one “pillar” piece into multiple **channel-specific variants** - Plan and schedule a **content release campaign** around one or more GEO pages - The user wants their content to be: - **Highly visible to AI search / generative engines** (ChatGPT, Perplexity, Gemini, Claude, SGE) - Properly surfaced to crawlers via **sitemaps, llms.txt, Schema.org, and internal linking** - The user mentions: - “End-to-end GEO workflow”, “full-funnel GEO content”, “publish to multiple platforms” - “Syndicate this article”, “turn into LinkedIn + Twitter + newsletter” - “Push this new page so AI models can see it”, “make AI pick up this content” Do **not** limit triggering only to the exact keywords above; trigger whenever the **intent** is: “Take optimized content and push it out broadly in a GEO-conscious way.” --- ## Relationship to other GEO skills When available, this skill should **coordinate** with these skills rather than re-implement them: - `geo-studio`: for overall GEO strategy and prioritization - `geo-content-optimizer`: to refine content before publishing - `geo-structured-writer`: to structure longform pages into AI-readable layouts - `geo-schema-gen`: to generate and refine Schema.org JSON-LD - `geo-llms-txt`: to design or update `llms.txt` and AI-targeted index pages - `geo-multimodal-tagger`: to optimize images, videos, and other media assets If these skills are not present, still follow the same **workflow shape** and explain what would be done, giving concrete, actionable outputs (copy, checklists, suggested structures). --- ## High-level workflow When this skill is used, follow this **9-step workflow** unless the user explicitly asks for only a subset. ### 1. Clarify publishing goals and constraints Briefly but explicitly identify: - **Core asset(s)**: - What is the main piece? (article, landing page, docs, FAQ, product page, dataset, video, etc.) - Is it already written and optimized, or still in draft? - **Primary GEO goal**: - e.g., “be the default answer for X in AI search”, “own intent Y”, “support product feature Z” - **Target audience and geography**: - Who needs to see this? Any language/locale requirements? - **Time horizon**: - One-off launch vs. ongoing campaign; any hard launch dates? - **Channels in scope**: - Website main page, blog, docs, product catalog, knowledge base - Social platforms (LinkedIn, X/Twitter, Reddit, TikTok, etc.) - Email/newsletter, in-app messages, app store descriptions, etc. - **User’s stack constraints (if provided)**: - CMS used (WordPress, Webflow, headless, custom) - Any platforms that are off-limits Output a short **“Publishing Brief”** section summarizing this in 5–10 bullet points. ### 2. Inventory and (if needed) optimize the source content - If content is **already optimized**: - Quickly check for obvious GEO gaps: structure, headings, FAQs, internal links, schemas, media. - If another optimizer skill is available, call it or conceptually apply its workflow. - If content is **not optimized yet**: - Recommend running `geo-content-optimizer` and/or `geo-structured-writer` first. - If the user insists on skipping deep optimization, still: - Ensure basic structure (H1, H2/H3, clear sections) - Add an FAQ or Q&A block where appropriate - Suggest at least a minimal internal-link plan Produce a concise **“Content Readiness”** section with: - Key strengths for GEO - Gaps that need to be addressed before or during publishing - Whether you will optimize inline or rely on another skill ### 3. Design the channel strategy and mapping Create a **channel plan** that maps the core asset to multiple formats and entry-points. - Decide which channels are **primary** (SEO/GEO anchors) and which are **supporting** (distribution). - For each channel, define: - **Role** (e.g., “anchor page for AI citations”, “social proof amplifier”, “email follow-up”) - **Key message focus** and adaptation (tone, length, proof level, CTA) - **Linking strategy** (which canonical URL to point to; how it supports the GEO target) - **Cadence** if multi-post/ongoing (e.g., 1 hero launch + 3 follow-ups) Output as a **markdown table** like: ```markdown | Channel | Role | Format / Asset Type | Primary CTA | Links to / Canonical | |-------------|-----------------------------|-------------------------|-----------------------------|----------------------| | Website LP | GEO anchor & canonical URL | Longform landing page | Start trial / Request demo | Self (canonical) | | Blog | Context + educational angle | Article with FAQ | Read full guide (LP) | LP | | LinkedIn | Thought leadership & reach | Post + carousel | Visit LP + comment | LP | | Newsletter | Deep-dive for subscribers | Email + link to LP/blog | Click to read full article | LP / Blog | ``` ### 4. Generate channel-specific content variants For each channel in the plan, **generate or refine** content variants that: - Respect channel constraints: - Length and formatting (e.g., LinkedIn vs. Twitter vs. email) - Visual vs. text-heavy - Preserve **core GEO messaging**: - Clear description of topic / entity / product - Concrete facts that models can safely cite - Stable terminology and entity naming - Include **explicit citation anchors** where helpful: - “According to [BrandName]’s guide on [topic]…” - Short, self-contained definitions that AI can safely quote Outputs for this step: - A section `## Channel Content Variants` with subheadings: - `### Website / Landing Page` - `### Blog Article` - `### Documentation / Knowledge Base` - `### Social (per platform)` - `### Newsletter / Email` - `### Other (e.g. app store, in-app banner, etc.)` - Under each, provide **ready-to-use** drafts (copy, suggested headings, bullets, CTAs). ### 5. Structure pages for AI readability For **web and longform** surfaces (website, blog, docs, KB): - Ensure the following structure (can be customized per page type): ```markdown # [Clear, entity-focused H1] ## Summary - 2–4 bullet summary focused on facts and definitions. ## What is [Topic]? Explain in clear, fact-focused language that is easy to quote. ## Why it matters Explain use cases, benefits, risks, etc. ## How [Brand/Product] helps Connect topic to the user’s product/service, if relevant. ## FAQ Q1: ... A1: ... Q2: ... A2: ... ``` - If `geo-structured-writer` is available, mention that this layout follows its guidance or that it could further refine the structure. - Explicitly call out **sections that are especially useful for AI citation** (definitions, FAQs, concise summaries). ### 6. Attach structured data and media metadata For all relevant pages: - Use or conceptually apply `geo-schema-gen` to propose: - `Article`, `BlogPosting`, `WebPage`, `FAQPage`, `Product`, or `HowTo` schemas as appropriate. - Include key fields: `headline`, `description`, `url`, `author`, `publisher`, `datePublished`, `mainEntityOfPage`, etc. - For images and videos: - Use or conceptually apply `geo-multimodal-tagger` to generate: - Descriptive but concise **alt text** - **File names** that reflect the topic/entity - Optional `ImageObject` / `VideoObject` schemas. Output: - A section `## Structured Data Package` that includes: - JSON-LD snippets (as code blocks) - A table mapping URLs to the schema types you recommend - Example alt text and filenames for key media assets ### 7. Plan the technical publishing steps You **do not** have direct access to the user’s CMS or APIs, so your job is to: - Produce **implementation checklists** for each major system: - CMS / website - Blog / docs / knowledge base - Email platform - Social scheduling tool(s) - For each checklist, include: - Fields and settings that must be filled (titles, meta descriptions, slugs, canonical URLs) - How to embed JSON-LD (theme template, tag manager, custom HTML, etc.) - How to ensure **clean URLs** and avoid duplicate URLs that dilute GEO signals - Any caching or build/deploy steps (for static / headless setups) Output: - A section `## Implementation Checklists` with subsections per system, using bullet lists. ### 8. AI crawler and generative engine signaling This step focuses on making the new/updated content more easily discoverable by: - Classical search crawlers (Google, Bing, etc.) - AI-specific crawlers and model ingestion systems where possible Actions to recommend: - **Sitemaps** - Confirm new URLs appear in the appropriate XML sitemaps (and HTML sitemaps if applicable). - If the user runs a headless or static site, specify where sitemaps are typically located and how they may be updated or regenerated. - **llms.txt and AI index pages** - Use or conceptually apply `geo-llms-txt` to: - Add or update entries pointing to the new content. - Group related content into clearly named sections (e.g., “Pricing guides”, “Implementation playbooks”, “Product docs for X”). - **Internal linking** - Suggest 5–20 **high-value internal link targets** that should now link to this new content. - Prioritize pages that: - Already rank / are cited for the same or adjacent intent - Are high-traffic or high-authority - **External exposure** - Propose low-friction actions to get early references: - Share with partners - Answer relevant questions on communities/QA platforms, linking to the canonical page Output: - A section `## AI & Crawler Signaling Plan` with: - A bullet checklist of concrete steps - A small table listing “URL → sitemap / llms.txt / internal link recommendations” ### 9. Final publishing plan and timeline Summarize everything into a **single, execution-ready publishing plan**: - **Timeline** (at least ordered steps; include dates if user provided them) - **Who does what** (if roles or teams are known or can be implied) - **Dependencies** (e.g., “publish LP before social”, “schema update before PR push”) - **Success metrics** that are realistic for GEO: - e.g., increased impressions/clicks from AI search, number of AI citations found in answers, traffic and engagement for target pages, newsletter clicks, etc. Output: - A `## Final Plan` section with: - A short executive summary (3–6 bullets) - A step-by-step list (checklist style) - A compact table of “Metric → Why it matters → How to measure” --- ## Output format Unless the user explicitly requests a different format, structure your answer as: 1. `## Publishing Brief` 2. `## Content Readiness` 3. `## Channel Strategy` 4. `## Channel Content Variants` 5. `## Page Structure for AI Readability` 6. `## Structured Data Package` 7. `## Implementation Checklists` 8. `## AI & Crawler Signaling Plan` 9. `## Final Plan` Use: - **Markdown headings and tables** for structure - Bulleted lists instead of dense paragraphs - Short, actionable sentences suitable for copying into task trackers, docs, or briefs If the user only asks for a **subset** (e.g., “social posts + email only”), still keep the headings but clearly mark skipped sections (e.g., “Not in scope for this request”). --- ## Examples of triggering prompts These are **example user prompts** that should trigger this skill (for reference; not user-facing): - “We just finished a GEO-optimized pillar article about ‘zero-trust data governance’. Help me turn this into a full publishing plan: main page + blog + docs + LinkedIn + newsletter, and make sure AI models will pick it up.” - “I’ve got a new product feature page and I want it to become the default answer in ChatGPT and Perplexity when people ask about [topic]. Can you help me design the publishing and distribution workflow?” - “Take this case study and roll it out everywhere: website hero section, landing page, PDF, LinkedIn, X, email, internal wiki. Also suggest how to configure llms.txt and sitemaps so AI crawlers see it.” - “I want a repeatable playbook for how we publish any new GEO content across our whole stack (WP site, HubSpot email, LinkedIn, X). Please write the workflow and checklists.” You do **not** need to surface this list directly to the user; it is here to clarify intent. ---

path: evals/evals.json
content: {
  "skill_name": "geo-content-publisher",
  "evals": [
    {
      "id": 1,
      "prompt": "We just finished a GEO-optimized pillar article about 'AI-powered contract management'. Help me design a full publishing workflow: website landing page, supporting blog post, LinkedIn posts, a short email for our newsletter, and recommendations for sitemaps / llms.txt / schema so AI models can pick it up.",
      "expected_output": "A structured markdown plan following the skill's output format, including Publishing Brief, Content Readiness, Channel Strategy, Channel Content Variants, Structured Data Package, AI & Crawler Signaling Plan, and Final Plan sections.",
      "files": []
    },
    {
      "id": 2,
      "prompt": "I have a long-form case study about how our product improved conversion rate for a SaaS client. Turn this into a repeatable GEO publishing playbook: which pages to create or update on our site, how to repurpose it for LinkedIn and X, what to send to our email list, and how to make sure ChatGPT and Perplexity discover it.",
      "expected_output": "A detailed, step-by-step publishing playbook that maps the case study into multiple channels, proposes internal linking, suggests schema types, and outlines AI crawler signaling tasks, formatted using the skill's recommended headings.",
      "files": []
    },
    {
      "id": 3,
      "prompt": "We are launching a new pricing guide that we want AI assistants to cite when users ask about our product's pricing model. Create an end-to-end GEO publishing and distribution plan that covers our main pricing page, supporting docs, FAQ, social announcement posts, and specific steps for sitemaps, llms.txt, and internal links.",
      "expected_output": "An end-to-end GEO publishing and distribution plan with all standard sections, clearly describing how the pricing guide becomes the canonical source, how different channels support it, and how AI crawlers and models are signaled.",
      "files": []
    }
  ]
}



path: references/publishing-templates.md
content: # GEO Content Publisher – Reference Templates

This file provides reusable templates and examples that the `geo-content-publisher` skill can draw
on without having to rewrite them from scratch every time.

Keep this file short, skimmable, and easy to adapt. The goal is to speed up reasoning and output
generation, not to be a full textbook.

---

## 1. Default longform page structure

Use this structure for **landing pages, pillar articles, and longform docs** that you want AI models
to cite. Adapt headings as needed, but try to preserve the overall logic.

```markdown
# [Clear, entity-focused H1]

## Summary
- 2–4 bullet points summarizing what this page is about.
- Focus on concrete facts, definitions, and stable product claims.

## What is [Topic or Product]?
Explain in clear, factual language:
- A short definition in 1–2 sentences.
- A slightly longer explanation (1–2 paragraphs) with simple examples.

## Why [Topic] matters
- Describe the main problems, risks, or opportunities.
- Use concrete, real-world scenarios.

## How [Brand/Product] helps
- Tie the topic back to the brand or product.
- Highlight 3–5 key capabilities or benefits.
- Optionally include a comparison table vs. alternatives.

## Key use cases
- Use case 1: [Name]
  - Who it is for
  - What changes for them
- Use case 2: [Name]
- Use case 3: [Name]

## Implementation or getting started
- Step 1: ...
- Step 2: ...
- Step 3: ...

## FAQ
Q1: [Common question]
A1: [Short, self-contained answer.]

Q2: [Common question]
A2: [Short, self-contained answer.]

Q3: [Common question]
A3: [Short, self-contained answer.]
```

---

## 2. Channel plan table template

Standard table for mapping the **core asset** to multiple channels.

```markdown
| Channel      | Role / Objective              | Format / Asset Type         | Primary Message / Angle                  | Primary CTA                    | Canonical Target |
|-------------|-------------------------------|-----------------------------|------------------------------------------|--------------------------------|------------------|
| Website LP  | GEO anchor & main converter   | Longform landing page       | Core value prop + social proof           | Start trial / Request demo     | Pricing LP       |
| Blog        | Educational context & support | Article + FAQ               | Zoom into one angle or problem scenario  | Read full guide / See pricing  | Pricing LP       |
| Docs / KB   | Implementation detail         | How-to / concept docs       | “How it works” and technical specifics   | Implement feature / Configure  | Docs home        |
| LinkedIn    | Thought leadership            | Post + optional carousel    | Strategic angle + 1–2 data points        | Visit LP / Comment             | Pricing LP       |
| X / Twitter | Awareness + curiosity         | Short threads / single post | Punchy hook + 1 key benefit or example   | Click through to LP or blog    | LP or blog       |
| Newsletter  | Deep-dive for subscribers     | Email feature or digest     | Why this matters now for this audience   | Read more / Book a call        | LP / blog        |
```

When generating a real plan, fill each cell with **concrete, user-specific content**, not placeholders.

---

## 3. Social post patterns

### 3.1 LinkedIn post pattern (B2B)

```markdown
Hook line introducing the core problem or opportunity in 1–2 sentences.

Short paragraph explaining:
- What has changed in the market / environment.
- Why this matters now for [target audience].

Bulleted list (3–5 bullets) covering:
- Key insight or data point #1
- Key insight or data point #2
- Key insight or data point #3

Transition: “We’ve put together a detailed guide on [topic] covering:”
- Section 1 summary
- Section 2 summary
- Section 3 summary

CTA: “Read the full guide here → [link to canonical LP or article]”

Optional: Ask a question to invite comments.
```

### 3.2 X / Twitter thread pattern

```markdown
1/ Strong hook about the core problem or surprising insight.

2/ Short explanation of why this matters for [audience].

3–5/ Each tweet covers:
- One clear idea
- One example or data point
- Plain language (no jargon if avoidable)

Final tweet:
“We put everything into a deep-dive on [topic], including [A], [B], [C]. Read it here → [link]”
```

---

## 4. Email / newsletter snippet template

```markdown
Subject: [Outcome-focused subject about topic or benefit]

Hi [First name / there],

In the last [time period], we’ve seen [problem or trend] become a top priority for [audience].

To help, we created a new resource on [topic], covering:
- [Key takeaway 1]
- [Key takeaway 2]
- [Key takeaway 3]

If you’re working on [situation 1] or [situation 2], this will help you:
- [Result / benefit 1]
- [Result / benefit 2]

👉 Read the full guide: [canonical link]

Best,
[Brand / Team]
```

---

## 5. Minimal JSON-LD examples

These are **skeletal** examples to keep in mind when generating schema. Always adapt fields to the
user’s actual site, URLs, and organization data.

### 5.1 Article / BlogPosting skeleton

```json
{
  "@context": "https://schema.org",
  "@type": "Article",
  "headline": "TITLE HERE",
  "description": "1–2 sentence summary of the article.",
  "url": "https://example.com/path",
  "author": {
    "@type": "Person",
    "name": "Author Name"
  },
  "publisher": {
    "@type": "Organization",
    "name": "Brand Name",
    "logo": {
      "@type": "ImageObject",
      "url": "https://example.com/logo.png"
    }
  },
  "datePublished": "2025-01-01",
  "mainEntityOfPage": "https://example.com/path"
}
```

### 5.2 FAQPage skeleton

```json
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "Question 1?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Short, self-contained answer to question 1."
      }
    },
    {
      "@type": "Question",
      "name": "Question 2?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Short, self-contained answer to question 2."
      }
    }
  ]
}
```

---

## 6. Alt text and filename patterns

- Prefer: `alt="Dashboard showing monthly MRR by cohort for SaaS product"`  
  Over: `alt="screenshot"` or `alt="image"`.

- Prefer filenames like:
  - `zero-trust-data-governance-architecture.png`
  - `pricing-tier-comparison-startup-vs-enterprise.png`

Avoid:
- `image1.png`, `screenshot-final.png`, `diagram-new-new-2.png`



path: scripts/generate_channel_plan.py
content: import argparse
import json
from typing import List, Dict


def generate_table(channels: List[Dict[str, str]]) -> str:
    """
    Generate a markdown channel plan table from a list of channel definitions.

    Each channel dict may contain:
      - name
      - role
      - format
      - message
      - cta
      - canonical
    Missing fields will be rendered as empty cells.
    """
    headers = [
        "Channel",
        "Role / Objective",
        "Format / Asset Type",
        "Primary Message / Angle",
        "Primary CTA",
        "Canonical Target",
    ]
    lines = []
    # Header
    lines.append("| " + " | ".join(headers) + " |")
    lines.append("|" + "|".join(["-" * (len(h) + 2) for h in headers]) + "|")

    for ch in channels:
        row = [
            ch.get("name", ""),
            ch.get("role", ""),
            ch.get("format", ""),
            ch.get("message", ""),
            ch.get("cta", ""),
            ch.get("canonical", ""),
        ]
        lines.append("| " + " | ".join(row) + " |")

    return "\n".join(lines)


def main() -> None:
    parser = argparse.ArgumentParser(
        description=(
            "Generate a markdown channel plan table for geo-content-publisher.\n\n"
            "Input JSON format example:\n"
            '[{"name": "Website LP", "role": "GEO anchor", '
            '"format": "Landing page", "message": "Core value prop", '
            '"cta": "Start trial", "canonical": "/product"}]'
        )
    )
    parser.add_argument(
        "--input",
        "-i",
        type=str,
        required=True,
        help="Path to JSON file containing a list of channel definitions.",
    )
    parser.add_argument(
        "--output",
        "-o",
        type=str,
        help="Optional path to write the markdown table to. Prints to stdout if omitted.",
    )
    args = parser.parse_args()

    with open(args.input, "r", encoding="utf-8") as f:
        data = json.load(f)

    if not isinstance(data, list):
        raise ValueError("Input JSON must be a list of channel objects.")

    table_md = generate_table(data)

    if args.output:
        with open(args.output, "w", encoding="utf-8") as f:
            f.write(table_md)
    else:
        print(table_md)


if __name__ == "__main__":
    main()



path: scripts/generate_page_structure_snippet.py
content: import argparse
from textwrap import dedent


def build_structure(topic: str, brand: str) -> str:
    """
    Return a markdown skeleton for a GEO-friendly longform page
    about `topic` for `brand`.
    """
    topic_display = topic or "Your Topic"
    brand_display = brand or "Your Brand"

    template = f"""
    # {topic_display}: Complete Guide by {brand_display}

    ## Summary
    - 2–4 bullet points summarizing what this page covers about {topic_display}.
    - Focus on concrete facts, definitions, and stable claims that AI assistants can safely cite.

    ## What is {topic_display}?
    Explain in clear, factual language:
    - A short definition in 1–2 sentences.
    - A slightly longer explanation (1–2 paragraphs) with simple examples.

    ## Why {topic_display} matters
    - Describe the main problems, risks, or opportunities that {topic_display} addresses.
    - Use concrete, real-world scenarios relevant to your target audience.

    ## How {brand_display} helps with {topic_display}
    - Tie the topic back to {brand_display}'s product or services.
    - Highlight 3–5 key capabilities or benefits.

    ## Key use cases
    - Use case 1: [Name]
      - Who it is for
      - What changes for them
    - Use case 2: [Name]
    - Use case 3: [Name]

    ## Implementation / Getting started
    - Step 1: ...
    - Step 2: ...
    - Step 3: ...

    ## FAQ
    Q1: [Common question about {topic_display}]
    A1: [Short, self-contained answer.]

    Q2: [Another question about {topic_display}]
    A2: [Short, self-contained answer.]
    """
    return dedent(template).strip() + "\n"


def main() -> None:
    parser = argparse.ArgumentParser(
        description="Generate a markdown page structure snippet for geo-content-publisher."
    )
    parser.add_argument(
        "--topic",
        "-t",
        type=str,
        required=True,
        help="Topic of the page (e.g. 'Zero-trust data governance').",
    )
    parser.add_argument(
        "--brand",
        "-b",
        type=str,
        required=False,
        default="Your Brand",
        help="Brand or product name to mention in the structure.",
    )
    parser.add_argument(
        "--output",
        "-o",
        type=str,
        help="Optional path to write the markdown snippet to. Prints to stdout if omitted.",
    )
    args = parser.parse_args()

    snippet = build_structure(args.topic, args.brand)

    if args.output:
        with open(args.output, "w", encoding="utf-8") as f:
            f.write(snippet)
    else:
        print(snippet)


if __name__ == "__main__":
    main()



Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (MEDIUM)