Social Annotations in the Atmosphere
15
fork

Configure Feed

Select the types of activity you want to include in your feed.

HTML 52.7%
TypeScript 33.2%
Go 7.8%
JavaScript 1.9%
CSS 1.9%
Nix 0.5%
Shell 0.3%
Other 1.5%
67 1 0

Clone this repository

https://tangled.org/sealight.xyz/seams.so https://tangled.org/did:plc:exp76a7fe76w25gstz4lww75/seams.so
git@tangled.org:sealight.xyz/seams.so git@tangled.org:did:plc:exp76a7fe76w25gstz4lww75/seams.so

For self-hosted knots, clone URLs may differ based on your setup.

Download tar.gz
README.md

seams.so#

Web annotation system built on AT Protocol - annotate any webpage and share annotations via Bluesky's decentralized infrastructure.

Project Structure#

  • Browser Extension (TypeScript/WXT) - Chrome/Firefox extension for creating and viewing annotations
  • Backend Server (Go) - SQLite-backed indexing service for querying annotations by URL
  • Landing Page (landing/) - Public feed of recent annotations
  • Proxy (proxy/) - Web-based proxy using wabac.js for annotation without extension

Quick Start#

Development Environment#

# Enter Nix development shell (includes Node.js, pnpm, Go, etc.)
nix develop

Extension Development#

# Install dependencies
pnpm install

# Start development server with hot reload
pnpm dev

# Build for production
pnpm build

# Package for Chrome Web Store / Firefox Add-ons
pnpm zip

Load the extension:

  • Chrome: Open chrome://extensions, enable "Developer mode", click "Load unpacked", select .output/chrome-mv3
  • Firefox: Open about:debugging#/runtime/this-firefox, click "Load Temporary Add-on", select .output/firefox-mv3/manifest.json

Backend Server#

cd server

# Install Go dependencies
go mod download

# Run server (defaults to port 8080)
go run cmd/server/main.go

# Run tests
go test ./internal/service -v

# Build binary
go build -o seams-server ./cmd/server

See server/README.md for detailed backend documentation.

Architecture#

Browser Extension (Storage-First)#

  • Background worker: Fetches annotations from backend on tab changes, syncs user's own annotations from PDS
  • Content script: Reads from storage.local, renders highlights, tracks text selection
  • Sidepanel: UI for creating/viewing annotations, optimistically updates cache

Backend (Go + SQLite)#

  • Indexes annotation records from users' Personal Data Servers (PDSs)
  • Resolves DIDs via plc.directory to support any PDS (not just bsky.social)
  • Provides query endpoint: GET /api/annotations?url={url}
  • Rate-limited: 100 req/min (GET), 10 req/min (POST)

Data Flow#

User creates annotation → PDS (via OAuth) → Backend indexes → storage.local cache → Content script renders highlights

Configuration#

Environment Variables#

Extension (.env):

BACKEND_URL=http://localhost:8080  # Backend API URL

Backend:

PORT=8080                        # Server port (default: 8080)
DB_PATH=./db/annotations.db      # SQLite database path

Documentation#

Tech Stack#

Extension:

  • TypeScript + WXT (Web Extension Framework)
  • @atcute/oauth-browser-client - AT Protocol OAuth
  • Vite for bundling

Backend:

  • Go 1.22+
  • SQLite (with WAL mode for concurrency)
  • chi (HTTP router)

Proxy:

  • wabac.js (client-side service worker)
  • CORS proxy server (Node.js/Hono)
  • Injects browser-based sidebar and content script
  • Caddy for static files and reverse proxy

Infrastructure:

  • Nix for reproducible development environments
  • pnpm for package management

License#

MIT