# Crier: Cross-Post Your Content Everywhere

I've published **crier** to [PyPI](https://pypi.org/project/crier/) - a command-line tool for cross-posting content to multiple platforms simultaneously.

Like a town crier announcing news across the land, crier broadcasts your content to dev.to, Hashnode, Medium, Ghost, WordPress, Bluesky, Mastodon, Threads, Telegram, Discord, and more.

## Quick Start

```bash
pip install crier
cd your-blog
crier init
```

The `init` command walks you through setup: detecting content directories, configuring platforms with API keys.

## The Workflow

1. **Your markdown posts** with YAML front matter are the source of truth
2. **`.crier/registry.yaml`** tracks what's published where
3. **`crier audit`** shows what's missing or changed
4. **`crier publish`** publishes content

```bash
# See what needs publishing
crier audit

# Publish to multiple platforms
crier publish post.md --to devto --to bluesky --to mastodon

# Bulk publish everything missing
crier audit --publish --yes
```

## LLM-Powered Auto-Rewrite

The star feature: short-form platforms like Bluesky (300 chars) and Mastodon (500 chars) need custom summaries. Crier generates these automatically using any OpenAI-compatible LLM:

```bash
# Auto-generate short-form content
crier publish post.md --to bluesky --to mastodon --auto-rewrite

# Bulk publish with auto-rewrite
crier audit --publish --auto-rewrite --yes
```

**Simplest setup:** If you have `OPENAI_API_KEY` set, it just works (defaults to gpt-4o-mini).

**Or use local models:**

```yaml
# ~/.config/crier/config.yaml
llm:
  base_url: http://localhost:11434/v1  # Ollama
  model: llama3
```

The LLM generates platform-appropriate summaries that fit within character limits, with automatic retry if output is too long.

## Supported Platforms

| Platform | Type | Notes |
|----------|------|-------|
| **dev.to** | Blog | Full article support |
| **Hashnode** | Blog | Full article support |
| **Medium** | Blog | Publish/import mode |
| **Ghost** | Blog | Full article support |
| **WordPress** | Blog | Self-hosted or .com |
| **Buttondown** | Newsletter | Email subscribers |
| **Bluesky** | Social | Posts with link cards |
| **Mastodon** | Social | Toots with hashtags |
| **Threads** | Social | Short posts |
| **LinkedIn** | Social | Professional network |
| **Twitter/X** | Social | Copy-paste mode |
| **Telegram** | Channel | Bot posts |
| **Discord** | Channel | Webhook embeds |

## Bulk Operations with Filters

The audit command supports powerful filtering for targeted bulk operations:

```bash
# API platforms only (skip manual/import)
crier audit --publish --yes --only-api

# Long-form only (skip short-form social)
crier audit --publish --yes --long-form

# Random sample of 5 articles
crier audit --publish --yes --sample 5

# Filter by path and date
crier audit content/post --since 1m --only-api --publish --yes

# Combine filters
crier audit content/post --since 1w --only-api --long-form --sample 10 --publish --yes
```

| Filter | Description |
|--------|-------------|
| `[PATH]` | Only scan specific directory |
| `--since` | Only content from this date (`1d`, `1w`, `1m`, or `YYYY-MM-DD`) |
| `--only-api` | Skip manual/import platforms |
| `--long-form` | Skip short-form social platforms |
| `--sample N` | Random sample of N items |
| `--auto-rewrite` | Generate short-form content with LLM |

## Profiles

Group platforms into reusable profiles:

```yaml
# ~/.config/crier/config.yaml
profiles:
  blogs: [devto, hashnode, medium]
  social: [bluesky, mastodon]
  everything: [blogs, social]  # Profiles can reference other profiles
```

Then use: `crier publish post.md --profile everything`

## Claude Code Integration

Crier is designed to work with Claude Code. Install the skill:

```bash
crier skill install
```

Then just ask naturally:
- "Cross-post my latest article to all platforms"
- "What articles haven't been published to Bluesky?"
- "Publish this post to Mastodon with a good announcement"

Claude automatically follows the workflow: audit, select, publish (with rewrites for short-form platforms).

## Configuration

**Global config** (`~/.config/crier/config.yaml`): API keys, profiles, LLM settings

```yaml
platforms:
  devto:
    api_key: your_key_here
  bluesky:
    api_key: "handle.bsky.social:app-password"
  twitter:
    api_key: manual  # Copy-paste mode

llm:
  api_key: sk-...  # Or set OPENAI_API_KEY env var
```

**Local config** (`.crier/config.yaml`): Project settings

```yaml
content_paths:
  - content
site_base_url: https://yoursite.com
default_profile: everything
```

## CLI Reference

```bash
# Setup
crier init                              # Interactive setup
crier config show                       # View configuration
crier doctor                            # Verify API keys

# Publishing
crier publish FILE --to PLATFORM        # Publish to platform(s)
crier publish FILE --auto-rewrite       # With LLM-generated short-form
crier audit                             # See what needs publishing
crier audit --publish --yes             # Bulk publish all missing
crier audit --publish --auto-rewrite    # Bulk publish with LLM rewrites

# Management
crier list PLATFORM                     # List your articles
crier status [FILE]                     # Show publication status

# Claude Code
crier skill install                     # Install the skill
```

## Links

- **PyPI**: [pypi.org/project/crier](https://pypi.org/project/crier/)
- **GitHub**: [github.com/queelius/crier](https://github.com/queelius/crier)
