Build and Development Environment Setup#
Package Manager#
This repository uses pnpm version 10.32.1 as specified in the root package.json:
"packageManager": "pnpm@10.32.1"
Install or update pnpm globally to match:
pnpm add -g pnpm@10.32.1
Node.js Version#
The required Node.js version is specified in the devEngines field:
"devEngines": {
"runtime": {
"name": "node",
"version": ">=22.0.0",
"onFail": "download"
}
}
Use a Node.js version manager to ensure you are running Node.js >=22.0.0. If the version is not met, the setup will attempt to download the correct version automatically.
Monorepo Structure#
The repository is organized as a monorepo with pnpm workspaces. All packages are located under apps/* and packages/*. Internal dependencies use the workspace:* protocol for cross-package references, ensuring modularity and streamlined builds.
Local Development Workflow#
Opt-in Local Package Development#
Developers can easily switch between using published @read-frog/* packages and local monorepo source code for faster iteration.
-
Environment Variable:
- Set
WXT_USE_LOCAL_PACKAGES=truein a.env.localfile to enable local package resolution. - An example file
.env.local.exampleis provided. Copy it to.env.localand adjust as needed.
- Set
-
TypeScript Configuration:
- The root
tsconfig.jsonnow extendstsconfig.local.jsonif present. - An example
tsconfig.local.example.jsonis provided. Copy it totsconfig.local.jsonand uncomment the relevantpathsmappings to point to your local monorepo sources. - This enables TypeScript to resolve
@read-frog/*imports to local source directories during development.
- The root
-
Vite/WXT Configuration:
- The
wxt.config.tsfile conditionally aliases@read-frog/*packages to local paths whenWXT_USE_LOCAL_PACKAGESis set. - React and ReactDOM are always resolved as singletons from the root
node_modulesto avoid duplication.
- The
-
.gitignore:
.gitignoreis updated to ignoretsconfig.local.jsonbut allow example files to be tracked.
Quick Start for Local Development#
- Copy
.env.local.exampleto.env.localand setWXT_USE_LOCAL_PACKAGES=true. - Copy
tsconfig.local.example.jsontotsconfig.local.jsonand uncomment thepathsmappings as needed. - Run development scripts as usual (e.g.,
pnpm devorpnpm dev:localif available).
Build System#
Turborepo#
Nx orchestrates builds, development, linting, testing, and type-checking across the monorepo. The root package.json defines scripts that delegate to Nx:
"scripts": {
"build": "DOTENV_CONFIG_QUIET=false wxt build",
"build:edge": "DOTENV_CONFIG_QUIET=false wxt build -b edge",
"build:firefox": "DOTENV_CONFIG_QUIET=false wxt build -b firefox --mv3",
"dev:local": "WXT_USE_LOCAL_PACKAGES=true wxt",
"dev": "DOTENV_CONFIG_QUIET=false wxt",
"dev:edge": "DOTENV_CONFIG_QUIET=false wxt -b edge",
"dev:firefox": "DOTENV_CONFIG_QUIET=false wxt -b firefox --mv3",
"lint": "nx exec -- eslint",
"lint:fix": "eslint --fix",
"test": "nx exec -- vitest run",
"test:cov": "nx exec -- vitest run --coverage",
"test:watch": "vitest",
"type-check": "nx exec -- tsc --noEmit",
"scrape:ai-sdk-models": "npx tsx scripts/scrape-ai-sdk-provider-models.ts --out scripts/output/ai-sdk-provider-models.json",
"zip": "DOTENV_CONFIG_QUIET=false WXT_ZIP_MODE=true wxt zip",
"zip:edge": "DOTENV_CONFIG_QUIET=false WXT_ZIP_MODE=true wxt zip -b edge",
"zip:firefox": "DOTENV_CONFIG_QUIET=false WXT_ZIP_MODE=true wxt zip -b firefox --mv3",
"zip:all": "DOTENV_CONFIG_QUIET=false pnpm zip && pnpm zip:edge && pnpm zip:firefox",
...
}
Nx enables build caching and dependency-aware task execution. The nx.json file configures caching for build, test, lint, and type-check tasks.
DOTENV_CONFIG_QUIET flag: All build, dev, and zip commands include the DOTENV_CONFIG_QUIET=false environment variable to provide better visibility into dotenv configuration loading during execution.
Firefox Manifest V3: All Firefox-related commands (dev:firefox, build:firefox, zip:firefox) now include the --mv3 flag to target Manifest V3 for Firefox builds.
AI Model Scraper#
The repository includes a utility script to scrape and update AI model information from Vercel AI SDK documentation:
pnpm scrape:ai-sdk-models
This script scrapes the latest AI SDK provider models from Vercel AI SDK documentation and outputs structured JSON to scripts/output/ai-sdk-provider-models.json. The scraper automatically discovers and parses model information from each provider's documentation page, including model names and their capabilities (image input, audio input, object generation, tool usage).
Purpose: Maintain up-to-date model lists in src/utils/constants/models.ts by collecting the latest available models from each AI provider's documentation.
Output: The generated JSON file contains metadata about scraped providers, model names, and their capabilities, which can be used to sync the codebase's model definitions with the latest offerings from AI providers.
Dependencies: Requires the jsdom package (included in devDependencies) for parsing HTML documentation.
Production Build Environment Variable Checks#
API Key Safeguard#
When running a production build (e.g., pnpm build or pnpm zip), the build system will fail immediately if any environment variables matching WXT_*_API_KEY are detected. This is enforced by a Vite plugin to prevent accidental bundling of sensitive API keys into production artifacts.
Whitelisted Keys:
WXT_POSTHOG_API_KEY is explicitly whitelisted and exempt from this check. This analytics key is intended to be bundled with the extension and will not cause build failures.
If you see an error like:
Found WXT_*_API_KEY environment variables that may be bundled:
- WXT_OPENAI_API_KEY
- WXT_DEEPSEEK_API_KEY
Please unset these variables before building for production.
Resolution:
- Unset or remove any
WXT_*_API_KEYenvironment variables from your environment before starting a production build (exceptWXT_POSTHOG_API_KEY, which is allowed). - This check only runs in production mode and does not affect local development workflows.
This safeguard helps ensure that API keys are not inadvertently included in production bundles.
Required Environment Variables for Extension Packaging#
When creating a production zip of the browser extension (using pnpm zip, pnpm zip:edge, pnpm zip:firefox, or pnpm zip:all), the build system requires the following environment variables to be set:
WXT_GOOGLE_CLIENT_ID: Google OAuth client ID for extension authenticationWXT_POSTHOG_API_KEY: PostHog API key for anonymous opt-in analytics trackingWXT_POSTHOG_HOST: PostHog host URL for analytics tracking
If any of these variables are missing, the build will fail with an error message listing the missing variables.
Purpose of Analytics Variables:
The PostHog environment variables enable anonymous, opt-in analytics tracking to help improve user experience and guide future development direction. Analytics is enabled by default on Chromium-based browsers and disabled by default on Firefox. Users can opt out anytime in Settings → Config → About.
Development Mode Distinct ID Override:
- The
WXT_POSTHOG_TEST_UUIDenvironment variable can be used to override the PostHog distinct ID for testing purposes. - In development builds (when
DEV=true), ifWXT_POSTHOG_TEST_UUIDis not set or contains only whitespace, the analytics system automatically uses a default test UUID:00000000-0000-0000-0000-000000000001. - Setting an explicit
WXT_POSTHOG_TEST_UUIDvalue overrides this development default. - In production builds, no automatic distinct ID override is applied; the extension generates a normal install ID unless an explicit override is provided.
GitHub Actions:
In GitHub Actions workflows, these environment variables can be sourced from either GitHub Secrets or GitHub Variables using fallback syntax: ${{ secrets.WXT_POSTHOG_API_KEY || vars.WXT_POSTHOG_API_KEY }}.
- Migration:
- Set all required variables in your
.env.productionfile or export them in your environment before running any zip command (pnpm zip,pnpm zip:edge,pnpm zip:firefox, orpnpm zip:all). - All zip builds are affected by this check; development builds (
pnpm dev, etc.) are unchanged.
- Set all required variables in your
Example:
# .env.production
WXT_GOOGLE_CLIENT_ID=your-google-client-id
WXT_POSTHOG_API_KEY=your-posthog-api-key
WXT_POSTHOG_HOST=https://your-posthog-host.com
Or, set them in your shell before running the zip command:
export WXT_GOOGLE_CLIENT_ID=your-google-client-id
export WXT_POSTHOG_API_KEY=your-posthog-api-key
export WXT_POSTHOG_HOST=https://your-posthog-host.com
pnpm zip:all
If any variables are missing, you will see an error like:
Missing required environment variables for zip:
- WXT_GOOGLE_CLIENT_ID
- WXT_POSTHOG_API_KEY
- WXT_POSTHOG_HOST
Set them in .env.production or your environment.
New Zip Scripts:
pnpm zipcreates a Chrome extension zip.pnpm zip:edgecreates an Edge extension zip.pnpm zip:firefoxcreates a Firefox extension zip (Manifest V3).pnpm zip:allbuilds Chrome, Edge, and Firefox zips sequentially.
The release workflow uses pnpm zip:all to generate all three browser zips and uploads them to GitHub releases automatically. The release workflow also supports manual triggering via workflow_dispatch to rebuild assets for existing release tags without publishing a new version.
Vercel Configuration#
The apps/website directory uses a vercel.json file to control deployment behavior. The configuration uses the ignoreCommand property to skip deployments for commits that only modify changeset files:
{
"$schema": "https://openapi.vercel.sh/vercel.json",
"ignoreCommand": "bash -c 'git diff --quiet HEAD^ HEAD -- . ../../packages ../../package.json ../../pnpm-lock.yaml \":(exclude)../../.changeset\"'"
}
This ensures that Vercel deployments are skipped when a commit only contains changeset updates, improving deployment efficiency and avoiding unnecessary builds. Nx is now used for local build orchestration, but Vercel deployment logic is unchanged.
WXT Zip Configuration#
The wxt.config.ts file includes a zip configuration section that controls which files are included or excluded when creating distribution zip files:
zip: {
includeSources: ['.env.production'],
excludeSources: ['docs/**/*', 'assets/**/*', 'repos/**/*'],
}
- includeSources: Explicitly includes
.env.productionin the zip archive. - excludeSources: Excludes documentation, assets, and repository files from the distribution package to reduce bundle size.
Firefox Manifest Configuration#
The wxt.config.ts file includes Firefox-specific manifest settings under browser_specific_settings.gecko:
browser_specific_settings: {
gecko: {
id: "{bd311a81-4530-4fcc-9178-74006155461b}",
strict_min_version: "112.0",
data_collection_permissions: {
required: [],
optional: ["technicalAndInteraction"],
},
},
},
Minimum Firefox Version:
- The extension requires Firefox
112.0or later. - Firefox 112 is the minimum version with full support for Manifest V3 background scripts (
background.type).
Data Collection Permissions:
- The
data_collection_permissions.optionalfield declares that the extension may collect "technicalAndInteraction" data. - This metadata is required for Firefox Add-ons (AMO) compliance when using analytics tools like PostHog.
- This declaration aligns with the PostHog analytics configuration (see
WXT_POSTHOG_API_KEYandWXT_POSTHOG_HOSTin Required Environment Variables for Extension Packaging). - Analytics is opt-in and disabled by default on Firefox; users can manage preferences in Settings → Config → About.
Firefox Content Security Policy (CSP) Override#
The wxt.config.ts file includes a custom Content Security Policy configuration for Firefox MV3 extensions to support HTTP requests to local and LAN providers:
content_security_policy: {
extension_pages: "script-src 'self' 'wasm-unsafe-eval'; object-src 'self';",
},
Why this override is needed:
- Firefox MV3 extensions include
upgrade-insecure-requestsin their default CSP, which silently upgrades all HTTP URLs to HTTPS. - This breaks custom providers using LAN or local HTTP endpoints (e.g.,
http://192.168.31.210:8090/v1). - The override sets the CSP to
script-src 'self' 'wasm-unsafe-eval'; object-src 'self';, which excludesupgrade-insecure-requestswhile adding'wasm-unsafe-eval'to properly support WebAssembly. - This allows HTTP requests to work correctly in Firefox while maintaining security for extension pages.
Impact:
- HTTPS users: No impact (HTTPS is never downgraded).
- HTTP users (local/LAN providers): HTTP requests work correctly in Firefox.
- Chrome/Edge: No behavior change (already the default CSP).
Firefox Web Accessible Resources#
The wxt.config.ts file includes a web_accessible_resources configuration to allow content scripts to load image and SVG assets:
web_accessible_resources: [
{
resources: ["assets/*.png", "assets/*.svg", "assets/*.webp"],
matches: ["*://*/*", "file:///*"],
},
],
Why this configuration is required:
- Content scripts that inject UI components with
<img>tags need explicit permission to load image assets frommoz-extension://URLs on regular web pages. - When content scripts reference images in their UI (e.g., logos, icons in toasts, floating buttons, popovers), the host page's Content Security Policy (CSP) can block the extension's internal URLs unless they are declared as web accessible resources.
- Firefox enforces this CSP requirement more strictly than Chrome, making this configuration essential for Firefox compatibility.
- This configuration grants access to PNG, SVG, and WebP assets in the
assets/directory for all pages and local files.
Impact:
- Enables content-script UI components to display images and icons correctly across all browsers, especially Firefox.
- Required for UI elements like floating buttons, toasts, and popover components that reference extension assets via
<img>tags. - No security impact: Only explicitly listed asset types from the
assets/directory are exposed.
Background Fetch Infrastructure#
The extension provides a shared background fetch infrastructure to proxy HTTP requests through the background script, bypassing Content Security Policy (CSP) restrictions that affect content scripts.
Background Fetch Client#
The core implementation is in src/utils/content-script/background-fetch-client.ts, which provides:
backgroundFetch(input, init, options): A shared function that proxiesfetch()requests through the background script viasendMessage("backgroundFetch", ...).- Response type support: Handles both text responses (JSON, HTML, etc.) and binary responses (images, fonts, etc.) via
responseType: "text" | "base64"option. - Response reconstruction: Automatically converts base64-encoded binary payloads back into proper
Responseobjects witharrayBuffer()andblob()support.
This client is used by both the Iconify icon loader and the asset URL resolver to avoid CSP violations when content scripts need to load external resources.
Iconify Background Fetch Setup#
The extension includes infrastructure to handle Iconify icon requests in content scripts through the background script. This is implemented in src/utils/iconify/setup-background-fetch.ts.
Why this is needed:
- Content scripts that use Iconify to dynamically load SVG icons can have their HTTP requests blocked by the host page's Content Security Policy (CSP).
- Many websites enforce strict CSP rules that prevent content scripts from making direct
fetch()requests to external APIs like Iconify's icon servers. - The background script is not subject to the host page's CSP restrictions and can safely perform these HTTP requests.
How it works:
- The
ensureIconifyBackgroundFetch()function configures Iconify to proxy all icon API requests through the background script using the sharedbackgroundFetch()client. - It uses Iconify's internal
_api.setFetch()method to replace the default fetch handler with the background fetch proxy. - This configuration is applied once per content script runtime and is idempotent (calling it multiple times has no effect).
Usage:
Content scripts that use Iconify must call ensureIconifyBackgroundFetch() before rendering any icons. For example, src/entrypoints/selection.content/index.tsx includes this call at the top of the script.
import { ensureIconifyBackgroundFetch } from "@/utils/iconify/setup-background-fetch"
ensureIconifyBackgroundFetch()
Note: To avoid CSP issues entirely, the codebase primarily uses bundled React icon components from @remixicon/react and @tabler/icons-react instead of dynamically loading icons via Iconify. The background fetch setup remains available for cases where dynamic icon loading is required.
Background Asset URL Proxying#
The extension provides utilities to proxy remote HTTP(S) assets through background fetch when running in content script contexts. This is implemented in src/utils/content-script/background-asset-url.ts.
Purpose:
- Proxy remote HTTP(S) assets (images, logos, etc.) through the background script to avoid CSP violations when content scripts display remote resources.
- Convert fetched binary assets to blob URLs that can be used safely in content script UI components.
Key functions:
shouldProxyAssetUrl(resourceUrl, pageUrl?): Determines if a URL needs proxying. Returnstruefor remote HTTP(S) URLs when the current page is not an extension page (e.g., options, popup). Returnsfalsefor data URIs, extension URLs, and when already on an extension page.resolveContentScriptAssetUrl(resourceUrl): Fetches the asset viabackgroundFetch()withresponseType: "base64", converts the response to a Blob, creates an object URL, and caches the result. Returns the cached object URL on subsequent calls.clearResolvedContentScriptAssetUrls(): Clears the cache and revokes all object URLs created by the resolver. Useful for cleanup when content scripts unmount.
Caching behavior:
- Resolved object URLs are cached in
resolvedAssetUrlCacheto avoid redundant fetches. - Pending promises are cached in
pendingAssetUrlCacheto deduplicate concurrent requests for the same asset URL. - The cache persists for the lifetime of the content script unless explicitly cleared.
Usage:
The ProviderIcon component uses resolveContentScriptAssetUrl() to load remote provider logos safely in content scripts:
import { resolveContentScriptAssetUrl, shouldProxyAssetUrl } from "@/utils/content-script/background-asset-url"
// Check if proxying is needed
if (shouldProxyAssetUrl(logoUrl)) {
const resolvedUrl = await resolveContentScriptAssetUrl(logoUrl)
// Use resolvedUrl (blob URL) in <img src={resolvedUrl} />
}
Architecture:
- Content scripts use
backgroundFetch()(frombackground-fetch-client.ts) to request assets. - The background fetch client sends the request to the background service worker via
sendMessage("backgroundFetch", ...). - The background service worker performs the actual HTTP request and returns the response body encoded as base64 for binary assets.
- The asset URL resolver converts the base64 response to a Blob and creates an object URL for use in the DOM.
Zod Configuration for MV3 Compatibility#
All browser extension entrypoints automatically import @/utils/zod-config as a side-effect import to prevent Content Security Policy (CSP) violations in Manifest V3 extensions.
Why this is implemented:
- Zod v4 uses
new Function("")to detect eval support, which triggers CSP violations in Manifest V3 extensions. - The
@/utils/zod-configmodule callsz.config({ jitless: true })to configure Zod to run in jitless mode, skipping thenew Functiondetection and preventing CSP eval violations. - This configuration is applied before any Zod schemas are defined or used.
Implementation:
All extension entrypoints include this import at the top of their imports:
src/entrypoints/background/index.tssrc/entrypoints/host.content/index.tsxsrc/entrypoints/selection.content/index.tsxsrc/entrypoints/side.content/index.tsxsrc/entrypoints/subtitles.content/index.tsxsrc/entrypoints/popup/main.tsxsrc/entrypoints/options/main.tsx
Example:
import "@/utils/zod-config"
// ... other imports
The ESLint import ordering rules (see Import Ordering) enforce that this import stays at the top of all files through a custom "setup" import group.
Package Overview#
- apps/extension: Browser extension using wxt, React 19, and various browser APIs. Scripts include
build,build:edge,build:firefox,dev,dev:edge,dev:firefox,lint,test,type-check, and packaging for different browsers:pnpm zip: Package Chrome extension zippnpm zip:edge: Package Edge extension zippnpm zip:firefox: Package Firefox extension zip (Manifest V3)pnpm zip:all: Build Chrome, Edge, and Firefox zips sequentially- The release workflow uses
pnpm zip:alland uploads all three browser zips to GitHub releases. - UI Components: All UI components are consolidated under
src/components/ui/. Thebase-uisubdirectory contains foundational UI primitives (e.g.,button,input,select, etc.), and additional components liketreeare also underui/. To import a UI component, use paths like@/components/ui/base-ui/buttonor@/components/ui/tree. - HelpButton Component: A draggable help button is available on the options and translation-hub pages. The button floats in the bottom-right or top-right corner, can be dragged between corners with localStorage persistence, and opens GitHub issues when clicked. This replaces the previous
agentationdev toolbar.
- apps/website: Next.js app using React 19 and Tailwind CSS 4.2.1. Scripts include
build,dev,lint,lint:fix,type-check,postinstall(fumadocs-mdx), andstart. Depends on internal packages for API, auth, DB, definitions, and UI. - packages/auth, db, api, definitions, ui: Each package has its own scripts for linting and, where relevant, database operations or exports. Internal dependencies use the workspace protocol.
Dependency Management#
- Pinned Versions: All
@read-frog/*dependencies are pinned to specific versions instead of usinglatest. Current versions include:@read-frog/api-contract@0.2.2@read-frog/definitions@0.1.2
- Icon Strategy: The extension uses bundled React icon components from
@remixicon/reactand@tabler/icons-reactto avoid Content Security Policy (CSP) restrictions on dynamically loaded SVGs. For cases requiring dynamic icon loading via Iconify, the extension provides a background fetch proxy (see Background Fetch Infrastructure). - Charting Library: The project uses
recharts(^3.8.1), a composable charting library built on React components, for rendering statistics charts such as the batch request chart. - Keyboard Shortcuts: The project uses
@tanstack/hotkeys(^0.7.1) and@tanstack/react-hotkeys(^0.9.1) for cross-platform keyboard shortcut handling. TanStack hotkeys provides portable key format with "Mod" semantics (Command on macOS, Control elsewhere), better TypeScript support, and modern event handling without global scope pollution. - ORPC: The project uses
@orpc/client(^1.13.13) and@orpc/tanstack-query(^1.13.13) for type-safe API client communication and TanStack Query integration. - New Dependencies:
tw-animate-cssis included for Tailwind animation utilities.@remixicon/reactis included for Remix icon components.rechartsis included for data visualization.@tanstack/hotkeysand@tanstack/react-hotkeysare included for keyboard shortcut management.@orpc/tanstack-queryis included for TanStack Query integration with ORPC clients. - Removed:
eslint-plugin-turboand related configuration have been removed. Theagentationdev dependency has also been removed and replaced with a custom HelpButton component.@visactor/react-vchartand@visactor/vcharthave been removed in favor ofrecharts. Theeffectdependency has been removed.hotkeys-jshas been replaced with TanStack hotkeys. - Dependabot: Automated dependency updates are configured via
.github/dependabot.yml. Dependabot automatically creates pull requests for outdated dependencies:- npm packages: Updated weekly with intelligent grouping:
- AI SDK packages (
@ai-sdk/*andai) are grouped together - Production dependencies (excluding AI SDK) are grouped together
- Development dependencies are grouped separately
- AI SDK packages (
- GitHub Actions: Updated monthly
- All Dependabot PRs are labeled with "chore" and use "chore" commit message prefixes
- Developers should review and merge Dependabot PRs to keep dependencies current. These automated updates complement manual dependency management via syncpack and changesets.
- npm packages: Updated weekly with intelligent grouping:
- Syncpack: Ensures consistent dependency versions. Use
pnpm syncpack:lintto check andpnpm syncpack:fixto resolve mismatches. - Changesets: Handles versioning and changelogs.
Tailwind and Theme Setup#
-
The Tailwind theme now imports
tailwindcss,tw-animate-css, and@read-frog/ui/styles/theme-base.cssinsrc/assets/tailwind/theme.css. -
Example import order:
@import 'tailwindcss'; @import 'tw-animate-css'; @import '@read-frog/ui/styles/theme-base.css'; @source "../**/*.{ts,tsx}"; -
Tailwind CSS version:
4.2.2
Linting and Formatting#
- ESLint is managed centrally via the
@repo/eslint-configworkspace package. Each package or app extends this config as needed. - Lint scripts are standardized:
"lint": "eslint .", "lint:fix": "eslint --fix" eslint-plugin-turbois no longer used.
Import Ordering#
ESLint enforces a custom import ordering convention using perfectionist/sort-imports:
- A custom "setup" import group has been added to the ESLint configuration to ensure that side-effect imports like
@/utils/zod-configappear first in all import lists. - The "setup" group is specifically for side-effect imports that must run before any other code executes (e.g., global configuration).
- Import groups are ordered as: setup, type imports, builtin values, external values, internal values, relative values, side-effects.
- The ESLint rule automatically enforces that
@/utils/zod-configstays at the very top of import lists through thecustomGroupsconfiguration withelementNamePattern: "@/utils/zod-config". - Developers should follow this ordering convention to ensure consistent code style and proper initialization order.
Testing and Type Checking#
- Testing is handled via Turborepo scripts. The extension uses Vitest for unit and integration tests.
- Type checking is performed with TypeScript across all packages. The website app includes a dedicated
type-checkscript (tsc --noEmit) for local type validation.
Pre-push Hook#
The .husky/pre-push hook runs the following checks before pushing:
pnpm exec nx lint: Runs linting across the monorepopnpm exec nx type-check: Performs TypeScript type checking- Free API tests (conditional, runs unless
SKIP_FREE_API=trueis set)
Note: The build step (pnpm exec nx build) is currently disabled in the pre-push hook to streamline the development workflow.
Notable Environment and Tooling#
- All packages are ES modules (
"type": "module"). - Shared TypeScript and ESLint configs are published as workspace packages.
- Build, lint, and test scripts are standardized and run via Turborepo for consistency and caching.
- The repository is private and versioned as
0.0.0at the root. - Node.js version:
>=22.0.0 - pnpm version:
10.32.1 - TypeScript version:
^6.0.2 - Tailwind CSS version:
4.2.2 - ESLint version:
^10.1.0 - Vite version:
^8.0.3 - Vitest version:
^4.1.2 - shadcn version:
^4.1.2(for UI component management) - Fumadocs, Next.js, and other major dependencies are kept up to date. See individual
package.jsonfiles for details.
Internationalization (i18n)#
- The English locale for the Read Service has been updated. The description now reads: "For read and explain content".
References#
For historical context or removed apps, refer to the repository history.
Note: When packaging the browser extension for production (zip builds), you must set WXT_GOOGLE_CLIENT_ID, WXT_POSTHOG_API_KEY, and WXT_POSTHOG_HOST in your environment or .env.production. These variables are required for successful production packaging.