Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 13 additions & 12 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# AGENTS

## Project Overview
Write Wall is a Chrome Extension (Manifest V3) that provides a synced text pad backed by `chrome.storage.sync` so text is shared across the signed-in Chrome account. The UI is a single page (`src/html/index.html`) with a textarea and a byte counter; logic lives in `src/main.ts` and background logic in `src/service_worker.ts`.
Write Wall is a Chrome Extension (Manifest V3) that provides a synced text pad backed by `chrome.storage.sync` so text is shared across the signed-in Chrome account. The UI is a single page (`public/html/index.html`) with a textarea and a byte counter; logic lives in `src/main.ts` and background logic in `src/service_worker.ts`.

## Tech Stack
- TypeScript (ES2024 target, strict mode)
- Webpack + ts-loader (build)
- Vite (build)
- Vitest (tests, `*.spec.ts` naming)
- Biome (lint + format)
- Husky (pre-commit: lint + test)
Expand All @@ -16,10 +16,11 @@ Write Wall is a Chrome Extension (Manifest V3) that provides a synced text pad b
- `src/main.ts`: UI logic, reads/writes synced text, throttles writes to respect sync quotas.
- `src/service_worker.ts`: MV3 service worker, opens `html/index.html` when the action icon is clicked.
- `src/utils.ts`: Shared utilities (throttle function).
- `src/html/index.html`: Extension UI page.
- `src/css/main.css`: UI styles (dark theme, CSS custom properties).
- `public/html/index.html`: Extension UI page.
- `public/css/main.css`: UI styles (dark theme, CSS custom properties).
- `public/images/`: Extension icons (copied verbatim to `dist/` by Vite).
- `public/manifest.json`: MV3 manifest (source of truth, copied to `dist/` on build).
- `webpack/webpack.config.cjs`: Build config, emits bundles to `dist/` and copies static assets.
- `vite.config.ts`: Build config, emits bundles to `dist/` and copies `public/` assets.
- `build.cjs`: Packages `dist/` into `app.zip` for release.
- `dist/`: Build output (generated, do not edit).

Expand All @@ -30,11 +31,11 @@ Write Wall is a Chrome Extension (Manifest V3) that provides a synced text pad b
| UI behavior / event handlers | `src/main.ts` |
| Background / tab management | `src/service_worker.ts` |
| Shared utilities | `src/utils.ts` |
| Styles | `src/css/main.css` |
| HTML structure | `src/html/index.html` |
| Static assets / icons | `src/images/` |
| Styles | `public/css/main.css` |
| HTML structure | `public/html/index.html` |
| Static assets / icons | `public/images/` |
| Manifest changes | `public/manifest.json` |
| Build config | `webpack/webpack.config.cjs` |
| Build config | `vite.config.ts` |
| New test | `src/<module>.spec.ts` |

## Development Workflow
Expand All @@ -48,8 +49,8 @@ Write Wall is a Chrome Extension (Manifest V3) that provides a synced text pad b
- `pnpm test`: Run Vitest tests.
- `pnpm lint`: Run Biome checks.
- `pnpm lint:fix`: Run Biome with auto-fix.
- `pnpm develop`: Webpack build in watch mode.
- `pnpm build`: Webpack build + package `dist/` into `app.zip`.
- `pnpm develop`: Vite build in watch mode.
- `pnpm build`: Vite build + package `dist/` into `app.zip`.
- `pnpm type:check`: Run TypeScript type checking.
- `pnpm prepare`: Install Husky hooks.
- `pnpm check-updates`: Run npm-check-updates in interactive mode.
Expand All @@ -63,7 +64,7 @@ Write Wall is a Chrome Extension (Manifest V3) that provides a synced text pad b

## Common Pitfalls
- Sync quota is 8,192 bytes total. Test near-limit behavior.
- Webpack uses `tsconfig.build.json`, not `tsconfig.json`. Build errors may differ from editor errors.
- Vite uses esbuild for transpilation (not `tsconfig.build.json`). Type checking is separate (`pnpm type:check`).
- Pre-commit hook runs lint + test. Fix with `pnpm lint:fix` before retrying.
- Test environment is Node (not browser). Chrome APIs must be mocked in tests.

Expand Down
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

### Changed

- Replace Webpack with Vite for build tooling
- Move static assets (`css/`, `html/`, `images/`) from `src/` to `public/`
- Output ESM bundles instead of IIFE (required for Vite multi-entry builds)
- Add `"type": "module"` to manifest background service worker

### Removed

- Remove `webpack`, `webpack-cli`, `ts-loader`, `copy-webpack-plugin` dependencies
- Remove `webpack/` directory

## [2.5.0] - 2026-01-27

### Added
Expand Down
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

## Architecture Quick Reference

