Skip to content

Add Chrome extension architecture with offscreen document and AI captioning#1

Merged
justn-hyeok merged 1 commit intomainfrom
claude/review-prd-specs-vb9Du
Mar 25, 2026
Merged

Add Chrome extension architecture with offscreen document and AI captioning#1
justn-hyeok merged 1 commit intomainfrom
claude/review-prd-specs-vb9Du

Conversation

@justn-hyeok
Copy link
Copy Markdown
Contributor

@justn-hyeok justn-hyeok commented Mar 25, 2026

Summary

This PR establishes the foundational architecture for a Chrome extension that performs image captioning using Transformers.js running in an offscreen document. It includes a complete message-passing system, build configuration, and comprehensive test coverage.

Key Changes

  • Message-passing infrastructure: Implemented a type-safe, routable message system with createMessageRouter that handles async message dispatch across extension contexts (background, content, offscreen) with envelope-based error handling via MessageResult<T>

  • Background service worker: Created the hub that manages offscreen document lifecycle (ensureOffscreenDocument) with concurrent creation guards, routes PING messages, and forwards CAPTION_IMAGE requests to the offscreen context

  • Offscreen document: Implemented Transformers.js integration with a singleton captioner pipeline that auto-initializes on first use, caches the model, and handles inference errors gracefully with retry support

  • Content script: Built as an IIFE (no imports/exports) that provides sendToBackground() for type-safe message sending with automatic error envelope wrapping

  • Build configuration:

    • Main Vite config for background/popup/offscreen with deterministic output filenames (no content hashes)
    • Separate content script build config using IIFE format
    • Manifest.json copying via Vite plugin
    • Path alias for @shared imports
  • Manifest.json: MV3-compliant with offscreen permission, WASM CSP directive, service worker module type, and web-accessible resources for WASM/ONNX files

  • Comprehensive test suite:

    • Build output validation (Spec 1.1-1.2)
    • Message routing and envelope handling (Spec 2.2-2.3)
    • Background offscreen lifecycle (Spec 3.1-3.2)
    • Content script messaging (Spec 4.2)
    • Offscreen captioning (Spec 5.1-5.3)
    • Full end-to-end message chain (Spec 6.1)

Notable Implementation Details

  • Concurrent creation guard: ensureOffscreenDocument() uses a promise-based guard to prevent race conditions when multiple messages trigger creation simultaneously
  • Singleton with retry: Captioner pipeline resets on initialization failure, allowing automatic retry on next call
  • Target-based routing: Messages can specify target: 'background' | 'offscreen' | 'content' to filter which contexts process them
  • Type-safe messaging: Discriminated union types for Message with corresponding MessageResponseMap ensure compile-time safety
  • Chrome API mocking: Complete mock setup in tests/setup.ts for testing without a real extension environment

https://claude.ai/code/session_01AvmyUL8FXAFNoy5t5A9XJT

Summary by CodeRabbit

Release Notes

New Features

  • Introduced the Readable browser extension with AI-powered web accessibility enhancements.
  • Added automatic image captioning using local machine learning models for improved image understanding.
  • Added page accessibility scanning to detect and report accessibility violations.
  • Includes a popup interface to manage extension features from your browser toolbar.

Complete MV3 Chrome extension boilerplate with all 6 specs:
- Spec 1: Vite dual-build (ES module + IIFE), valid MV3 manifest
- Spec 2: Type-safe messaging (discriminated union, envelope, router)
- Spec 3: Background service worker (offscreen lifecycle, message hub)
- Spec 4: Content script (sendToBackground with error handling)
- Spec 5: Offscreen document (Transformers.js singleton, captioning)
- Spec 6: Full message chain integration test

50 tests passing across 7 test files.

https://claude.ai/code/session_01AvmyUL8FXAFNoy5t5A9XJT
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 25, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 58bec372-b1d6-4847-8249-177f5e23e105

📥 Commits

Reviewing files that changed from the base of the PR and between 4772773 and b388e0b.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (23)
  • .gitignore
  • package.json
  • public/manifest.json
  • src/background/index.ts
  • src/content/index.ts
  • src/offscreen/index.html
  • src/offscreen/index.ts
  • src/popup/index.html
  • src/popup/index.ts
  • src/shared/messaging.ts
  • src/shared/types.ts
  • tests/integration/message-chain.test.ts
  • tests/setup.ts
  • tests/unit/background.test.ts
  • tests/unit/build.test.ts
  • tests/unit/content.test.ts
  • tests/unit/manifest.test.ts
  • tests/unit/messaging.test.ts
  • tests/unit/offscreen.test.ts
  • tsconfig.json
  • vite.config.content.ts
  • vite.config.ts
  • vitest.config.ts

