Clone this repository
For self-hosted knots, clone URLs may differ based on your setup.
Download tar.gz
The env var was in .env.prod but not passed through to the container,
causing the trusted aggregator check to always fail.
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Check for COVES_API_KEY instead of AGGREGATOR_HANDLE/PASSWORD
- Display API key prefix on startup for debugging
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Switch from OAuth to simpler API key auth
- Add retry logic with exponential backoff
- Update examples and test coverage
- Remove httpx dependency (use requests)
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace single KAGI_AGGREGATOR_DID with comma-separated
TRUSTED_AGGREGATOR_DIDS env var. Allows multiple aggregators
to bypass community authorization checks.
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Register API key management routes in main.go (was missing)
- Add metrics handler for monitoring API key service health
- Improve error handling and validation in handlers
- Refactor apikey_service for better token refresh flow
- Update aggregator repo with credential persistence
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Deleted 41 spam bot accounts that were created between Dec 26-28.
All accounts used rotating residential proxies and followed the same
pattern: Brazilian-style names, no profiles, only follows/likes/reposts.
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add API key-based authentication allowing aggregators to post to communities
via bot-like behavior. This complements OAuth for programmatic access.
Key components:
- API key generation, validation, and revocation endpoints
- Encrypted OAuth token storage for session persistence
- DualAuthMiddleware supporting API keys alongside OAuth
- Database migrations for key storage with encryption at rest
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Extract external link embeds (title, description, thumb) from quoted posts
- Handle blocked quoted posts (#viewBlocked) with "This post is from a blocked account"
- Handle deleted quoted posts (#viewNotFound) with "This post has been deleted"
- Handle detached quoted posts (#viewDetached) with "This post is unavailable"
- Add Detached boolean field for consistency with Blocked/NotFound pattern
- Add logging for JSON unmarshal failures and timestamp parsing errors
- Improve doc comments for embed extraction functions
Also adds beads issue Coves-327 for Phase 3: image/video extraction
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The Indigo xrpc client always sends Auth.AccessJwt as the Authorization
header, but com.atproto.server.refreshSession requires the refresh token
in that header. This was causing "InvalidToken: Invalid token type" errors
when community tokens needed refreshing.
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When embedding Bluesky posts that contain external links (link cards),
the external link metadata (URI, title, description, thumbnail) is now
extracted and stored in the BlueskyPostResult.
Changes:
- Add ExternalEmbed type to capture link card data
- Add Embed field to BlueskyPostResult
- Parse app.bsky.embed.external#view from Bluesky API responses
- Add unit tests for external embed extraction
- Fix productionPLCIdentityResolver to require db parameter
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>