- UI page: `src/html/index.html` with logic in `src/main.ts`
- UI page: `public/html/index.html` with logic in `src/main.ts`
- Service worker: `src/service_worker.ts` (tab management only)
- Shared utilities: `src/utils.ts` (throttle function)
- Sync storage key: `v2` in `chrome.storage.sync` (8,192 byte limit)
Expand Down Expand Up @@ -33,7 +33,7 @@ if (copyButtonEl) {

1. **Tests fail**: Run `pnpm test` locally. Tests mock Chrome APIs; check mock setup in spec files.
2. **Lint errors**: Run `pnpm lint:fix`. Biome config is in `biome.json`.
3. **Build issues**: Check `webpack/webpack.config.cjs`. Uses `tsconfig.build.json` (not `tsconfig.json`).
3. **Build issues**: Check `vite.config.ts`. Vite uses esbuild for transpilation; type checking is separate (`pnpm type:check`).
4. **Version mismatch**: Both `package.json` and `public/manifest.json` must match. Use `pnpm verify-version`.

## CI/CD Details
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ pnpm verify-version

- Avoid editing `dist/` directly (generated output).
- `chrome.storage.sync` is quota-limited; preserve write throttling.
- The UI is `src/html/index.html`; logic is in `src/main.ts`.
- The UI is `public/html/index.html`; logic is in `src/main.ts`.

## Communication

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ signing in to Chrome.

## How It Works

- The UI lives in `src/html/index.html` with logic in `src/main.ts`
- The UI lives in `public/html/index.html` with logic in `src/main.ts`
- Text is saved to `chrome.storage.sync` under the `v2` key
- Writes are throttled to respect Chrome sync quotas
- The byte counter uses `chrome.storage.sync.getBytesInUse`
Expand Down Expand Up @@ -55,7 +55,7 @@ signing in to Chrome.

### Common Scripts

- `pnpm develop`: Webpack build in watch mode
- `pnpm develop`: Vite build in watch mode
- `pnpm build`: Production build + `app.zip` packaging
- `pnpm lint`: Biome checks
- `pnpm lint:fix`: Biome auto-fix
Expand Down
Binary file modified app.zip
Binary file not shown.
5 changes: 2 additions & 3 deletions biome.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"$schema": "https://biomejs.dev/schemas/2.3.12/schema.json",
"$schema": "https://biomejs.dev/schemas/2.3.14/schema.json",
"vcs": { "enabled": true, "clientKind": "git", "useIgnoreFile": true },
"files": { "includes": ["**", "!!**/dist", "!!**/coverage"] },
"formatter": {
Expand Down Expand Up @@ -122,8 +122,7 @@
"!.idea/*",
"!dist/*",
"!node_modules/*",
"!*.cjs",
"!webpack/*"
"!*.cjs"
]
},
"javascript": {
Expand Down
19 changes: 9 additions & 10 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Write Wall is a Chrome Extension built on Manifest V3. It provides a synced text

## Extension Components

### UI Page (`src/html/index.html`)
### UI Page (`public/html/index.html`)

Single HTML page rendered when the extension action icon is clicked. Contains:
- `<textarea id="text">` - main editing area
Expand Down Expand Up @@ -57,17 +57,17 @@ This yields roughly a 4-second delay between sync writes. The `throttle` utility

## Build Pipeline

### Webpack (`webpack/webpack.config.cjs`)
### Vite (`vite.config.ts`)

- **Entry points**: `src/main.ts` and `src/service_worker.ts`
- **Output**: `dist/` directory with `main.bundle.js` and `service_worker.bundle.js`
- **Loader**: `ts-loader` using `tsconfig.build.json`
- **Copy plugin**: copies `public/` (manifest, icons), `src/html/`, `src/css/`, `src/images/` into `dist/`
- **Mode**: production with inline source maps
- **Transpilation**: esbuild (built into Vite), targeting ES2024
- **Static assets**: `public/` directory (manifest, HTML, CSS, icons) copied verbatim to `dist/`
- **Mode**: production, no source maps

### Packaging (`build.cjs`)

After webpack, `build.cjs` uses `adm-zip` to create `app.zip` from `dist/` for Chrome Web Store submission.
After Vite builds, `build.cjs` uses `adm-zip` to create `app.zip` from `dist/` for Chrome Web Store submission.

## CI/CD

Expand Down Expand Up @@ -99,13 +99,12 @@ src/
service_worker.spec.ts - Tests for service worker
utils.spec.ts - Tests for throttle utility
verify-version.spec.ts - Tests for version verification
public/
manifest.json - MV3 manifest (source of truth)
html/index.html - Extension UI page
css/main.css - Styles (dark theme, CSS variables)
images/ - Extension icons (16, 19, 48, 64, 128, 512)
public/
manifest.json - MV3 manifest (source of truth)
webpack/
webpack.config.cjs - Build configuration
vite.config.ts - Build configuration
scripts/
verify-version.cjs - Checks package.json and manifest.json version parity
dist/ - Build output (generated, do not edit)
Expand Down
20 changes: 10 additions & 10 deletions docs/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ pnpm install # install dependencies

| Script | Command | Description |
|--------|---------|-------------|
| Develop | `pnpm develop` | Webpack watch mode, rebuilds on change |
| Build | `pnpm build` | Production webpack build + `app.zip` |
| Develop | `pnpm develop` | Vite watch mode, rebuilds on change |
| Build | `pnpm build` | Production Vite build + `app.zip` |
| Test | `pnpm test` | Run Vitest test suite |
| Lint | `pnpm lint` | Biome checks (errors only) |
| Lint fix | `pnpm lint:fix` | Biome auto-fix |
Expand All @@ -29,10 +29,10 @@ pnpm install # install dependencies

## Local Development Loop

1. Run `pnpm develop` to start webpack in watch mode
1. Run `pnpm develop` to start Vite in watch mode
2. Open `chrome://extensions`, enable Developer mode
3. Click "Load unpacked" and select the `dist/` directory
4. Make changes to `src/` files; webpack rebuilds automatically
4. Make changes to `src/` files; Vite rebuilds automatically
5. Click the reload button on the extension card in `chrome://extensions`

## Testing
Expand All @@ -55,12 +55,12 @@ Key settings:
- Indent: 2 spaces, LF line endings
- Line width: 100
- Single quotes, trailing commas, semicolons always
- Excludes: `.github/`, `.husky/`, `.idea/`, `dist/`, `node_modules/`, `*.cjs`, `webpack/`
- Excludes: `.github/`, `.husky/`, `.idea/`, `dist/`, `node_modules/`, `*.cjs`

## TypeScript Configuration

- `tsconfig.json`: Base config, strict mode, target ES2024, ESNext modules
- `tsconfig.build.json`: Used by ts-loader for webpack builds
- `tsconfig.build.json`: Excludes test and config files from type-checked source
- `tsconfig.test.json`: Used by Vitest

Type definitions: `@types/chrome` for Chrome extension APIs.
Expand Down Expand Up @@ -104,9 +104,9 @@ type(scope)!: subject
| UI behavior / event handlers | `src/main.ts` |
| Background / tab management | `src/service_worker.ts` |
| Shared utilities | `src/utils.ts` |
| Styles | `src/css/main.css` |
| HTML structure | `src/html/index.html` |
| Static assets / icons | `src/images/` |
| Styles | `public/css/main.css` |
| HTML structure | `public/html/index.html` |
| Static assets / icons | `public/images/` |
| Manifest changes | `public/manifest.json` |
| Build config | `webpack/webpack.config.cjs` |
| Build config | `vite.config.ts` |
| New test | `src/<module>.spec.ts` |
2 changes: 1 addition & 1 deletion docs/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Do **not** use `nvm` for this project.

### Build output is stale after changes

Webpack watch mode (`pnpm develop`) rebuilds on file changes, but you must still manually reload the extension in `chrome://extensions`. Click the reload icon on the Write Wall extension card.
Vite watch mode (`pnpm develop`) rebuilds on file changes, but you must still manually reload the extension in `chrome://extensions`. Click the reload icon on the Write Wall extension card.

### Tests fail with Chrome API errors

Expand Down
19 changes: 8 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,30 @@
"test:coverage:summary": "vitest run --coverage --coverage.reporter=text-summary",
"lint": "biome check --diagnostic-level=error",
"lint:fix": "biome check --write --diagnostic-level=error",
"develop": "webpack --config webpack/webpack.config.cjs --watch",
"build": "webpack --config webpack/webpack.config.cjs && node build.cjs",
"develop": "vite build --watch",
"build": "vite build && node build.cjs",
"type:check": "tsc --noEmit",
"verify-version": "node scripts/verify-version.cjs",
"prepare": "husky",
"check-updates": "pnpm ncu -i"
},
"packageManager": "pnpm@10.28.1+sha512.7d7dbbca9e99447b7c3bf7a73286afaaf6be99251eb9498baefa7d406892f67b879adb3a1d7e687fc4ccc1a388c7175fbaae567a26ab44d1067b54fcb0d6a316",
"packageManager": "pnpm@10.28.2+sha512.41872f037ad22f7348e3b1debbaf7e867cfd448f2726d9cf74c08f19507c31d2c8e7a11525b983febc2df640b5438dee6023ebb1f84ed43cc2d654d2bc326264",
"engineStrict": true,
"engines": {
"node": "^22.0.0 || ^24.0.0"
},
"devDependencies": {
"@biomejs/biome": "2.3.12",
"@biomejs/biome": "2.3.14",
"@testing-library/user-event": "^14.6.1",
"@types/chrome": "^0.1.36",
"@vitest/coverage-v8": "^4.0.18",
"adm-zip": "^0.5.16",
"copy-webpack-plugin": "^13.0.1",
"corepack": "^0.34.6",
"globals": "^17.1.0",
"globals": "^17.3.0",
"husky": "^9.1.7",
"npm-check-updates": "^19.3.1",
"ts-loader": "^9.5.4",
"npm-check-updates": "^19.3.2",
"typescript": "^5.9.3",
"vitest": "^4.0.18",
"webpack": "^5.104.1",
"webpack-cli": "^6.0.1"
"vite": "^7.3.1",
"vitest": "^4.0.18"
}
}
Loading