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
29 changes: 0 additions & 29 deletions .github/ISSUE_TEMPLATE/bug_report.md

This file was deleted.

37 changes: 37 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Bug report
description: Something in MeterX doesn't work or shows the wrong result
labels: [bug]
body:
- type: dropdown
id: browser
attributes:
label: Browser
options: [Firefox, Microsoft Edge, Opera, Chrome (unpacked), Brave or Vivaldi (unpacked), Other]
validations:
required: true
- type: input
id: versions
attributes:
label: Browser and MeterX versions
description: MeterX's version is at the bottom of its settings page.
placeholder: Firefox 158.0.1, MeterX 2027.0.1
validations:
required: true
- type: dropdown
id: server
attributes:
label: Test server
options: [Default (Cloudflare), Custom server]
- type: textarea
id: steps
attributes:
label: What you did and what happened
description: Steps to reproduce, what you expected, and what you saw. A screenshot helps.
validations:
required: true
- type: textarea
id: console
attributes:
label: Console errors
description: "Firefox: about:debugging, This Firefox, Inspect next to MeterX. Chromium: the extensions page, service worker link."
render: text
8 changes: 8 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: Question or idea to discuss
url: https://github.com/ajithakdev/meterx/discussions
about: Ask how something works or float an idea before opening an issue.
- name: Security problem
url: https://github.com/ajithakdev/meterx/security/advisories/new
about: Report it privately, not in a public issue.
15 changes: 0 additions & 15 deletions .github/ISSUE_TEMPLATE/feature_request.md

This file was deleted.

