Skip to content

Latest commit

 

History

History
103 lines (81 loc) · 8.27 KB

File metadata and controls

103 lines (81 loc) · 8.27 KB

Project Overview

Last reviewed: 2026-08-13

Purpose

Learning Copilot is a Manifest V3 browser extension that explains text selected on a webpage. It supports Google Gemini, OpenAI, Anthropic, and user-configured local LLM endpoints. Users manage provider credentials, model overrides, and explanation personas on the extension's options page.

Runtime Architecture

Webpage
  -> WXT content script detects a text selection
  -> Shadow DOM React UI displays the action bar/result window
  -> validated runtime port sends an explicit Explain or Cancel request
  -> background service worker reads local settings
  -> selected provider streams an answer with an abort signal tied to the port
  -> runtime port streams chunks back to the webpage UI

Options page
  -> React settings/persona editor
  -> Test Key sends the current provider, credential, and selected model to the background worker
  -> provider model endpoint verifies authentication and model access
  -> WXT storage wrapper
  -> chrome.storage.local

Entrypoints

Path Role
entrypoints/content.tsx Runs on matching webpages, detects the exact text selection, mounts the Shadow DOM UI, and opens a streaming runtime port.
entrypoints/background.ts Owns provider generation and key/model-validation requests in the Manifest V3 service worker and returns structured result/error messages.
entrypoints/options/ Provides onboarding, provider configuration, API-key/model testing, debug mode, and custom-persona management.

Shared Modules

Path Role
utils/storage.ts Defines typed settings, defaults, and the chrome.storage.local-backed WXT storage item.
utils/models.ts Defines the reviewed low-cost default model for each cloud provider so provider requests and UI hints stay synchronized.
utils/llm-providers.ts Builds prompts and implements generation plus credential/model validation for Gemini, OpenAI, Anthropic, and local providers.
utils/runtime-messages.ts Defines typed runtime contracts, request-size limits, and boundary validators for provider tests and streamed explanations.
utils/presets.ts Defines built-in explanation styles.
components/ActionBar.tsx Renders actions shown beside selected text.
components/ResultTooltip.tsx Renders streamed Markdown output in a draggable, resizable panel.
assets/style.css Supplies Tailwind v4 theme tokens and shared content/options-page styling.

Build and Release

  • main is the accepted Chrome Web Store baseline; dev is the integration branch for the next release. Version 0.8.1 remains stable on main while subsequent changes are developed and validated on dev.
  • A release is promoted from dev to main only after its version, documentation, automated checks, manual Chrome smoke test, live-provider checks, Store disclosures, and ZIP artifact have been reviewed together.
  • WXT generates the Manifest V3 extension from wxt.config.ts and the files under entrypoints/.
  • npm run compile performs a TypeScript no-emit check.
  • npm run build writes an unpacked Chrome build to .output/chrome-mv3/.
  • npm run zip creates the Chrome Web Store upload archive.
  • The package version in package.json becomes the extension version; keep the root package metadata in package-lock.json synchronized.

Permission and Data-Flow Audit

Access Status Evidence and purpose
storage Required utils/storage.ts stores provider configuration, API keys, prompt preferences, and personas in local extension storage.
Provider host permissions Required and allowlisted The background worker can reach only the Google Gemini, OpenAI, and Anthropic API origins plus HTTP(S) on localhost and 127.0.0.1.
Content-script matches: <all_urls> Required by the current design entrypoints/content.tsx must detect a selection on the page where the user is reading.
scripting Removed in v0.8.1 No chrome.scripting or browser.scripting call exists. WXT declares the content script statically.
activeTab Removed in v0.8.1 No tab API or action-triggered temporary host access exists. Static content-script access does not use this permission.

When a selection is made, the content script reads only the exact selection so it can display the action bar. It does not read the page URL, title, surrounding content, cookies, form data, or browsing history. When the user clicks Explain, the selected text and configured prompt instructions are sent through the service worker directly to the chosen model provider. When the user clicks Test Key, only the current credential and selected model identifier are sent to that provider to verify access; no website content or prompt is included. API keys remain in local extension storage unless the user is testing unsaved form values and are sent only as authentication to the cloud provider selected by the user.

Current Technical State

  • The repository began as a single v0.8.0 commit. It now has runtime-boundary tests and a least-privilege GitHub Actions workflow, but provider parsers still need fixture-based coverage.
  • Provider output is streamed over a long-lived extension runtime port. Closing the UI, stopping generation, changing the selection, or replacing a request aborts the active fetch and stale streams are ignored.
  • The Settings page can verify the entered cloud key against the effective default or custom model and displays a success state or the provider's error reason. Local mode performs a minimal one-token model request and labels the action Test Connection.
  • Gemini, OpenAI, Anthropic, and local-provider streaming parsers are implemented. The reviewed efficiency-first cloud defaults are gemini-3.5-flash-lite, gpt-5.6-luna with reasoning disabled, and claude-haiku-4-5.
  • Provider host permissions are allowlisted. The local-provider URL is validated at request time and permits only HTTP(S) on localhost or 127.0.0.1 without embedded credentials.
  • The toolbar action opens the options page without requesting an additional permission.
  • Production-package verification rejects unexpected API/host permissions, wrong icon dimensions, source maps, starter assets, and common remote/evaluated-code patterns.
  • Explanation requests accept at most 20,000 selected characters and a 200-character style identifier; malformed runtime messages fail closed.
  • Gemini credentials are sent in the x-goog-api-key header rather than embedded in the request URL.
  • AI Markdown renders without raw HTML support; generated links open in a separate context with opener access disabled.
  • The in-page UI supports Compact, Balanced, and Large scale preferences. The result panel can shrink to 220 pixels and its body typography interpolates with the current width while retaining a 12-pixel floor.
  • Chrome's built-in PDF viewer does not expose its selection as a regular webpage DOM, so the content-script workflow supports arXiv HTML pages but not selections made inside Chrome's PDF viewer.

Verification Baseline

Version 0.8.1 passed Chrome Web Store review and is the stable baseline. Its source and production-package audit included:

  • npm run compile passed.
  • npm test passed eight runtime-boundary and responsive-sizing tests.
  • npm audit reported zero known dependency vulnerabilities after upgrading WXT and the build toolchain.
  • npm run build produced .output/chrome-mv3/.
  • The generated manifest contains only storage in permissions; neither scripting nor activeTab is present.
  • npm run zip produced .output/learning-copilot-0.8.1-chrome.zip.
  • npm run verify:store enforces the reviewed production-manifest and package constraints.
  • The options page was rendered at the default desktop viewport and at 390×844; its guide and provider setup remained usable without horizontal overflow.
  • The release completed its required package audit, manual Chrome smoke test, live-provider checks, and Chrome Web Store review.

Known Security and Release Constraints

  • API keys in chrome.storage.local are protected by the browser profile boundary, not an encrypted credential vault.
  • Selected text can contain prompt-injection instructions. The extension isolates code execution and does not enable raw HTML, but it cannot guarantee the factual integrity of provider output.