# Contributing to GLM Usage Monitor

Thanks for considering a contribution! This is a small, dependency-free browser
extension, so getting set up is quick. The project is open source under the
[MIT license](LICENSE), and all contributions will be licensed the same way.

## Project layout

| Path | Role |
|---|---|
| `manifest.json` | MV3 manifest — the single source of permissions and metadata |
| `background.js` | Service worker: polling, token-auth fetch, response mapping, badge |
| `popup.{html,css,js}` | Toolbar popup UI |
| `options.{html,css,js}` | Settings: key, platform, interval, test connection |
| `icons/` | Toolbar icons (`icon.svg` source + generated PNGs) |
| `dev/make-icons.py` | Regenerate the PNG icons from the SVG source (needs ImageMagick + Python) |
| `dev/test-raw.mjs` | Standalone Node script to dump raw monitor responses (great for debugging API shape changes) |
| `scripts/validate.mjs` | Manifest + packaging sanity checks (run locally and in CI) |

## Development setup

There is **no build step and no dependencies to install** — the JavaScript in
the repo is exactly what runs in the browser.

1. Clone the repo.
2. Open your browser's extensions page and enable **Developer mode**:
   - Brave: `brave://extensions` · Chrome: `chrome://extensions` · Edge: `edge://extensions`
3. **Load unpacked** → select the repo root (the folder containing `manifest.json`).
4. After any change to `background.js`, click **reload** on the extension card
   (service workers need a restart). Popup/options pick up on the next open.

To point it at your own account, open **Settings** in the popup and paste your
GLM Coding Plan key (the same value you use as `ANTHROPIC_AUTH_TOKEN`). Use
**Test connection** to confirm.

## Validating your changes

Run the same checks CI runs, before pushing:

```sh
# Syntax-check every JS file (catches typos / unbalanced braces)
for f in background.js popup.js options.js scripts/validate.mjs dev/test-raw.mjs; do node --check "$f"; done

# Manifest + packaging checks (name/description lengths, version, referenced files exist)
node scripts/validate.mjs
```

CI (`.github/workflows/ci.yml`) runs both on every push and pull request.

## Code style & conventions

- **Match the surrounding code** — naming, formatting, and comment density.
  No linter is configured; keep it readable.
- **Never use `innerHTML`** with API data — always `.textContent`. The
  extension's hardening depends on this; see [SECURITY.md](SECURITY.md).
- **Keep permissions minimal.** Anything that widens `host_permissions` or adds
  `cookies` / `tabs` / `<all_urls>` / `webRequest` / content scripts /
  `externally_connectable` is security-sensitive and must be discussed in an
  issue first. See [SECURITY.md](SECURITY.md) for the threat model.
- **Be null-safe** when parsing the API. Z.AI / ZHIPU may omit fields (for
  example, token windows sometimes return only a percentage with no `total`).
  A missing value should render `—`, not throw.

## Debugging the API

If the response shapes change, dump the raw data without the extension in the
way:

```sh
ZAI_API_KEY=your-coding-plan-key node dev/test-raw.mjs
```

The extension's parsing is deliberately defensive, so a changed field degrades
to `—` rather than crashing.

## Pull requests

1. Open an issue first for anything beyond a small fix, so we can align on
   approach.
2. Keep PRs focused — one logical change per PR.
3. Make sure `node --check` and `node scripts/validate.mjs` pass locally.
4. Reference the issue in the PR description and note any behavior change.

## Releasing (maintainers)

1. Bump `version` in `manifest.json` and add a `CHANGELOG.md` entry.
2. Run the validator and `node --check`.
3. Build the store zip (see `store/LISTING.md`), excluding `dev/`, `research/`,
   and docs.
4. Upload to the Chrome Web Store developer dashboard and update the listing.

## Security issues

Do **not** open a public issue for security problems. See [SECURITY.md](SECURITY.md)
for how to report privately.