15 changes: 15 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: Feature request
description: Suggest something MeterX should measure, show or do
labels: [enhancement]
body:
- type: textarea
id: problem
attributes:
label: What are you trying to do?
description: The problem first; a solution is welcome but optional.
validations:
required: true
- type: textarea
id: idea
attributes:
label: Your idea
16 changes: 15 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,19 @@ All notable changes to MeterX are documented here. The format follows [Keep a Ch

## [Unreleased]

## [2027.0.1] - 2026-10-27

### Fixed
- Updated the PDF export's libraries (DOMPurify 3.4.17, fflate 0.8.3) and the self-host server's Express dependencies (body-parser 2.4.0 and others) to versions without known security advisories

### Added
- Appearance setting: Match system, Light or Dark. Firefox gives extension pages the system's light or dark setting rather than Firefox's own theme, so the popup and sidebar could disagree with the browser; now you can pick
- `docs/STORE-CHECKLIST.md`: what to check before each store upload, built from the Firefox, Edge, Opera and Chrome store policies
- `SECURITY.md` with what MeterX trusts and how to report privately, issue forms for bugs and features, and `npm run check:docs`, which checks the docs' sections, links, spelling and headings as part of `npm test`

### Changed
- README rewritten around install, privacy and data, how a test works and a FAQ, with dark-mode images and live store user, download and star counts; CONTRIBUTING covers loading the extension in Firefox and the pull request rules

## [2027.0.0] - 2026-10-27

### Added
Expand Down Expand Up @@ -173,7 +186,8 @@ First store release, store version 2026.3.19.1 ("Major Rewrite One").
- Express.js server with test file generation
- Simple popup UI

[Unreleased]: https://github.com/ajithakdev/meterx/compare/v2027.0.0...HEAD
[Unreleased]: https://github.com/ajithakdev/meterx/compare/v2027.0.1...HEAD
[2027.0.1]: https://github.com/ajithakdev/meterx/compare/v2027.0.0...v2027.0.1
[2027.0.0]: https://github.com/ajithakdev/meterx/compare/v2026.2.0...v2027.0.0
[2026.2.0]: https://github.com/ajithakdev/meterx/compare/v2026.1.0...v2026.2.0
[2026.1.0]: https://github.com/ajithakdev/meterx/compare/v2026.0.0...v2026.1.0
Expand Down
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,14 @@ scripts/ package-stores.mjs for store uploads
```

- **Extension** (`apps/extension`): esbuild bundles `src/background/index.ts` (service worker; measurement in `background/runner.ts` and `measure.ts`) and `src/pages/{popup,sidepanel,options}.ts`. Pages are thin: they send `chrome.runtime` messages (`startTest`, `cancelTest`, `getState`, `rescheduleTests`) and listen for `testProgress` / `testComplete` / `testError`. Browser-only helpers live in `src/lib/` (history, isp, export downloads, ui, tooltips, browser).
- **Site** (`apps/site`): `build.mjs` copies `static/`, fills the `<!-- header -->` and `<!-- footer -->` partials, and copies the built extension pages into `dist/app/` with `src/demo-shim.ts` injected before their scripts. The shim stands in for the extension APIs with labelled sample data (`src/sample.ts`); the home page drives the popup's sample test from scroll through `postMessage`. The scroll engine is `static/sc/` (scroll-craft, unmodified).
- **Site** (`apps/site`): `build.mjs` copies `static/`, fills the `<!-- header -->` and `<!-- footer -->` partials, and copies the built extension pages into `dist/app/` with `src/demo-shim.ts` injected before their scripts. The shim stands in for the extension APIs with labeled sample data (`src/sample.ts`); the home page drives the popup's sample test from scroll through `postMessage`. The scroll engine is `static/sc/` (scroll-craft, unmodified).
- **Worker and server**: same API, kept in sync. CORS answers extension origins, the site origin and localhost dev ports (`isAllowedOrigin` in shared).

**Server API contract**: `GET/HEAD /ping`, `GET /test-file/{1|5|10|25}MB.bin`, `POST /upload` (`application/octet-stream`, body discarded), `GET /health`, `GET /ip`. Sizes come from `ALLOWED_SIZES_MB` / `TEST_FILE_RE` in shared. Responses send `Timing-Allow-Origin` so the extension can read DNS timing.

**Measurement**: 4 download and 3 upload streams for a fixed time, ramp-up and tail trimmed, loaded-latency pings for the bufferbloat grade. The rate limits in the worker and server are sized for this burst; raise them if you add streams.

**Storage**: `chrome.storage.sync` holds settings (`serverUrl`, `ispPlan`, `scheduleMinutes`, `notifyOnDrop`); `chrome.storage.local` holds `history` (capped at 200). Scheduled tests use `chrome.alarms`.
**Storage**: `chrome.storage.sync` holds settings (`serverUrl`, `ispPlan`, `scheduleMinutes`, `notifyOnDrop`, `theme`); `chrome.storage.local` holds `history` (capped at 200). Scheduled tests use `chrome.alarms`.

Custom server URLs need a runtime host-permission grant (`optional_host_permissions`); the settings page requests it.

Expand Down
106 changes: 41 additions & 65 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,90 +1,66 @@
# Contributing to MeterX

Here's how to get set up and contribute.
Bug reports, test reports from other browsers and fixes are all welcome. Start with a [good first issue](https://github.com/ajithakdev/meterx/labels/good%20first%20issue), or ask in [Discussions](https://github.com/ajithakdev/meterx/discussions) before a large change.

## Dev Setup
## Setup

You need Node 22 or newer and npm.

```bash
git clone https://github.com/ajithakdev/meterx.git
cd meterx
npm install
npm run build
```

## Load the Extension

1. Go to `chrome://extensions` (or `edge://extensions`)
2. Enable "Developer mode"
3. Click "Load unpacked"
4. Select `apps/extension/dist/`

Rebuild with `npm run build` after changes, then hit reload on the extensions page.

## Run the Worker Locally

```bash
cd services/worker
npx wrangler dev
npm run dev:ext # builds the extension, runs a local test server on http://localhost:8787
```

This starts a local Cloudflare Worker on `http://localhost:8787`. Update the server URL in the extension settings to point here.
`npm run dev:site` builds and serves the website on http://localhost:8788 instead.

## Run the Server Locally
## Load the extension

```bash
npm start
```
- Chromium (Chrome, Edge, Opera, Brave): open `chrome://extensions`, turn on Developer mode, choose Load unpacked and pick `apps/extension/dist/`.
- Firefox: run `npm run package`, then open `about:debugging`, choose This Firefox, Load Temporary Add-on, and pick `release/meterx-<version>-firefox.zip`. `dist/` has the Chromium manifest, so Firefox needs the packaged zip.

Starts the Express.js self-host server. Useful for LAN testing or when you don't want to touch the worker.
To test against your local server, set Custom server to `http://localhost:8787` in MeterX settings. After a change, run `npm run build -w @meterx/extension` and reload the extension.

## Project Structure
## Project layout

```text
apps/extension Browser extension (TypeScript, Manifest V3, esbuild)
apps/extension the extension (TypeScript, Manifest V3, esbuild)
apps/site meterx.ajithakdev.com
services/worker Cloudflare Worker, the default test server
services/server Express server, for self-hosting
packages/shared Types, API constants and rules every part shares
services/server Express server with the same API, for self-hosting
packages/shared types, API constants and rules every part shares
packages/reports PDF, CSV and JSON builders
```

The full map is in [docs/CODEMAP.md](docs/CODEMAP.md).
Every file is listed in [docs/CODEMAP.md](docs/CODEMAP.md). The worker and the server share one API; change both together.

## Commands

| Command | What it does |
|---------|-------------|
| `npm install` | Install all workspace deps |
| `npm run build` | Build all packages |
| `npm start` | Run self-host server |
| `npm test` | Run all tests |
| `npm run lint` | ESLint check |
| `npm run lint:fix` | Auto-fix lint issues |
| `npm -w @meterx/server run test` | Run server tests only |
| `cd services/worker && npx wrangler dev` | Run worker locally |
| `cd services/worker && npx wrangler deploy` | Deploy worker to Cloudflare |

## Code Style

- TypeScript everywhere, no plain JS
- ESLint with strict rules, run `npm run lint` before committing
- Prefix unused parameters with `_`
- Keep functions short and focused
- Throw errors, don't return sentinel values
- No `any` unless absolutely necessary

## Pull Requests

1. Fork the repo, branch from `main`
2. Make your changes
3. Run `npm run lint && npm run build && npm test`: all must pass
4. Open a PR with a clear description of what changed and why
5. One approval required to merge

## Reporting Bugs

Open an issue with:
- Browser and version
- Steps to reproduce
- Expected vs actual behavior
- Console errors if applicable
| --- | --- |
| `npm run build` | Build the extension, site and server |
| `npm test` | Every workspace's tests, the scripts' tests and the docs check |
| `npm run lint` | ESLint for TypeScript, CSS and Markdown |
| `npm run check:docs` | Docs rules only: sections, links, spelling, headings |
| `npm run package` | Store zips in `release/` |
| `npm start` | Self-host server on port 3000 (after a build) |

## Code style

- TypeScript, strict. No `any` unless there is no other way.
- Keep pages thin: they send `chrome.runtime` messages, and measurement stays in `apps/extension/src/background/`.
- New logic gets a test next to it (`*.test.ts`).
- Prefix unused parameters with `_`.

## Pull requests

1. Branch from `main`.
2. Run `npm run lint && npm run build && npm test`. All three must pass.
3. Write commit messages with a conventional prefix (`feat:`, `fix:`, `docs:`, `chore:`, `refactor:`).
4. Add a line under `## [Unreleased]` in [CHANGELOG.md](CHANGELOG.md) for anything a user would notice.
5. Open the pull request with what changed and why, and how you tested it. Include a screenshot for UI changes.

## Reporting bugs

Use the [bug report form](https://github.com/ajithakdev/meterx/issues/new?template=bug_report.yml). It asks for your browser, versions and any console errors. Security problems go through [SECURITY.md](SECURITY.md).
Loading
Loading