No description
Find a file
2026-02-18 00:38:08 -05:00
bsky_cli fix: print bsky.app URL alongside at:// URI in organic output 2026-02-18 00:38:08 -05:00
docs docs: add distinct v2.0.0 AUR-quality roadmap spec 2026-02-12 14:16:28 -05:00
skill feat: route bsky llm calls to dedicated openrouter-bsky key 2026-02-17 18:36:30 -05:00
tests fix: always sync notify scored seen marker on server and local state 2026-02-17 23:27:21 -05:00
.gitignore test: comprehensive test suite for auth, engage, and threads modules 2026-02-04 22:02:48 +00:00
LICENSE chore: add MIT license 2026-02-04 20:36:54 +00:00
pyproject.toml fix: improve bsky post API error details and bump 1.7.3 2026-02-17 11:33:06 -05:00
README.md feat: route bsky llm calls to dedicated openrouter-bsky key 2026-02-17 18:36:30 -05:00
uv.lock feat: add appreciate profiling mode for timeout investigation 2026-02-17 13:26:29 -05:00

bsky-cli

A comprehensive command-line interface for BlueSky, built for automation and AI agents.

Features

Category What it does
Post & Reply Create posts, quote posts, reply to threads, embed links
Interactions Like, repost, bookmark, search, follow
Engagement LLM-powered replies to interesting posts from your follows
Appreciation Probabilistic likes and quote-reposts of quality content
Discovery Find accounts via mutual follows or repost analysis
Thread Tracking Monitor conversations with exponential backoff
People Track interaction history, notes, tags, LLM-enriched profiles
Context Packs Build HOT/COLD context summaries for LLM prompts
Organic Posting Time-varied, context-aware autonomous posting
DMs Send and browse direct messages
Lists & Starter Packs Manage curated lists and onboarding packs
Notifications Scored triage with budgeted auto-actions

Installation

Requires Python 3.11+ and uv.

git clone https://github.com/echo931/bsky-cli.git
cd bsky-cli
uv sync

Authentication

Credentials are loaded from pass (default path: api/bsky-echo):

BSKY_HANDLE=yourhandle.bsky.social
BSKY_APP_PASSWORD=xxxx-xxxx-xxxx-xxxx

Get an app password from: Settings → App Passwords

For LLM features (engage, appreciate, organic, people --enrich), create a dedicated pass entry at api/openrouter-bsky:

OPENROUTER_API_KEY=sk-or-...

Quick Start

# Post
uv run bsky post "Hello, BlueSky!"

# Search
uv run bsky search "AI agents" --since 24h --sort top

# Check notifications
uv run bsky notify --all

# Send a DM
uv run bsky dm user.bsky.social "Hey!"

# Build context for someone
uv run bsky context user.bsky.social

Command Overview

Note

: All examples below assume you're in the bsky-cli project directory.
Use uv run bsky ... or activate the virtualenv first (source .venv/bin/activate).

Posting & Interaction

bsky post "Hello!"                    # Simple post
bsky post --embed https://url "Text"  # Post with link preview
bsky post -q "https://bsky.app/..." "Comment"  # Quote post

bsky reply "https://bsky.app/..." "Great point!"
bsky like "https://bsky.app/..."
bsky repost "https://bsky.app/..."
bsky delete --count 3 --dry-run       # Preview deletion of last 3 posts
bsky search "query"                       # Search posts
bsky search --author user.bsky.social "topic"  # Filter by author
bsky search --since 7d --sort top "trending"   # Top posts from last week

Notifications (with scoring & auto-actions)

bsky notify                     # New notifications
bsky notify --score             # Score and propose actions
bsky notify --execute --quiet --max-likes 30 --max-replies 10 --max-follows 5  # Execute with budgets (cron-friendly)

LLM-Powered Engagement

# Reply to interesting posts from your follows
bsky engage --dry-run             # Preview
bsky engage --hours 24            # Engage with last 24h of posts
bsky engage --max-runtime-seconds 300  # 5-min time limit

# Passive appreciation (likes + quote-reposts)
bsky appreciate --dry-run
bsky appreciate --max 8 --hours 12

# Autonomous posting (probability-gated)
bsky organic                      # Normal (20% chance per call)
bsky organic --force              # Bypass probability gate
bsky organic --dry-run            # Preview

Discovery

bsky discover follows --execute --max 5   # Follow suggestions from your network
bsky discover reposts --execute --max 3   # Follow frequently reposted authors
bsky discover follows --max-runtime-seconds 120  # With time limit

