···
+
# Kagi News RSS Aggregator
+
A Python-based RSS aggregator that posts Kagi News stories to Coves communities using rich text formatting.
+
- Fetches RSS feeds from Kagi News daily via CRON
+
- Parses HTML descriptions to extract structured content (highlights, perspectives, sources)
+
- Formats posts using Coves rich text with facets (bold, italic, links)
+
- Hot-links images from Kagi's proxy (no blob upload)
+
- Posts to configured communities via XRPC
+
│ ├── models.py # Data models (KagiStory, Perspective, etc.)
+
│ ├── rss_fetcher.py # RSS feed fetching with retry logic
+
│ ├── html_parser.py # Parse Kagi HTML to structured data
+
│ ├── richtext_formatter.py # Format content with rich text facets (TODO)
+
│ ├── atproto_client.py # ATProto authentication and operations (TODO)
+
│ ├── state_manager.py # Deduplication state tracking (TODO)
+
│ ├── config.py # Configuration loading (TODO)
+
│ └── main.py # Entry point (TODO)
+
│ ├── test_rss_fetcher.py # RSS fetcher tests ✓
+
│ ├── test_html_parser.py # HTML parser tests ✓
+
│ ├── sample_rss_item.xml
+
│ └── generate_did.py # Helper to generate aggregator DID (TODO)
+
├── requirements.txt # Python dependencies
+
├── config.example.yaml # Example configuration
+
├── .env.example # Environment variables template
+
├── crontab # CRON schedule
+
- python3-venv package (`apt install python3.12-venv`)
+
1. Create virtual environment:
+
source venv/bin/activate
+
2. Install dependencies:
+
pip install -r requirements.txt
+
3. Copy configuration templates:
+
cp config.example.yaml config.yaml
+
4. Edit `config.yaml` to map RSS feeds to communities
+
5. Set environment variables in `.env` (aggregator DID and private key)
+
# Activate virtual environment
+
source venv/bin/activate
+
# Run specific test file
+
pytest tests/test_html_parser.py -v
+
pytest --cov=src --cov-report=html
+
### ✅ Phase 1-2 Complete (Oct 24, 2025)
+
- [x] Project structure created
+
- [x] Data models defined (KagiStory, Perspective, Quote, Source)
+
- [x] RSS fetcher with retry logic and tests
+
- [x] HTML parser extracting all sections (summary, highlights, perspectives, sources, quote, image)
+
- [x] Test fixtures from real Kagi News feed
+
### 🚧 Next Steps (Phase 3-4)
+
- [ ] Rich text formatter (convert to Coves format with facets)
+
- [ ] State manager for deduplication
+
- [ ] Configuration loader
+
- [ ] ATProto client for post creation
+
- [ ] Main orchestration script
+
Edit `config.yaml` to define feed-to-community mappings:
+
coves_api_url: "https://api.coves.social"
+
url: "https://news.kagi.com/world.xml"
+
community_handle: "world-news.coves.social"
+
url: "https://news.kagi.com/tech.xml"
+
community_handle: "tech.coves.social"
+
Posts use Coves rich text with UTF-8 byte-positioned facets:
+
"content": "Summary text...\n\nHighlights:\n• Point 1\n...",
+
"index": {"byteStart": 20, "byteEnd": 31},
+
"features": [{"$type": "social.coves.richtext.facet#bold"}]
+
"index": {"byteStart": 50, "byteEnd": 75},
+
"features": [{"$type": "social.coves.richtext.facet#link", "uri": "https://..."}]
+
See parent Coves project license.
+
## Related Documentation
+
- [PRD: Kagi News Aggregator](../../docs/aggregators/PRD_KAGI_NEWS_RSS.md)
+
- [PRD: Aggregator System](../../docs/aggregators/PRD_AGGREGATORS.md)
+
- [Coves Rich Text Lexicon](../../internal/atproto/lexicon/social/coves/richtext/README.md)