Documents
Build and Development Environment Setup
Build and Development Environment Setup
Type
Document
Status
Published
Created
Aug 8, 2025
Updated
Apr 3, 2026
Updated by
Dosu Bot

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=true in a .env.local file to enable local package resolution.
    • An example file .env.local.example is provided. Copy it to .env.local and adjust as needed.
  • TypeScript Configuration:

    • The root tsconfig.json now extends tsconfig.local.json if present.
    • An example tsconfig.local.example.json is provided. Copy it to tsconfig.local.json and uncomment the relevant paths mappings to point to your local monorepo sources.
    • This enables TypeScript to resolve @read-frog/* imports to local source directories during development.
  • Vite/WXT Configuration:

    • The wxt.config.ts file conditionally aliases @read-frog/* packages to local paths when WXT_USE_LOCAL_PACKAGES is set.
    • React and ReactDOM are always resolved as singletons from the root node_modules to avoid duplication.
  • .gitignore:

    • .gitignore is updated to ignore tsconfig.local.json but allow example files to be tracked.

Quick Start for Local Development#

  1. Copy .env.local.example to .env.local and set WXT_USE_LOCAL_PACKAGES=true.
  2. Copy tsconfig.local.example.json to tsconfig.local.json and uncomment the paths mappings as needed.
  3. Run development scripts as usual (e.g., pnpm dev or pnpm dev:local if 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_KEY environment variables from your environment before starting a production build (except WXT_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 authentication
  • WXT_POSTHOG_API_KEY: PostHog API key for anonymous opt-in analytics tracking
  • WXT_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_UUID environment variable can be used to override the PostHog distinct ID for testing purposes.
  • In development builds (when DEV=true), if WXT_POSTHOG_TEST_UUID is 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_UUID value 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.production file or export them in your environment before running any zip command (pnpm zip, pnpm zip:edge, pnpm zip:firefox, or pnpm zip:all).
    • All zip builds are affected by this check; development builds (pnpm dev, etc.) are unchanged.

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 zip creates a Chrome extension zip.
  • pnpm zip:edge creates an Edge extension zip.
  • pnpm zip:firefox creates a Firefox extension zip (Manifest V3).
  • pnpm zip:all builds 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.production in 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.0 or later.
  • Firefox 112 is the minimum version with full support for Manifest V3 background scripts (background.type).

Data Collection Permissions:

  • The data_collection_permissions.optional field 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_KEY and WXT_POSTHOG_HOST in 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-requests in 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 excludes upgrade-insecure-requests while 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 from moz-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 proxies fetch() requests through the background script via sendMessage("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 Response objects with arrayBuffer() and blob() 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 shared backgroundFetch() 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. Returns true for remote HTTP(S) URLs when the current page is not an extension page (e.g., options, popup). Returns false for data URIs, extension URLs, and when already on an extension page.
  • resolveContentScriptAssetUrl(resourceUrl): Fetches the asset via backgroundFetch() with responseType: "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 resolvedAssetUrlCache to avoid redundant fetches.
  • Pending promises are cached in pendingAssetUrlCache to 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() (from background-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-config module calls z.config({ jitless: true }) to configure Zod to run in jitless mode, skipping the new Function detection 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.ts
  • src/entrypoints/host.content/index.tsx
  • src/entrypoints/selection.content/index.tsx
  • src/entrypoints/side.content/index.tsx
  • src/entrypoints/subtitles.content/index.tsx
  • src/entrypoints/popup/main.tsx
  • src/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 zip
    • pnpm zip:edge: Package Edge extension zip
    • pnpm zip:firefox: Package Firefox extension zip (Manifest V3)
    • pnpm zip:all: Build Chrome, Edge, and Firefox zips sequentially
    • The release workflow uses pnpm zip:all and uploads all three browser zips to GitHub releases.
    • UI Components: All UI components are consolidated under src/components/ui/. The base-ui subdirectory contains foundational UI primitives (e.g., button, input, select, etc.), and additional components like tree are also under ui/. To import a UI component, use paths like @/components/ui/base-ui/button or @/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 agentation dev 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), and start. 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 using latest. 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/react and @tabler/icons-react to 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-css is included for Tailwind animation utilities. @remixicon/react is included for Remix icon components. recharts is included for data visualization. @tanstack/hotkeys and @tanstack/react-hotkeys are included for keyboard shortcut management. @orpc/tanstack-query is included for TanStack Query integration with ORPC clients.
  • Removed: eslint-plugin-turbo and related configuration have been removed. The agentation dev dependency has also been removed and replaced with a custom HelpButton component. @visactor/react-vchart and @visactor/vchart have been removed in favor of recharts. The effect dependency has been removed. hotkeys-js has 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/* and ai) are grouped together
      • Production dependencies (excluding AI SDK) are grouped together
      • Development dependencies are grouped separately
    • 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.
  • Syncpack: Ensures consistent dependency versions. Use pnpm syncpack:lint to check and pnpm syncpack:fix to 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.css in src/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-config workspace package. Each package or app extends this config as needed.
  • Lint scripts are standardized:
    "lint": "eslint .",
    "lint:fix": "eslint --fix"
    
  • eslint-plugin-turbo is 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-config appear 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-config stays at the very top of import lists through the customGroups configuration with elementNamePattern: "@/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-check script (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 monorepo
  • pnpm exec nx type-check: Performs TypeScript type checking
  • Free API tests (conditional, runs unless SKIP_FREE_API=true is 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.0 at 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.json files 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.