From 1ed5f1dc25e6bb344c83d86b899b7dedd7c62af2 Mon Sep 17 00:00:00 2001 From: Bartosz Tomczyk Date: Sun, 22 Mar 2026 07:35:12 +0100 Subject: [PATCH] docs: split agent guidance into modular docs --- AGENTS.md | 249 +++----------------------------- docs/agents/architecture.md | 38 +++++ docs/agents/commands.md | 50 +++++++ docs/agents/runtime-features.md | 55 +++++++ docs/agents/testing.md | 58 ++++++++ 5 files changed, 218 insertions(+), 232 deletions(-) create mode 100644 docs/agents/architecture.md create mode 100644 docs/agents/commands.md create mode 100644 docs/agents/runtime-features.md create mode 100644 docs/agents/testing.md diff --git a/AGENTS.md b/AGENTS.md index fc6fc47b..14e8fa77 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,239 +1,24 @@ # AGENTS.md -This file is the **project brief for AI coding agents** working on FluentTyper (browser extension: autocomplete + spellcheck + text expansions). +FluentTyper is a privacy-first browser extension that provides local autocomplete, spellcheck, and text expansion across the web. -If you’re an agent: follow the guardrails below, prefer small focused changes, and keep the extension privacy-first and offline-friendly. +- Package manager: `bun@1.3.10` +- Build: `bun run build` +- Firefox build: `bun run build --platform=firefox` +- Full repo check: `bun run check` +- Typecheck only: `bun run typecheck` ---- +## Core Principles -## Non‑negotiables +- Keep typed content local; do not add telemetry, external uploads, or phone-home behavior. +- Keep the core experience working offline. +- Do not add new permissions or host permissions unless a maintainer explicitly asks for them. +- Preserve platform separation across Chrome, Edge, and Firefox manifests and quirks. +- Preserve architecture boundaries: Domain -> Application -> Adapters -> UI. -- **Privacy-first**: do not add telemetry, external uploads, or “phone home” behavior. Typed content must stay local. -- **Offline-first**: keep the core experience working offline. -- **Don’t expand permissions casually**: avoid adding new permissions/host permissions unless a maintainer request explicitly requires it. -- **Respect platform separation** (Chrome/Edge vs Firefox manifests and quirks). -- **Keep architecture boundaries** (Domain → Application → Adapters → UI). See “Architecture rules”. +## Task-Specific Guides ---- - -## Tech stack + tooling - -- **Language**: TypeScript (strict). -- **Runtime/build**: Bun (repo is pinned to a specific Bun version via `packageManager`). -- **Bundling**: `bun run build` produces `build/` and copies assets/manifests. -- **Lint/format**: ESLint + Prettier. -- **Tests**: - - Unit: `bun run test` - - Fast e2e smoke: `bun run test:e2e` - - Full e2e regression: `bun run test:e2e:full` - - Dev-runtime e2e: `bun run test:e2e:dev` - - Coverage matrix validation: `bun run check:e2e:coverage` - ---- - -## “Golden” commands (run these) - -### Install - -```bash -bun install -``` - -### Build - -```bash -bun run build -# Build Firefox: -bun run build --platform=firefox -``` - -### Quality gates (before PR) - -```bash -bun run lint -bun run format:check -bun run test -bun run test:e2e -bun run check:e2e:coverage -# Required when runtime/e2e behavior changes: -bun run test:e2e:full -bun run test:e2e:full --platform=firefox -# Required when changing dev-runtime hooks/toggles: -bun run test:e2e:dev -bun run test:e2e:dev --platform=firefox -# Recommended smoke cross-browser check: -bun run test:e2e --platform=firefox -``` - -Smoke budget policy: - -- `bun run test:e2e --platform=chrome` and `bun run test:e2e --platform=firefox` both target `<=10s` wall-time. -- CI records and reports smoke runtime, but does not fail solely for exceeding the 10s target. - -### Autofix - -```bash -bun run fix -``` - ---- - -## Repository map (where things live) - -### Entry points (bundled) - -- `src/entries/background.ts` → background bootstrap -- `src/entries/content_script.ts` → content-script bootstrap -- `src/entries/popup.ts` → popup UI bootstrap -- `src/entries/settings.ts` → options/settings bootstrap - -### Layered architecture - -- `src/core/domain/` - Contracts, types, constants, pure logic. **No imports from application/adapters/ui**. -- `src/core/application/` - Use-cases, repositories, settings/logging utilities. **No imports from adapters/ui**. -- `src/adapters/chrome/` - Browser integration: - - `background/` service worker + prediction orchestration, settings application, routing - - `content-script/` DOM integration + suggestion rendering -- `src/ui/` - Popup + options UI. - -### Path aliases (use these) - -- `@core/*`, `@adapters/*`, `@ui/*`, `@third-party/*` - -Avoid legacy import roots like: - -- `src/background/*`, `src/content-script/*`, `src/shared/*` - ---- - -## Architecture rules (important) - -Follow these boundaries when adding/changing code: - -- `src/core/domain`: **pure** domain logic only. -- `src/core/application`: orchestration/repositories/utilities; **no adapter or UI imports**. -- `src/adapters/chrome`: integration layer; background and content-script must remain separated: - - `src/adapters/chrome/background/**` must not import from `.../content-script/**` - - `src/adapters/chrome/content-script/**` must not import from `.../background/**` -- `src/ui`: UI only; do not reach into adapter internals. - -If you need a cross-layer contract, put it in: - -- `src/core/domain/contracts/**` and/or `src/core/domain/messageTypes.d.ts` - ---- - -## Prediction + messaging overview (so you don’t break it) - -High level flow: - -1. Content script observes typing and requests predictions via runtime messaging. -2. Background routes messages and runs prediction (Presage in prod; optional WebLLM in dev builds). -3. Background sends prediction response back to the correct tab/frame. -4. Content script renders suggestions + handles acceptance (Tab/keyboard navigation). - -If you change message shapes: - -- Update `src/core/domain/messageTypes.d.ts` -- Update constants in `src/core/domain/constants.ts` -- Update routers/handlers in `src/adapters/chrome/background/router/**` -- Update content message handling in `src/adapters/chrome/content-script/**` - ---- - -## WebLLM / AI predictor constraint (dev/debug only) - -- Production store builds are **Presage-only**. -- Dev/debug builds can include WebLLM and will adjust CSP/connect-src accordingly during build. - -When touching this area: - -- Do not make WebLLM required for normal operation. -- Keep safe fallbacks when the AI predictor is unavailable or times out. -- Avoid increasing network surface area in production builds. - ---- - -## Text expansions + dynamic variables - -Text expansion is configured via settings and used in prediction + expansion logic. - -Dynamic variables are resolved in: - -- `src/core/domain/variables.ts` (e.g. `${time}`, `${date}`, `${datetime}`, `${uuid}`, `${random:...}`) -- `src/adapters/chrome/background/TemplateExpander.ts` (async resolver; can also read active tab context for page variables) - -If you add a new variable: - -1. Add it to `resolveDynamicVariable(...)` in `src/core/domain/variables.ts` when it can be computed locally. -2. If it needs browser context (tab/title/url), extend the resolver in `TemplateExpander.createResolver(...)`. -3. Add/adjust tests if behavior changes. - ---- - -## Settings changes (how to do it safely) - -When adding a new user-facing setting: - -- Add a key/constant in `src/core/domain/constants.ts` (if it’s used in runtime logic). -- Wire it through repositories (likely `src/core/application/repositories/**`). -- Ensure config assembly includes it if it affects runtime (`src/adapters/chrome/background/config/ConfigAssembler.ts`). -- Update UI (options/popup) and defaults/migrations as needed. - -Keep backward compatibility in mind; migrations exist for older stored settings. - ---- - -## Platform manifests + versioning - -Manifests live under: - -- `platform/chrome/manifest.json` -- `platform/firefox/manifest.json` -- `platform/edge/manifest.json` - -Versioning workflow: - -- `package.json` is the source of truth for the version. -- `bun version` runs `scripts/update-manifest-version.cjs` to sync manifest versions. - -Do not hand-edit versions in multiple places without running the script. - ---- - -## Logging guidelines - -- Default prod logging should be minimal (warn/error). -- Avoid logging full user text content. -- If you add debug logs, guard them behind dev mode and/or existing logging levels. - ---- - -## What to include in PRs - -- A short description of the user-visible impact. -- Tests run. - Required baseline: `bun run lint` + `bun run format:check` + `bun run test` + `bun run test:e2e` + `bun run check:e2e:coverage`. -- If changing runtime behavior: add/adjust tests (unit and/or e2e). -- If changing UI: screenshots are helpful. - -E2E coverage policy: - -- Coverage parity is enforced by behavior mapping, not by preserving identical e2e case counts. -- If behavior moves between e2e/unit/integration tests, update `tests/e2e/coverage-matrix.json` and `tests/e2e/coverage-baseline-ids.json`. - ---- - -## If you’re unsure - -Prefer: - -- Small, reversible changes -- Adding tests -- Keeping behavior consistent with README/Contributing docs - -When in doubt, do not widen permissions, do not add network dependencies, and do not cross architecture boundaries. +- [Commands and release workflow](docs/agents/commands.md) +- [Architecture and code placement](docs/agents/architecture.md) +- [Testing and coverage policy](docs/agents/testing.md) +- [Runtime feature workflows](docs/agents/runtime-features.md) diff --git a/docs/agents/architecture.md b/docs/agents/architecture.md new file mode 100644 index 00000000..acdae12d --- /dev/null +++ b/docs/agents/architecture.md @@ -0,0 +1,38 @@ +# Architecture and Code Placement + +FluentTyper uses a layered architecture. Keep imports and responsibilities flowing downward only. + +## Layers + +- `src/core/domain/`: pure domain logic, contracts, constants, guards, and types. Do not import from application, adapters, or UI. +- `src/core/application/`: use-case orchestration, repositories, logging, and settings access. Do not import from adapters or UI. +- `src/adapters/chrome/`: browser integration for background and content-script runtime behavior. Do not import from UI. +- `src/ui/`: popup, onboarding, and settings UI. Do not import from adapter internals. + +## Adapter Separation + +- `src/adapters/chrome/background/**` must not import from `src/adapters/chrome/content-script/**`. +- `src/adapters/chrome/content-script/**` must not import from `src/adapters/chrome/background/**`. + +## Entry Points + +- `src/entries/background.ts` +- `src/entries/content_script.ts` +- `src/entries/content_script_main_world.ts` +- `src/entries/content_script_main_world_start.ts` +- `src/entries/popup.ts` +- `src/entries/settings.ts` +- `src/entries/onboarding.ts` + +## Imports and Shared Contracts + +- Prefer path aliases: `@core/*`, `@adapters/*`, `@ui/*`, `@third-party/*`. +- Avoid legacy roots such as `src/background/*`, `src/content-script/*`, and `src/shared/*`. +- Put cross-layer contracts in `src/core/domain/contracts/**`. +- Keep runtime message schemas and shared message types in `src/core/domain/messageTypes.d.ts`. + +## Placement Heuristics + +- Keep modules focused and composable; do not re-introduce large monolithic runtime files. +- Follow existing placement patterns before creating new top-level structure. +- When architecture changes affect routing or runtime boundaries, update the related tests called out in [testing.md](testing.md). diff --git a/docs/agents/commands.md b/docs/agents/commands.md new file mode 100644 index 00000000..4889e345 --- /dev/null +++ b/docs/agents/commands.md @@ -0,0 +1,50 @@ +# Commands and Release Workflow + +Use Bun for installs, scripts, and versioning. `bun.lock` is the canonical lockfile. + +- Primary language: TypeScript with strict type-checking. +- Linting and formatting are handled with ESLint and Prettier through the Bun scripts in `package.json`. + +## Common Commands + +- Install dependencies: `bun install` +- Production build: `bun run build` +- Firefox production build: `bun run build --platform=firefox` +- Watch mode: `bun run watch` +- Full repo check: `bun run check` +- Typecheck only: `bun run typecheck` +- Unit tests: `bun run test` +- Smoke e2e: `bun run test:e2e` +- Full e2e: `bun run test:e2e:full` +- Dev-runtime e2e: `bun run test:e2e:dev` +- E2E coverage validation: `bun run check:e2e:coverage` +- Autofix lint and format: `bun run fix` + +Production builds write the unpacked extension output to `build/`. + +## Local Browser Loading + +- Chrome and Edge: load the unpacked extension from `build/`. +- Firefox: open `about:debugging`, choose "This Firefox", then load `build/manifest.json`. + +## Versioning + +- Browser manifests live in: + - `platform/chrome/manifest.json` + - `platform/firefox/manifest.json` + - `platform/edge/manifest.json` +- `package.json` is the source of truth for the extension version. +- Prefer `bun run bump` for version bumps. It runs `bun pm version`, which triggers the Bun `version` lifecycle and syncs the browser manifests through `scripts/update-manifest-version.cjs`. +- Do not hand-edit manifest versions in `platform/*/manifest.json`. + +## Release-Safe Defaults + +- If a change affects runtime behavior, run the expanded e2e suite described in [testing.md](testing.md). +- If a change affects docs or workflows, keep [`README.md`](../../README.md) and [`CONTRIBUTING.md`](../../CONTRIBUTING.md) aligned with the same command surface. + +## PR Notes + +- Summarize the user-visible impact. +- List the tests you ran. +- If a change affects runtime behavior, add or update tests. +- If a change affects UI, include screenshots when they help reviewers. diff --git a/docs/agents/runtime-features.md b/docs/agents/runtime-features.md new file mode 100644 index 00000000..1969724e --- /dev/null +++ b/docs/agents/runtime-features.md @@ -0,0 +1,55 @@ +# Runtime Feature Workflows + +This guide covers the repo-specific workflows most likely to break runtime behavior if they are changed casually. + +## Prediction and Messaging + +High-level flow: + +1. The content script observes typing and requests predictions through runtime messaging. +2. The background layer routes the message and runs prediction. +3. The background layer responds to the correct tab and frame. +4. The content script renders suggestions and handles acceptance. + +If you change message shapes: + +- Update `src/core/domain/messageTypes.d.ts`. +- Update related constants in `src/core/domain/constants.ts`. +- Update the background routers and handlers under `src/adapters/chrome/background/router/**`. +- Update the content-script message handling under `src/adapters/chrome/content-script/**`. + +## Predictor Constraints + +- Production store builds are Presage-only. +- WebLLM is allowed only in development and debug builds. +- Do not make WebLLM required for normal operation. +- Preserve safe fallbacks when the AI predictor is unavailable or times out. +- Avoid expanding the network surface area in production builds. + +## Text Expansions and Dynamic Variables + +Text expansion behavior is split between local domain resolution and browser-context-aware expansion. + +- Local dynamic variables live in `src/core/domain/variables.ts`. +- Browser-context-aware expansion lives in `src/adapters/chrome/background/TemplateExpander.ts`. + +When adding a new variable: + +1. Add it to `resolveDynamicVariable(...)` in `src/core/domain/variables.ts` if it can be computed locally. +2. Extend `TemplateExpander.createResolver(...)` if it needs tab, title, URL, or other browser context. +3. Add or update tests for the new behavior. + +## Settings Changes + +When adding a user-facing setting: + +- Add a key or constant in `src/core/domain/constants.ts` if runtime logic depends on it. +- Wire it through the relevant repositories in `src/core/application/repositories/**`. +- Include it in runtime config assembly when needed, usually in `src/adapters/chrome/background/config/ConfigAssembler.ts`. +- Update the popup or settings UI and any defaults or migrations that keep older stored settings compatible. + +## Logging + +- Production logging should stay minimal, typically warn and error only. +- Do not log full user text content. +- Guard extra debug logging behind development mode or the existing logging level controls. diff --git a/docs/agents/testing.md b/docs/agents/testing.md new file mode 100644 index 00000000..ee89c490 --- /dev/null +++ b/docs/agents/testing.md @@ -0,0 +1,58 @@ +# Testing and Coverage Policy + +Testing expectations depend on what changed. Use the smallest suite that still proves the behavior, then add the required broader suites when runtime behavior moves. + +## Test Commands + +- Unit tests: `bun run test` +- Smoke e2e: `bun run test:e2e` +- Full regression e2e: `bun run test:e2e:full` +- Dev-runtime e2e: `bun run test:e2e:dev` +- Coverage matrix validation: `bun run check:e2e:coverage` + +## Baseline Before a PR + +Run these for every PR: + +- `bun run check` +- `bun run test` +- `bun run test:e2e` +- `bun run check:e2e:coverage` + +## Conditional Suites + +- If runtime or end-to-end behavior changed, also run: + - `bun run test:e2e:full` + - `bun run test:e2e:full --platform=firefox` +- If development-mode runtime hooks or toggles changed, also run: + - `bun run test:e2e:dev` + - `bun run test:e2e:dev --platform=firefox` +- Recommended cross-browser smoke validation before PR: + - `bun run test:e2e --platform=firefox` + +## Smoke Runtime Expectations + +- `bun run test:e2e` defaults to `--platform=chrome`. +- Target smoke runtime is `<=10s` wall-time for both: + - `bun run test:e2e --platform=chrome` + - `bun run test:e2e --platform=firefox` +- CI reports smoke runtime regressions but does not fail solely for exceeding the target. + +## Coverage Matrix Policy + +- Coverage parity is behavior-based, not test-count-based. +- When behavior is added, removed, or moved across unit, integration, and e2e coverage, update: + - `tests/e2e/coverage-matrix.json` + - `tests/e2e/coverage-baseline-ids.json` +- Validate the mapping with `bun run check:e2e:coverage`. + +## Architecture-Sensitive Tests + +- Routing changes often need updates in `tests/background.routing.test.ts`. +- Content runtime changes often need updates in: + - `tests/content_script.behavior.test.ts` + - `tests/content_script.watchdog.test.ts` + +## Scoped Test Overrides + +- When editing files under `tests/**`, also follow [`tests/AGENTS.override.md`](../../tests/AGENTS.override.md).