Highlight, filter, and reply to posts on Bluesky with a local LLM.
SkyBuddy is a Chrome extension (Manifest V3) that helps you monitor Bluesky for posts matching your keywords, with a configurable glow color, and quickly draft replies using a local LLM of your choice with selectable reply tones.
- Keyword highlighting - Posts matching your keywords glow with a configurable color. Case-insensitive matching.
- Negative keyword filtering - Hide posts matching negative keywords entirely (
bsky-hidden-post). - Configurable glow color - Pick any color for the highlight glow via a color picker in the popup.
- Magic Reply with tones - Injects a button into reply dialogs. Select from multiple reply tones (Generic, Agree, Disagree, Funny, Informative), each with its own system prompt for the LLM.
- Master on/off toggle - Pause all extension activity (scanning, highlighting, magic reply) without losing your settings.
- Full-config export/import - Export and import all settings (keywords with modes, toggles, LLM config, tone prompts, glow color) as a shareable JSON file.
- Right-click to add keywords - Right-click a hashtag on Bluesky to add it to your positive or negative keyword list.
- Privacy-first - All LLM requests go to a server you control (localhost or LAN). No third-party API calls, no telemetry.
- Clone or download this repo.
- Open Chrome and go to
chrome://extensions. - Enable Developer mode (top right).
- Click Load unpacked and select the
bsky-buddyfolder.
SkyBuddy works with OpenAI-compatible /v1/chat/completions APIs (e.g., llama.cpp, LM Studio) and Ollama's /api/chat endpoint. Select your backend from the dropdown in the popup.
Supported servers:
Set the endpoint URL and model name in the LLM Settings collapsible (default endpoint: http://localhost:8080, backend: OpenAI).
Two independent keyword lists in the popup:
| List | Effect |
|---|---|
| Positive | Posts matching these keywords get the glow highlight |
| Negative | Posts matching these keywords are hidden (display: none) |
Keywords are matched case-insensitively using simple substring matching.
The Reply Tone selector in LLM Settings switches between five tone presets, each with its own editable system prompt:
- Generic - Neutral, authentic reply (default)
- Agree - Enthusiastic agreement
- Disagree - Respectful counterpoint
- Funny - Light humor
- Informative - Contextual facts
Each tone's prompt is saved independently. Click Restore Default to reset the current tone to its built-in prompt.
Set the highlight color via the color picker in Data Management & Settings. Default: #0088ff (blue).
- The content script runs on
bsky.app/*and scans the DOM for posts using a rAF-throttled MutationObserver. - New posts are checked against positive and negative keywords. Matching posts get either a configurable CSS glow (
bsky-glow-post) or are hidden (bsky-hidden-post). - Reply dialogs are detected and injected with a "✨ Magic Reply" button. Multiple reply tones are available, each stored as a separate prompt in
chrome.storage.local. - Clicking the button extracts the post text (sanitized), sends it to your local LLM with the selected tone's system prompt, and inserts the generated reply into the composer.
- The popup controls all settings. Changes sync to the content script via
chrome.storage.onChanged. The background service worker handles the right-click context menu. - Full-config export produces a versioned JSON file covering all settings. Import detects the file format and either replaces all settings (v1+) or merges keywords additively (legacy).
bsky-buddy/
manifest.json MV3 manifest
shared.js Constants, defaults, selectors
content.js Orchestrator - init, storage listener, mutation observer, enable/disable
popup.html Popup UI
popup.js Popup logic - settings, keywords, export/import
background.js Service worker - context menus
styles.css Shared styles (glow, magic reply button, toast)
icon-128.png App icon
lib/
keywords.js Keyword state, loadKeywords
posts.js Post scanning, highlighting, negative filter
dialogs.js Dialog scanning, Magic Reply injection, reconnection
llm.js LLM API calls, text extraction, insertTextIntoReply
Set DEBUG = true in shared.js to enable verbose logging from all modules.
- SkyBuddy does not collect data, phone home, or use analytics.
- Post content is sent only to the LLM endpoint you configure (localhost by default).
- No data is stored outside of
chrome.storage.local(keywords, settings, tone prompts). - This extension is not affiliated, associated, authorized, endorsed by, or in any way officially connected with Bluesky Social PBC or its subsidiaries.

