Expert assistant for developing the Pufferfish video fact-checking browser extension with compliance-first architecture, YouTube integration, and microservices backend.
This skill has safety concerns that you should review before use. Some patterns were detected that may pose a risk.Safety score: 60/100.
KillerSkills scans all public content for safety. Use caution before installing or executing flagged content.
Expert assistant for the Pufferfish video fact-checking platform. Specializes in Chrome extension development, YouTube integration, compliance enforcement, and microservices architecture.
Pufferfish is a browser extension for real-time video fact-checking with platform-specific compliance, transcript/frame analysis, and AI-powered verification.
**Architecture:** Turbo monorepo with WXT-based Chrome extension, FastAPI gateway, Elasticsearch vector search, LangGraph orchestration, and specialized microservices (STT, OCR, LLM).
**Repository:** `/Users/seanm-github/Documents/ClaudeCodeProjects/Pufferfish`
When working on Pufferfish:
- Extension toolbar button click
- Context menu ("Fact-check video on this page")
- Keyboard shortcut (Cmd+Shift+F / Ctrl+Shift+F)
- YouTube player button (custom overlay)
**Key Files:**
**Video Detection:**
Use MutationObserver to detect dynamically loaded videos (YouTube SPA behavior).
**Loading Extension:**
```bash
```
Enforce platform-specific policies at the content script level:
| Platform | Allowed UI | Content Extraction | Limits |
|----------|------------|-------------------|--------|
| **YouTube** | Context menu only (no overlays) | Transcript via API | No frame extraction |
| **CNN/Fox News** | Adjacent fact-check panels | Frames + transcripts | 0.5 FPS max |
| **Vimeo** | Adjacent fact-check panels | Frames + transcripts | 0.5 FPS max |
| **All** | Fair use segments | 30-second max clips | Automatic attribution |
**Implementation:**
**Services:**
**Local Development:**
```bash
make docker-up
make setup-elastic
docker-compose logs -f gateway
```
**Index:** `facts`
**Schema:**
**Search Strategy:** Hybrid (RRF) combining BM25 and kNN dense vectors.
```bash
npm install --legacy-peer-deps
turbo build
cd apps/extension
turbo dev
turbo lint
turbo format
turbo test
```
**npm Dependency Resolution (macOS):**
**YouTube Context Menu:**
**Video Detection:**
```
apps/
extension/ # Chrome extension (WXT framework)
manifest.json # Manifest v3 (vanilla JS)
background.js # Service worker
content.js # Video detector
youtube-overlay.js # YouTube player button
src/
entrypoints/ # WXT TypeScript (future)
content/ # Content scripts
policy.ts # Platform compliance engine
components/ # React UI (future)
services/
gateway/ # FastAPI WebSocket server
stt/ # Whisper speech-to-text
ocr/ # PaddleOCR text extraction
llm/ # Ollama/Gemma2 claim extraction
orchestrator/ # LangGraph workflow
packages/
shared/ # Shared TypeScript types
ui/ # Shared React components
docker-compose.yml # Local services stack
Makefile # Development commands
turbo.json # Build pipeline config
```
**For Extension Changes:**
1. Edit files in `apps/extension/`
2. Reload extension in `chrome://extensions/`
3. Test on YouTube or CNN
4. Check console for errors
5. Verify compliance (no overlays on YouTube, 0.5 FPS on CNN)
**For Backend Changes:**
1. Edit service in `services/*/`
2. Restart container: `docker-compose restart <service>`
3. Check logs: `docker-compose logs -f <service>`
4. Test WebSocket connection from extension
**For Shared Code:**
1. Edit in `packages/shared/` or `packages/ui/`
2. Run `turbo build` to rebuild dependents
3. Reload extension if affected
**Manual Testing:**
**Automated Testing (Future):**
**Sprint 1 (Current):**
1. Resolve npm dependencies for WXT TypeScript migration
2. Implement policy engine (`apps/extension/src/content/policy.ts`)
3. Add extension icons (icon-16.png, icon-48.png, icon-128.png)
4. Load `youtube-overlay.js` in manifest
5. Connect extension to backend WebSocket
**Sprint 2:**
1. Deploy Elasticsearch cluster
2. Implement FastAPI gateway with WebSocket
3. Create STT service with Whisper
4. Build OCR service with PaddleOCR
5. Implement LangGraph orchestration workflow
**Sprint 3:**
1. Build React UI for fact-check results
2. Add confidence scoring visualization
3. Implement source attribution overlay
4. Add user settings (enable/disable platforms, sensitivity)
5. Create onboarding flow
**Documentation:**
**External:**
```bash
make docker-up # Start all services
make docker-down # Stop all services
make setup-elastic # Initialize Elasticsearch indices
make logs SERVICE=gateway # View service logs
npm install --legacy-peer-deps # Install dependencies
turbo build # Build all packages
turbo dev # Watch mode for all packages
turbo lint # Lint all packages
turbo format # Format all packages
turbo test # Run all tests
rm -rf node_modules apps/*/node_modules packages/*/node_modules
npm cache clean --force
```
When adding support for a new video platform (e.g., TikTok):
1. **Update policy engine** (`apps/extension/src/content/policy.ts`):
```typescript
export const PLATFORM_POLICIES = {
'tiktok.com': {
allowedUI: ['adjacent-panel'],
contentExtraction: {
frames: true,
fps: 0.5,
transcripts: true
},
fairUse: {
maxClipLength: 15, // TikTok videos are short
requireAttribution: true
}
}
}
```
2. **Create platform detector** (`apps/extension/src/content/detectors/tiktok.ts`):
```typescript
export class TikTokDetector implements VideoDetector {
detect(): VideoElement | null {
return document.querySelector('video[src*="tiktok"]')
}
}
```
3. **Register in content script** (`apps/extension/content.js`):
```javascript
const detectors = [
new YouTubeDetector(),
new CNNDetector(),
new TikTokDetector()
]
```
4. **Test compliance:**
Connect extension to backend gateway:
1. **In background service worker** (`apps/extension/background.js`):
```javascript
let ws = null
function connectWebSocket() {
ws = new WebSocket('ws://localhost:8000/ws')
ws.onopen = () => console.log('Connected to gateway')
ws.onmessage = (event) => {
const data = JSON.parse(event.data)
// Handle fact-check results
chrome.tabs.sendMessage(data.tabId, {
type: 'FACTCHECK_RESULT',
payload: data
})
}
ws.onerror = (error) => console.error('WebSocket error:', error)
ws.onclose = () => setTimeout(connectWebSocket, 5000) // Reconnect
}
connectWebSocket()
```
2. **Send video data** (from content script):
```javascript
chrome.runtime.sendMessage({
type: 'FACTCHECK_REQUEST',
video: {
url: window.location.href,
platform: 'youtube.com',
transcript: extractedTranscript
}
})
```
3. **In background worker** (forward to WebSocket):
```javascript
chrome.runtime.onMessage.addListener((message, sender) => {
if (message.type === 'FACTCHECK_REQUEST') {
ws.send(JSON.stringify({
tabId: sender.tab.id,
video: message.video
}))
}
})
```
Extract YouTube captions without violating TOS:
1. **Use official API** (in content script):
```javascript
async function getYouTubeTranscript(videoId) {
const response = await fetch(
`https://www.youtube.com/api/timedtext?v=${videoId}&lang=en`
)
const xml = await response.text()
const parser = new DOMParser()
const doc = parser.parseFromString(xml, 'text/xml')
return Array.from(doc.querySelectorAll('text')).map(node => ({
start: parseFloat(node.getAttribute('start')),
duration: parseFloat(node.getAttribute('dur')),
text: node.textContent
}))
}
```
2. **Check policy before extraction**:
```javascript
import { canExtractTranscript } from './policy'
if (canExtractTranscript('youtube.com')) {
const transcript = await getYouTubeTranscript(videoId)
sendToBackend(transcript)
} else {
console.warn('Transcript extraction not allowed on this platform')
}
```
Leave a review
No reviews yet. Be the first to review this skill!
# Download SKILL.md from killerskills.ai/api/skills/pufferfish-extension-development-assistant/raw