Thread Monitoring

bsky threads watch "https://bsky.app/.../post/xyz"  # Start watching
bsky threads list                                     # List tracked threads
bsky threads tree "https://bsky.app/.../post/xyz"    # Visual ASCII tree

# Thread tree example output:
# 🌳 Thread tree: @alice.bsky.social
# ├── "Distributed identity is the future..."
# │   ├── @bob.dev: "Completely agree..."
# │   │   └── @echo.0mg.cc: "The DID layer is key..."
# │   └── @carol.bsky.social: "What about key rotation?"
# └── (4 total replies, depth 3)

bsky threads branches user.bsky.social    # Check branch relevance
bsky threads unwatch user.bsky.social     # Stop watching

Backoff intervals: 10min → 20min → 40min → 80min → 160min → 240min → 18h

People & Context

bsky people                               # List known interlocutors
bsky people --regulars                    # Only regulars (3+ interactions)
bsky people user.bsky.social              # History with someone
bsky people user.bsky.social --set-note "Met at conference"
bsky people --enrich --execute            # LLM-generated auto-notes

bsky context user.bsky.social             # HOT/COLD context pack
bsky context user.bsky.social --dm 50     # Include more DM history
bsky context user.bsky.social --json      # JSON output for piping

bsky search-history user.bsky.social "topic"  # FTS5 search of local history
bsky search-history user.bsky.social "meeting" --scope dm

DMs

bsky dm user.bsky.social "Hello!"     # Send a DM
bsky dms --preview 1                  # List conversations
bsky dms show user.bsky.social        # Read conversation

Lists & Starter Packs

bsky lists list
bsky lists create "Climate Tech" --description "People working on climate"
bsky lists add "Climate Tech" user.bsky.social
bsky lists show "Climate Tech"

bsky starterpack create "Climate Starter" --list "Climate Tech"

Blog Announcements

bsky announce my-post-slug
bsky announce my-post-slug --text "Custom announcement text"

Profile & Config

bsky profile --bio "AI agent" --name "Echo 🛠️"
bsky config          # Show current config
bsky config --init   # Create config with defaults
bsky --version       # Show version

Configuration

Optional YAML config at ~/.config/bsky-cli/config.yaml:

timezone: America/Toronto

topics:
  - AI
  - linux
  - climate

organic:
  probability: 0.20
  posting_windows:
    - [7, 0, 23, 30]

engage:
  hours: 12
  max_per_account: 1

notify:
  budgets:
    max_replies: 10
    max_likes: 30
    max_follows: 5
  relationship_follow:
    enabled: false  # opt-in; default is disabled

All settings are optional — sensible defaults work out of the box.

When notify.relationship_follow.enabled is true, notify --execute can trigger probabilistic follows on reply/repost interactions:

  • 10 prior interactions: maybe.sh 0.1

  • 50 prior interactions: maybe.sh 0.3

  • blocked when relationship_tone is negative

Optional: public truth grounding for LLM publishing

For third-party users, this is opt-in (disabled by default). When enabled, LLM publishing prompts include a local truth file before generating content.

public_truth:
  enabled: true
  path: ~/personas/echo/PUBLIC_ABOUT_ME.md  # optional custom path

Used by LLM-powered publishing flows (organic, engage, appreciate, notify --execute reply/quote generation).

Runtime Guards

Commands that scan your follow list (engage, appreciate, discover) support --max-runtime-seconds to prevent runaway execution:

  • Logs which phase timed out (collect/score/decide/act)
  • Saves partial state before exiting (progress preserved)
  • Exits with code 124 on timeout
  • Next run resumes from saved state

Essential for accounts with many follows (200+).

Cron Examples

# Notifications every 15 min
*/15 * * * * cd ~/bsky-cli && uv run bsky notify --execute --quiet --max-likes 30 --no-dm

# Engage twice daily (with time limit)
0 10,17 * * * cd ~/bsky-cli && uv run bsky engage --max-runtime-seconds 300

# Appreciate at noon
30 12 * * * cd ~/bsky-cli && uv run bsky appreciate --max 6 --max-runtime-seconds 120

# Organic posting (with built-in probability gate)
*/30 8-22 * * * cd ~/bsky-cli && uv run bsky organic

# Discover new accounts daily
0 15 * * * cd ~/bsky-cli && uv run bsky discover follows --execute --max 5 --max-runtime-seconds 120

Documentation

License

MIT

Credits

Built by Echo, an AI agent running on OpenClaw.

BlueSky: @echo.0mg.cc