TapWord Translator
Documents a Chrome extension that translates selected text using LLMs, with floating annotations and persistent notes.
What this file does
Documents a Chrome extension that translates selected text using LLMs, with floating annotations and persistent notes.
When to use it
- Building a browser extension that needs context-aware translation
- Creating a Chrome extension with content scripts and background workers
- Implementing floating UI overlays for selected text
- Setting up a TypeScript+Vite extension project with E2E tests
Assumes this stack
TapWord Translator
A smart AI-powered translation browser extension that provides context-aware translations for selected text on web pages.
✨ Features
- Smart Trigger: A subtle icon appears next to selected text, waiting for your click.
- Context-Aware Translation: By analyzing the surrounding text, the AI delivers highly accurate and relevant translations, far beyond simple word-for-word equivalents.
- AI-Powered: Leverages the power of Large Language Models (LLMs) like GPT and Gemini for superior translation quality.
- Floating Notes Display: Translations are displayed in an unobtrusive floating card directly below the highlighted text.
- Persistent Annotations: All translations remain on the page as you scroll, creating a temporary "annotated" version of the site for easy reference.
Folder Structure
.
├── dist/ # Build output (loaded into Chrome)
├── resources/ # Static assets (icons, etc.)
├── src/ # Source code
│ ├── 0_common/ # Shared utilities, types, and constants
│ ├── 1_content/ # Content scripts injected into web pages
│ ├── 2_background/ # Background service worker
│ ├── 3_popup/ # Extension popup UI
│ ├── 5_backend/ # Generic API infrastructure (service, types)
│ ├── 6_translate/ # Translation business logic
│ ├── 7_speech/ # Speech synthesis module
│ └── 8_generate/ # Text generation module
├── test/ # Unit and integration tests
├── package.json # NPM package configuration
├── tsconfig.json # TypeScript configuration
└── vite.config.ts # Vite build configuration
Sub-Module Documentation
Mandatory Reading: Before working on any file within a sub-module, you MUST read its corresponding README document first, to understand its architecture and coding conventions.
src/0_common/README.mdsrc/1_content/README.mdsrc/2_background/README.mdsrc/3_popup/README.mdsrc/5_backend/README.mdsrc/6_translate/README.mdsrc/7_speech/README.mdsrc/8_generate/README.md
Technical Stack
Core Technologies
- TypeScript: For static typing and modern JavaScript features.
- Vite: As the build tool for development and production.
- Vitest: For running unit and integration tests.
Key Configuration Files
package.json: Defines project scripts, dependencies, and metadata.vite.config.ts: Configures the Vite build process, including plugins and build targets.tsconfig.json: Specifies TypeScript compiler options and project files.manifest.json: The extension manifest file for Chrome.
Common Commands
npm run dev: Starts the development build with watch mode.npm run build: Creates a production-ready build.npm run dev:community: Starts the community build with watch mode.npm run build:community: Creates a community-ready build.npm test -- run <test-file>: Run a specific test file.npm run type-check: Checks for TypeScript type errors without compiling.
Project Coding Conventions
Import Style
- Absolute Paths: Always use the
@/prefix (maps tosrc/) for imports instead of relative paths (../). - Namespace Imports: Use namespace imports (
import * as name from '...') for functions and variables to make their origin explicit. This is preferred over named imports for clarity.
// ✅ Correct
import * as loggerModule from '@/0_common/utils/logger';
const logger = loggerModule.createLogger('my-module');
// ❌ Avoid (Relative Path and Named Import)
import { createLogger } from '../../0_common/utils/logger';
const logger = createLogger('my-module');
Module Index Files
- Explicit exports only: Module
index.tsfiles must explicitly list all exported members, never useexport * - Categorized exports: Group exports by type (classes, functions, types) with clear comments
- Type annotations: Use
export typefor type-only exports to enable proper tree-shaking
// ✅ Correct - Explicit exports with categories
export type { TranslationApiData, TranslateParams } from './models/TranslationModels';
export { translate, translateWord } from './services/TranslationService';
// ❌ Avoid - Wildcard exports
export * from './models/TranslationModels';
Logging
- Use logger utility: Replace
console.log/errorwithcreateLogger()for consistent prefixes
// ✅ Correct
import { createLogger } from '@/0_common/utils/logger';
const logger = createLogger('className/ModuleName/functionName');
logger.info('Message');
// ❌ Avoid
console.log('[ModuleName] Message');
Code Organization
- Export functions/variables at file top, internal functions below
In-App UI Localization
The project uses a custom utility at src/0_common/utils/i18n.ts for in-app UI translations.
- HTML: Add
data-i18n-key="key.name"to elements.applyTranslations()will handle the rest. - TypeScript: Import with
import * as i18nModule from "@/0_common/utils/i18n", then usei18nModule.translate('key.name')for dynamic strings.
Architecture Principles
- Infrastructure Purity: Infrastructure code MUST be agnostic of business logic and environment state.
- Inject, Don't Fetch: Pass configuration via arguments (Dependency Injection). NEVER import business logic or state managers into infrastructure layers.
Automated E2E Testing (Playwright)
Use Playwright to verify extension functionality in a real browser environment.
For detailed instructions on running, writing, and debugging E2E tests, AI agents MUST refer to the dedicated skill document:
docs/skills/e2e-testing/SKILL.md
What's inside
8 sections covering features, folder structure, sub-module docs, tech stack, commands, coding conventions, i18n, and E2E testing
Change this for your project
- Replace
hongyuan007/tapword-translatorwith your own repository name - Replace
@/path alias with your own project's alias if different - Replace
src/0_common/utils/loggerwith your own logger module path - Replace
docs/skills/e2e-testing/SKILL.mdwith your own E2E skill document path
Where it goes
Save as AGENTS.md in your repository root. Read by Codex, Cursor and other agents that follow the AGENTS.md convention.
Worth borrowing
- Namespace imports with explicit module prefix to clarify origin
- Categorized explicit exports in index files instead of wildcard re-exports
- Dependency injection for infrastructure layers to keep them agnostic of business logic
Related Documents
Browser-only development
Guides AI assistants on an Electron + React + TypeScript desktop app for browsing and organizing AI-generated images locally.
Claude Agents — Reference & Recommendations
Catalogues 40+ Claude agents and marketing skills for building a cat adoption charity landing page, with a ready-to-paste prompt and backend API reference.
Golden DKG Prototype -- Master Plan
Defines an 8-phase implementation plan for a Rust prototype of the Golden non-interactive DKG protocol using BLS12-381 and tokio.
Swarms Examples Index
Lists 60+ example scripts for building single and multi-agent systems with the Swarms framework, organized by category and use case.