typefully 0.1.0

A full-featured CLI client for the Typefully API v2
Documentation

โœจ Features

  • ๐Ÿ“ Create drafts with rich content, tags, and media attachments
  • ๐Ÿงต Thread support with simple --- separators
  • ๐Ÿ“… Schedule posts for specific times or the next free slot
  • ๐ŸŒ Multi-platform publishing (X, LinkedIn, Threads, Bluesky, Mastodon)
  • ๐Ÿ–ผ๏ธ Media uploads with automatic S3 presigned URL handling
  • ๐Ÿท๏ธ Tag management for organizing your content
  • ๐Ÿ“Š Flexible output with human-friendly tables or JSON
  • ๐Ÿ” Secure API key handling (never logged or displayed)
  • โšก Fast async runtime powered by tokio

๐Ÿ“ฆ Installation

Homebrew

brew install ricardodantas/tap/typefully

From crates.io

cargo install typefully

From source

git clone https://github.com/ricardodantas/typefully-cli.git
cd typefully-cli
cargo install --path .

๐Ÿš€ Quick Start

# 1. Set up your API key and default social set
typefully config init

# 2. Verify authentication
typefully auth

# 3. Create your first draft
typefully draft create --content "Hello from the terminal! ๐Ÿš€"

# 4. Publish it immediately
typefully draft create --content "Going live now!" --publish-at now

โš™๏ธ Configuration

Interactive Setup

The easiest way to get started:

typefully config init

This prompts for your API key and lets you pick a default social set from your account.

Manual Setup

Create ~/.config/typefully/config.toml:

api_key = "your-api-key-here"
default_social_set_id = "your-social-set-id"

API Key Precedence

The CLI looks for your API key in this order:

  1. --api-key command-line flag
  2. TYPEFULLY_API_KEY environment variable
  3. ~/.config/typefully/config.toml file

๐Ÿ“– Command Reference

Authentication

Verify your API key and display account information:

typefully auth
typefully auth --json

Social Sets

List all social sets with their connected platforms:

typefully sets
typefully sets --json

Drafts

Create a Draft

# Simple draft (saved as draft, not published)
typefully draft create --content "Hello world!"

# Pipe content from stdin
echo "Hello from a pipe" | typefully draft create

# Publish immediately
typefully draft create --content "Live now!" --publish-at now

# Schedule for the next free slot
typefully draft create --content "Queued up" --publish-at next-free-slot

# Schedule for a specific time (ISO-8601)
typefully draft create --content "Timed post" --publish-at "2025-06-15T10:00:00Z"

# Add tags
typefully draft create --content "Product update" --tag launch --tag product

# Attach uploaded media
typefully draft create --content "Check this out!" --media media_abc123

# Target specific platforms
typefully draft create --content "Hello LinkedIn!" --platform linkedin

# Post to multiple platforms
typefully draft create --content "Everywhere at once" --platform x --platform linkedin --platform threads

# Use a specific social set
typefully draft create --set set_abc123 --content "Hello!"

Create a Thread

Split your content into multiple posts using --- on its own line:

typefully draft create --content "1/ Here's a thread about something interesting.
---
2/ The second post continues the thought.
---
3/ And the conclusion wraps it all up."

You can also pipe a thread from a file:

cat my-thread.txt | typefully draft create

Where my-thread.txt contains:

First post of the thread.
---
Second post with more detail.
---
Final post with a call to action!

List Drafts

# List recent drafts (default: 20)
typefully draft list

# Filter by status
typefully draft list --status scheduled
typefully draft list --status published
typefully draft list --status draft

# Filter by tag
typefully draft list --tag marketing

# Custom sorting
typefully draft list --sort scheduled_date
typefully draft list --sort updated_at

# Pagination
typefully draft list --limit 10 --offset 20

# Combine filters
typefully draft list --status scheduled --tag launch --sort scheduled_date --limit 5

Get a Draft

typefully draft get abc123
typefully draft get abc123 --json

Edit a Draft

# Update content
typefully draft edit abc123 --content "Updated content here"

# Reschedule
typefully draft edit abc123 --publish-at "2025-07-01T09:00:00Z"

# Update tags
typefully draft edit abc123 --tag new-tag --tag another-tag

# Toggle sharing
typefully draft edit abc123 --share true

Delete a Draft

# With confirmation prompt
typefully draft delete abc123

# Skip confirmation
typefully draft delete abc123 --force

Publish Immediately

A shortcut to publish a draft right now:

typefully draft publish abc123

Schedule a Draft

# Schedule for the next free slot
typefully draft schedule abc123 next-free-slot

# Schedule for a specific time
typefully draft schedule abc123 "2025-06-20T14:00:00Z"

Media

Upload Workflow

Media uploads use a three-step process (handled automatically by the CLI):

  1. Request a presigned upload URL from Typefully
  2. Upload the file to S3
  3. Poll until processing is complete
# Upload an image
typefully media upload photo.jpg

# Upload and get the media ID as JSON (useful for scripting)
typefully media upload banner.png --json

# Then attach it to a draft
typefully draft create --content "New banner!" --media <media_id_from_above>

Supported formats: PNG, JPEG, GIF, WebP, MP4.

Tags

List Tags

typefully tags list
typefully tags list --json

Create a Tag

typefully tags create "product-launch"
typefully tags create "weekly-update" --set set_abc123

Self-Update

Update typefully to the latest version. Automatically detects whether you installed via Homebrew or cargo:

typefully update

๐ŸŒ Global Flags

These flags work with every command:

Flag Description
--json Output raw JSON to stdout
--no-color Disable colored output (also respects NO_COLOR env)
-q, --quiet Minimal output (only errors)
-v, --verbose Debug logging to stderr
--api-key <key> Override the API key for this invocation
-h, --help Show help text
--version Show version

๐Ÿ”ข Exit Codes

Code Meaning
0 Success
1 API error or runtime error
2 Invalid usage (bad flags, missing arguments)

๐Ÿ”ง Scripting Examples

# List scheduled draft IDs as plain text
typefully draft list --status scheduled --json | jq -r '.[].id'

# Publish all drafts tagged "ready"
for id in $(typefully draft list --tag ready --json | jq -r '.[].id'); do
  typefully draft publish "$id"
done

# Upload media and create a draft in one pipeline
MEDIA_ID=$(typefully media upload photo.jpg --json | jq -r '.media_id')
typefully draft create --content "New photo!" --media "$MEDIA_ID"

๐Ÿค Contributing

Contributions are welcome! Please read the following before submitting a PR:

  1. Read AGENTS.md for project conventions and architecture
  2. Rust 2024 edition with MSRV 1.91
  3. All checks must pass:
    cargo check
    cargo clippy -- -D warnings
    cargo build --release
    
  4. Follow existing patterns: trait-based API client, thiserror for errors, tracing for logging
  5. Add doc comments on all public items
  6. No em dashes in any text content

๐Ÿ“„ License

This project is licensed under the GNU General Public License v3.0.