📝 Walkthrough

Walkthrough

This PR establishes a complete Chrome Extension (Manifest V3) project called "Readable" for AI-powered web accessibility. It includes build/test infrastructure (Vite, Vitest, TypeScript), shared messaging types and routing, background service worker and offscreen document lifecycle management, content script integration, and comprehensive unit and integration tests validating the end-to-end message chain for image captioning via Hugging Face Transformers.js.

Changes

Cohort / File(s) Summary
Project Configuration
package.json, tsconfig.json, vite.config.ts, vite.config.content.ts, vitest.config.ts
Configures ESM/Vite build with multi-entry points, TypeScript strict mode, Vitest testing, path aliases, and @huggingface/transformers dependency.
Extension Manifest & Git
public/manifest.json, .gitignore
Defines Chrome Extension Manifest V3 with service worker, content script, popup, permissions (offscreen/activeTab), CSP, web-accessible resources (WASM/ONNX); ignores node_modules, dist, and local files.
Background Service Worker
src/background/index.ts
Implements offscreen document lifecycle (creation, existence checks) with concurrency guards and message router for PING/CAPTION_IMAGE, forwarding caption requests to offscreen target.
Content Script
src/content/index.ts
Exports sendToBackground() wrapper for messaging; handles undefined responses and errors, always returning a MessageResult envelope.
Offscreen Document
src/offscreen/index.html, src/offscreen/index.ts
Configures Transformers.js for WASM and implements singleton image captioning pipeline with lazy initialization and error recovery; registers CAPTION_IMAGE message handler.
Popup UI
src/popup/index.html, src/popup/index.ts
Minimal popup entry point with basic HTML structure and console log on load.
Shared Types & Messaging
src/shared/types.ts, src/shared/messaging.ts
Defines discriminated Message union (PING, CAPTION_IMAGE, CAPTION_RESULT, SCAN_PAGE, SCAN_RESULT), MessageResult error envelope, unwrapResult() utility, and createMessageRouter() for async request/response handling with optional target filtering.
Unit Tests
tests/unit/background.test.ts, tests/unit/content.test.ts, tests/unit/offscreen.test.ts, tests/unit/messaging.test.ts, tests/unit/manifest.test.ts, tests/unit/build.test.ts
Validates offscreen lifecycle, message routing, error propagation, Transformers pipeline initialization/caching, content messaging, manifest structure, and build output paths/filenames.
Integration Tests & Setup
tests/integration/message-chain.test.ts, tests/setup.ts
Mocks Chrome runtime/offscreen APIs globally; end-to-end tests verify Content → Background → Offscreen message chain for CAPTION_IMAGE with success and error scenarios, plus PING routing.

Sequence Diagram

sequenceDiagram
    participant Content as Content Script
    participant Background as Background/Service Worker
    participant Offscreen as Offscreen Document
    participant Pipeline as Transformers.js Pipeline

    Content->>Background: sendMessage({ type: 'CAPTION_IMAGE', imageUrl: '...' })
    Background->>Background: Receive CAPTION_IMAGE message
    Background->>Offscreen: Ensure offscreen document exists<br/>(create if needed)
    Offscreen-->>Background: Document ready
    Background->>Offscreen: Forward CAPTION_IMAGE message
    Offscreen->>Offscreen: Receive CAPTION_IMAGE message
    Offscreen->>Offscreen: Initialize pipeline (if needed)<br/>pipeline('image-to-text', MODEL_ID)
    Offscreen->>Pipeline: Call captionImage(imageUrl)
    Pipeline-->>Offscreen: Return generated caption
    Offscreen-->>Background: Return { ok: true, data: { caption: '...' } }
    Background-->>Content: Return { ok: true, data: { caption: '...' } }
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

The PR spans 31 files across configuration, extension infrastructure, message routing logic, Transformers.js integration, and comprehensive test suites. While individual modules are moderately complex, the breadth of concerns (Chrome extension patterns, async messaging with error handling, pipeline singleton management, build output validation, and mocked API interactions in tests) requires careful verification of message flow integrity, test coverage completeness, and build configuration correctness.

Poem

🐰 From seed to sprout, the extension does grow,
With messages hopping to and fro,
Transformers whisper through web's DOM maze,
Making the pages accessible in countless ways!
~The Code Rabbit 🌿✨

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/review-prd-specs-vb9Du

Comment @coderabbitai help to get the list of available commands and usage tips.

@justn-hyeok justn-hyeok merged commit 33ff001 into main Mar 25, 2026
0 of 2 checks passed
@justn-hyeok justn-hyeok deleted the claude/review-prd-specs-vb9Du branch March 25, 2026 12:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants