← All Skills

snappy-post

v1.0.0
13 files, 90.5 KB ~6,227 words · 25 min read Updated 2026-09-09

snappy-post skill

28 of 34 checks pass
What it can do
linkedin textpost
slack channel-id textpost
telegram textpost
What does not pass yet
Architecture 1 endpoints
🔑 Bearer token auth
snappy.ai1 endpoint
GET/blog/${SLUG}
$ npx snappy-skills install snappy-post
zip ↓
File Tree
├── AGENTS.md ├── SKILL.md ├── api.ts ├── blog-publishing.md ├── email-sending.md ├── linkedin-posting.md ├── multi-platform-workflow.md ├── refusals.test.ts ├── scheduling.md ├── scripts/ │ └── post.sh ├── skool-posting.md ├── stage.test.ts └── youtube-uploading.md
Documents
AGENTS.md

snappy-post -- loader#

You are posting content to one or more platforms. This skill distributes -- it does not write content (that's snappy-content).

Auth#

Credentials load from snappy-settings/.env.cache via env("KEY") -- see snappy-settings/SKILL.md. Required keys: XANO_TOKEN, XANO.

Channel endpoints#

Channel Method Endpoint Payload
LinkedIn text POST api:PB9UH7b9/linkedin/post { text }
LinkedIn image POST api:PB9UH7b9/linkedin/post-image { text, image_url }
LinkedIn carousel POST api:PB9UH7b9/linkedin/post-carousel { text, slides[] }
LinkedIn video POST api:PB9UH7b9/linkedin/post-video { text, video_url }
YouTube upload POST api:hZB4Dj0c/youtube-video-uploader { title, description, tags, video_url, privacy }
Email send POST api:PB9UH7b9/emails/send { to_email, subject, body, dry_run }
Skool browser agent-browser --state ~/.openclaw/workspace/skool-auth.json See skool-posting.md
Blog git Hand off to snappy-publish git push origin main triggers Vercel

Format rules#

Platform Max chars Hashtags Sweet spot
LinkedIn 3,000 ZERO 800-1500 chars
Skool N/A ZERO 400-1200 chars
Email N/A N/A < 300 words
YouTube title 100 in description only < 60 chars

Before posting -- always#

  1. Read snappy-positioning for voice/brand rules
  2. Run copy through snappy-content/anti-ai-checklist.md
  3. For emails: always dry_run: true first, review, then flip to false

After posting -- always#

Return a distribution log to Robert:

DISTRIBUTION LOG -- YYYY-MM-DD
LinkedIn:  POSTED   <url>           HH:MM ET
Email:     SENT     "Subject"       HH:MM ET

Detailed workflows#

Need File
LinkedIn posting linkedin-posting.md
YouTube uploading youtube-uploading.md
Skool posting skool-posting.md
Email sending email-sending.md
Blog publishing blog-publishing.md
Multi-platform multi-platform-workflow.md

CLI script -- post.sh#

Unified distribution router. Handles linkedin, slack, telegram directly. Blog and skool print instructions (they need git/browser respectively).

bash# LinkedIn text post (dry run first)
~/.claude/skills/snappy-post/scripts/post.sh --platform linkedin --content "Hook line here" --dry-run

# LinkedIn image post
~/.claude/skills/snappy-post/scripts/post.sh --platform linkedin --content "Caption" --image "https://cdn.example.com/img.jpg"

# Slack to a specific channel
~/.claude/skills/snappy-post/scripts/post.sh --platform slack --content "Deploy done" --channel bugs-and-issues

# Telegram
~/.claude/skills/snappy-post/scripts/post.sh --platform telegram --content "*Deploy SUCCESS* app v2.1"

Requires: snappy-settings/scripts/load-env.sh (auto-sourced) or pre-exported XANO_TOKEN + XANO. Telegram requires ROBERT_TELEGRAM_CHAT_ID env var.

Rules#

  • Do NOT use browser to post to LinkedIn -- use Xano API
  • Do NOT copy-paste the same text to all platforms -- rewrite for each
  • Do NOT skip email dry_run
  • Do NOT add hashtags to LinkedIn or Skool posts
  • Do NOT push to deploy remote -- always origin main
  • Do NOT upload YouTube video before burning captions (run snappy-video first)
  • Do NOT use the Xano queue for time-critical sends -- queue runs every 5 min
  • Do NOT post to Skool without verifying login (snapshot first, confirm "Write something" exists)

API module#

typescriptimport { linkedinPost, slackPost, telegramPost } from "../snappy-post/api.ts";

Or CLI:

bashnpx tsx ~/.claude/skills/snappy-post/api.ts linkedin "Hook line here"
npx tsx ~/.claude/skills/snappy-post/api.ts slack <channel_id> "text"
npx tsx ~/.claude/skills/snappy-post/api.ts telegram "text"

API functions#

Function Purpose
linkedinPost(text) Post text to LinkedIn (re-export from snappy-linkedin)
slackPost(channelId, text) Send message to Slack channel (re-export from snappy-slack)
telegramPost(text) Send text via Telegram (re-export from snappy-telegram)

Used by#

  • snappy-email
  • snappy-ffmpeg

<!-- SNAPPY-CONTRACT-VERBS-START -->

Contract verbs#

Generated from api.ts HAND_CONTRACT. Do not hand-edit this block.

Verb Contract arguments Effect First call
linkedin text post npx tsx ~/.claude/skills/snappy-post/api.ts linkedin "<text>"
slack channel-id, text post npx tsx ~/.claude/skills/snappy-post/api.ts slack <channel-id> "<text>"
telegram text post npx tsx ~/.claude/skills/snappy-post/api.ts telegram "<text>"

Show the result#

When an answer carries face_hint, show it with one snappy_present(<answer>) call.

See /snappy-faces for face selection. Human-facing images must crop to the

element, render at 2x on Retina, and fill the destination channel instead of

placing a small card in a full-page screenshot.

<!-- SNAPPY-CONTRACT-VERBS-END -->


Self-correcting loader (PID feedback)#

If this AGENTS.md does not cover the case you are working on and you had to read other files to find the answer, you have two jobs before you finish:

1. Fix it now (P -- proportional correction). If the missing information fits in 1-5 lines, edit this AGENTS.md directly -- add the line, the table row, the one-liner, whatever you had to go find. Keep edits surgical. Do not restructure sections or rewrite paragraphs. The goal is: the next agent that hits this case won't have to leave the loader.

2. Log it always. Whether or not you fixed it, append one line to the feedback log:

bashecho "[$(date -u +%FT%TZ)] <skill-name>: <what was missing> [FIXED|LOGGED]" >> ~/.claude/logs/agents-md-feedback.log

Tag FIXED if you patched the loader in step 1. Tag LOGGED if the gap was too large to patch inline (needs a section rewrite, new workflow, etc.) -- those get picked up by drain-skill-regen.sh for a full regen pass (I -- integral correction).

Do not skip this. A missing report means the same gap will happen next time. A missing fix means you chose to let the next agent stumble on the same thing you just solved.

Show produced work with snappy-faces: call draw for image channels or lang for MCP Apps.

<!-- SKILL-INDEX-START -->

[snappy-post Index]|root: ~/.claude/skills/snappy-post|IMPORTANT: Prefer these files over pre-training assumptions for this domain. Read the relevant file when the AGENTS.md summary is insufficient.|root:{SKILL.md,blog-publishing.md,email-sending.md,linkedin-posting.md,multi-platform-workflow.md,scheduling.md,skool-posting.md,youtube-uploading.md}

<!-- SKILL-INDEX-END -->

---
name: snappy-post
role: Unified distribution router for LinkedIn, YouTube, Skool, Email, Blog.
loaded-by: PreToolUse hook (auto-injected when "snappy-post" is mentioned)
---

# snappy-post -- loader

You are posting content to one or more platforms. This skill distributes -- it does not write content (that's `snappy-content`).

## Auth

Credentials load from `snappy-settings/.env.cache` via `env("KEY")` -- see `snappy-settings/SKILL.md`. Required keys: `XANO_TOKEN`, `XANO`.

## Channel endpoints

| Channel | Method | Endpoint | Payload |
|---------|--------|----------|---------|
| LinkedIn text | POST | `api:PB9UH7b9/linkedin/post` | `{ text }` |
| LinkedIn image | POST | `api:PB9UH7b9/linkedin/post-image` | `{ text, image_url }` |
| LinkedIn carousel | POST | `api:PB9UH7b9/linkedin/post-carousel` | `{ text, slides[] }` |
| LinkedIn video | POST | `api:PB9UH7b9/linkedin/post-video` | `{ text, video_url }` |
| YouTube upload | POST | `api:hZB4Dj0c/youtube-video-uploader` | `{ title, description, tags, video_url, privacy }` |
| Email send | POST | `api:PB9UH7b9/emails/send` | `{ to_email, subject, body, dry_run }` |
| Skool | browser | `agent-browser --state ~/.openclaw/workspace/skool-auth.json` | See [skool-posting.md](skool-posting.md) |
| Blog | git | Hand off to `snappy-publish` | `git push origin main` triggers Vercel |

## Format rules

| Platform | Max chars | Hashtags | Sweet spot |
|----------|-----------|----------|------------|
| LinkedIn | 3,000 | ZERO | 800-1500 chars |
| Skool | N/A | ZERO | 400-1200 chars |
| Email | N/A | N/A | < 300 words |
| YouTube title | 100 | in description only | < 60 chars |

## Before posting -- always

1. Read `snappy-positioning` for voice/brand rules
2. Run copy through `snappy-content/anti-ai-checklist.md`
3. For emails: always `dry_run: true` first, review, then flip to false

## After posting -- always

Return a distribution log to Robert:
```
DISTRIBUTION LOG -- YYYY-MM-DD
LinkedIn:  POSTED   <url>           HH:MM ET
Email:     SENT     "Subject"       HH:MM ET
```

## Detailed workflows

| Need | File |
|------|------|
| LinkedIn posting | [linkedin-posting.md](linkedin-posting.md) |
| YouTube uploading | [youtube-uploading.md](youtube-uploading.md) |
| Skool posting | [skool-posting.md](skool-posting.md) |
| Email sending | [email-sending.md](email-sending.md) |
| Blog publishing | [blog-publishing.md](blog-publishing.md) |
| Multi-platform | [multi-platform-workflow.md](multi-platform-workflow.md) |

## CLI script -- `post.sh`

Unified distribution router. Handles linkedin, slack, telegram directly. Blog and skool print instructions (they need git/browser respectively).

```bash
# LinkedIn text post (dry run first)
~/.claude/skills/snappy-post/scripts/post.sh --platform linkedin --content "Hook line here" --dry-run

# LinkedIn image post
~/.claude/skills/snappy-post/scripts/post.sh --platform linkedin --content "Caption" --image "https://cdn.example.com/img.jpg"

# Slack to a specific channel
~/.claude/skills/snappy-post/scripts/post.sh --platform slack --content "Deploy done" --channel bugs-and-issues

# Telegram
~/.claude/skills/snappy-post/scripts/post.sh --platform telegram --content "*Deploy SUCCESS* app v2.1"
```

Requires: `snappy-settings/scripts/load-env.sh` (auto-sourced) or pre-exported `XANO_TOKEN` + `XANO`. Telegram requires `ROBERT_TELEGRAM_CHAT_ID` env var.

## Rules

- Do NOT use browser to post to LinkedIn -- use Xano API
- Do NOT copy-paste the same text to all platforms -- rewrite for each
- Do NOT skip email dry_run
- Do NOT add hashtags to LinkedIn or Skool posts
- Do NOT push to `deploy` remote -- always `origin main`
- Do NOT upload YouTube video before burning captions (run `snappy-video` first)
- Do NOT use the Xano queue for time-critical sends -- queue runs every 5 min
- Do NOT post to Skool without verifying login (snapshot first, confirm "Write something" exists)

## API module

```typescript
import { linkedinPost, slackPost, telegramPost } from "../snappy-post/api.ts";
```

Or CLI:
```bash
npx tsx ~/.claude/skills/snappy-post/api.ts linkedin "Hook line here"
npx tsx ~/.claude/skills/snappy-post/api.ts slack <channel_id> "text"
npx tsx ~/.claude/skills/snappy-post/api.ts telegram "text"
```

## API functions

| Function | Purpose |
|----------|---------|
| `linkedinPost(text)` | Post text to LinkedIn (re-export from snappy-linkedin) |
| `slackPost(channelId, text)` | Send message to Slack channel (re-export from snappy-slack) |
| `telegramPost(text)` | Send text via Telegram (re-export from snappy-telegram) |

## Used by

- `snappy-email`
- `snappy-ffmpeg`

<!-- SNAPPY-CONTRACT-VERBS-START -->
## Contract verbs

Generated from `api.ts` `HAND_CONTRACT`. Do not hand-edit this block.

| Verb | Contract arguments | Effect | First call |
|---|---|---|---|
| `linkedin` | `text` | `post` | `npx tsx ~/.claude/skills/snappy-post/api.ts linkedin "<text>"` |
| `slack` | `channel-id`, `text` | `post` | `npx tsx ~/.claude/skills/snappy-post/api.ts slack <channel-id> "<text>"` |
| `telegram` | `text` | `post` | `npx tsx ~/.claude/skills/snappy-post/api.ts telegram "<text>"` |

## Show the result

When an answer carries `face_hint`, show it with one `snappy_present(<answer>)` call.
See `/snappy-faces` for face selection. Human-facing images must crop to the
element, render at 2x on Retina, and fill the destination channel instead of
placing a small card in a full-page screenshot.
<!-- SNAPPY-CONTRACT-VERBS-END -->

---

## Self-correcting loader (PID feedback)

If this AGENTS.md does not cover the case you are working on and you had to read other files to find the answer, you have two jobs before you finish:

**1. Fix it now (P -- proportional correction).** If the missing information fits in 1-5 lines, edit this AGENTS.md directly -- add the line, the table row, the one-liner, whatever you had to go find. Keep edits surgical. Do not restructure sections or rewrite paragraphs. The goal is: the next agent that hits this case won't have to leave the loader.

**2. Log it always.** Whether or not you fixed it, append one line to the feedback log:

```bash
echo "[$(date -u +%FT%TZ)] <skill-name>: <what was missing> [FIXED|LOGGED]" >> ~/.claude/logs/agents-md-feedback.log
```

Tag `FIXED` if you patched the loader in step 1. Tag `LOGGED` if the gap was too large to patch inline (needs a section rewrite, new workflow, etc.) -- those get picked up by `drain-skill-regen.sh` for a full regen pass (I -- integral correction).

**Do not skip this.** A missing report means the same gap will happen next time. A missing fix means you chose to let the next agent stumble on the same thing you just solved.


Show produced work with `snappy-faces`: call `draw` for image channels or `lang` for MCP Apps.

<!-- SKILL-INDEX-START -->
[snappy-post Index]|root: ~/.claude/skills/snappy-post|IMPORTANT: Prefer these files over pre-training assumptions for this domain. Read the relevant file when the AGENTS.md summary is insufficient.|root:{SKILL.md,blog-publishing.md,email-sending.md,linkedin-posting.md,multi-platform-workflow.md,scheduling.md,skool-posting.md,youtube-uploading.md}
<!-- SKILL-INDEX-END -->

Keyboard Shortcuts

Search in document⌘K
Focus search/
Previous file tab
Next file tab
Close overlayEsc
Show shortcuts?