···11+Copyright 2025 me@haileyok.com
22+33+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
44+55+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
66+77+THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+182
README.md
···11+# dontshowmethis
22+33+An AI-powered Bluesky content moderation system that automatically labels replies to monitored accounts using LLM-based content analysis.
44+55+## Overview
66+77+This project monitors Bluesky posts in real-time via Jetstream and uses a local LLM (via LM Studio) to classify replies to watched accounts. It automatically applies labels such as "bad-faith", "off-topic", and "funny" to help users filter and moderate content.
88+99+The system consists of two components:
1010+1. **Go Consumer** - Monitors the Jetstream firehose and analyzes replies using an LLM
1111+2. **Skyware Labeler** - TypeScript server that manages and emits content labels
1212+1313+## Architecture
1414+1515+```
1616+Jetstream → Go Consumer → LM Studio (LLM) → Labeler Service → Bluesky
1717+```
1818+1919+1. The Go consumer subscribes to Jetstream and monitors replies to specified accounts
2020+2. When a reply is detected, it fetches the parent post and sends both to LM Studio
2121+3. The LLM classifies the reply based on the system prompt
2222+4. Labels are emitted via the Skyware labeler service
2323+5. Labels are propagated to Bluesky's labeling system
2424+2525+## Prerequisites
2626+2727+- [LM Studio](https://lmstudio.ai/) with a compatible model loaded
2828+- A Bluesky account for the labeler
2929+3030+## Installation
3131+3232+### Clone the repository
3333+3434+```bash
3535+git clone https://github.com/haileyok/dontshowmethis.git
3636+cd dontshowmethis
3737+```
3838+3939+### Install Go dependencies
4040+4141+```bash
4242+go mod download
4343+```
4444+4545+### Install labeler dependencies
4646+4747+```bash
4848+cd labeler
4949+yarn install
5050+cd ..
5151+```
5252+5353+## Configuration
5454+5555+Copy the example environment file and configure it:
5656+5757+```bash
5858+cp .env.example .env
5959+```
6060+6161+### Environment Variables
6262+6363+**For the Go Consumer:**
6464+6565+- `PDS_URL` - Your Bluesky PDS URL (e.g., `https://bsky.social`)
6666+- `ACCOUNT_HANDLE` - Your Bluesky account handle
6767+- `ACCOUNT_PASSWORD` - Your Bluesky account password
6868+- `WATCHED_OPS` - Comma-separated list of DIDs to monitor for replies
6969+- `JETSTREAM_URL` - Jetstream WebSocket URL (default: `wss://jetstream2.us-west.bsky.network/subscribe`)
7070+- `LABELER_URL` - URL of your labeler service (e.g., `http://localhost:3000`)
7171+- `LABELER_KEY` - Authentication key for the labeler API
7272+- `LMSTUDIO_HOST` - LM Studio API host (e.g., `http://localhost:1234`)
7373+7474+**For the Skyware Labeler:**
7575+7676+- `SKYWARE_DID` - Your labeler's DID
7777+- `SKYWARE_SIG_KEY` - Your labeler's signing key
7878+- `EMIT_LABEL_KEY` - Secret key for the emit label API (must match `LABELER_KEY` above)
7979+8080+## Running the Services
8181+8282+### 1. Start LM Studio
8383+8484+1. Open LM Studio
8585+2. Load a compatible model (recommended: `google/gemma-3-27b` or similar)
8686+3. Start the local server (usually runs on `http://localhost:1234`)
8787+8888+### 2. Start the Labeler Service
8989+9090+```bash
9191+cd labeler
9292+npm start
9393+```
9494+9595+The labeler will start two servers:
9696+- Port 14831: Skyware labeler server
9797+- Port 3000: Label emission API
9898+9999+### 3. Start the Go Consumer
100100+101101+```bash
102102+go run .
103103+```
104104+105105+Or build and run:
106106+107107+```bash
108108+go build -o dontshowmethis
109109+./dontshowmethis
110110+```
111111+112112+## Usage
113113+114114+Once running, the system will:
115115+116116+1. Connect to Jetstream and monitor the firehose
117117+2. Watch for replies to accounts specified in `WATCHED_OPS`
118118+3. Automatically analyze and label qualifying replies
119119+4. Log all actions to stdout
120120+121121+### Finding Account DIDs
122122+123123+To monitor specific accounts, you need their DIDs. You can find a DID by:
124124+125125+```bash
126126+curl "https://bsky.social/xrpc/com.atproto.identity.resolveHandle?handle=username.bsky.social"
127127+```
128128+129129+Add the returned DID to your `WATCHED_OPS` environment variable.
130130+131131+## How Content Classification Works
132132+133133+See `lmstudio.go:147` for the system prompt.
134134+135135+## Development
136136+137137+### Project Structure
138138+139139+```
140140+.
141141+├── main.go # CLI setup and consumer initialization
142142+├── handle_post.go # Post handling and labeling logic
143143+├── lmstudio.go # LLM client and content classification
144144+├── sets/
145145+│ └── domains.go # Political domain list (currently unused)
146146+├── labeler/
147147+│ ├── index.ts # Skyware labeler service
148148+│ └── package.json # Labeler dependencies
149149+├── .env.example # Example environment configuration
150150+└── README.md # This file
151151+```
152152+153153+### Adding New Labels
154154+155155+1. Add the label constant in `main.go`:
156156+ ```go
157157+ const LabelNewLabel = "new-label"
158158+ ```
159159+160160+2. Add it to the labeler's allowed labels in `labeler/index.ts`:
161161+ ```typescript
162162+ const LABELS: Record<string, boolean> = {
163163+ 'bad-faith': true,
164164+ 'off-topic': true,
165165+ 'funny': true,
166166+ 'new-label': true, // Add here
167167+ }
168168+ ```
169169+170170+3. Update the LLM schema in `lmstudio.go` to include the new classification
171171+172172+4. Update the handling logic in `handle_post.go` to emit the new label
173173+174174+## License
175175+176176+MIT
177177+178178+## Acknowledgments
179179+180180+- [Jetstream](https://github.com/bluesky-social/jetstream) - Real-time firehose for Bluesky
181181+- [Skyware](https://skyware.js.org/) - Labeler framework
182182+- [LM Studio](https://lmstudio.ai/) - Local LLM inference