You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* feat: anonymous opt-out telemetry (PostHog)
Add a thin telemetry layer that counts command usage anonymously. All
PostHog-specific code lives behind src/telemetry/index.ts so the backend
can be swapped in one file.
- Whitelist payload only: machine_id, scaffold_id, command name, mex_version,
os, node_version. No args, paths, file contents, repo names, IP, or geo
(disableGeoip is set so PostHog never derives location from the IP).
- Opt-out precedence: DO_NOT_TRACK=1, MEX_TELEMETRY=0, `mex config set
telemetry off`, else on. Dev-repo guard hard-disables when run from a clone
of mex itself, before any disk read.
- machine_id is a random UUID at ~/.mex/telemetry-id (0600), created only when
enabled. scaffold_id (from E1) is passed as a string only — never the
identity object — so scaffold_name/origin/upstream can't leak.
- Fire-and-forget: capture fires in a preAction hook (so process.exit commands
like `check` on drift are still counted); flush is best-effort and bounded;
a telemetry failure never blocks or changes a command's exit code.
- Transparency: `mex telemetry inspect` prints the exact would-be payload
without sending (and without minting the machine-id file); `mex telemetry
status` shows enabled/disabled + reason; one-time first-run notice to stderr.
- Tests never emit real events (vitest sets MEX_TELEMETRY=0).
- Docs: TELEMETRY.md + README link + CHANGELOG entry.
* fix(telemetry): address review on #74
- preAction no longer fires for the telemetry/config meta-commands, so
`mex telemetry inspect` sends no event and never creates the machine-id
file — it stays a pure audit surface even when telemetry is enabled.
- flush() now clears its race timer in a finally, so a fast flush can't
leave an 800ms timeout pending and delay process exit.
- Remove unused `constants` import in global-config.ts.
- Fix isDevRepo JSDoc: the bare `mex` package name is intentionally excluded.
- Make the "no I/O at import time" test real — it now re-evaluates the module
under a fresh HOME and asserts nothing is written, instead of passing
vacuously.
- TELEMETRY.md: drop the non-interactive auto-disable claim; CI usage is
counted (no TTY gate), so the doc matches the code.
Copy file name to clipboardExpand all lines: CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file.
5
5
## [Unreleased]
6
6
7
7
### Added
8
+
-**Anonymous telemetry** — opt-out usage counting via PostHog. Each command sends one event with only `machine_id`, `scaffold_id`, `command` name, `mex_version`, `os`, and `node_version` — no args, paths, file contents, repo names, IP, or location. Opt out with `DO_NOT_TRACK=1`, `MEX_TELEMETRY=0`, or `mex config set telemetry off`. Audit the exact payload with `mex telemetry inspect`; check state with `mex telemetry status`. Telemetry is disabled automatically when running from a clone of the mex repo. See [TELEMETRY.md](TELEMETRY.md).
8
9
-**Scaffold identity** — `.mex/config.json` now carries a stable `scaffold_id` (UUID v4), `scaffold_name`, and nullable `origin`/`upstream`. Generated at `mex setup` and silently backfilled for existing scaffolds on the next CLI invocation. New `getScaffoldIdentity()` export on the public API.
9
10
-**broken-link drift checker** — flags Markdown links in scaffold files whose local target file does not exist.
Copy file name to clipboardExpand all lines: README.md
+4Lines changed: 4 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -262,6 +262,10 @@ Optional settings live in `.mex/config.json`. Missing values fall back to defaul
262
262
}
263
263
```
264
264
265
+
## Telemetry
266
+
267
+
mex collects anonymous, opt-out usage data (command name, version, OS — never paths, args, file contents, IP, or personal data) to understand how the tool is used. Audit the exact payload with `mex telemetry inspect`, and opt out any time with `DO_NOT_TRACK=1`, `MEX_TELEMETRY=0`, or `mex config set telemetry off`. Full details: [TELEMETRY.md](TELEMETRY.md).
268
+
265
269
## Ecosystem
266
270
267
271
mex is provider-neutral. Integration guides, sponsored examples, and community recipes should be useful on their own, clearly labeled, and live in docs rather than silently changing the default experience.
mex collects **anonymous, opt-out** usage data so the maintainer can see how the
4
+
tool is actually used — which commands matter, roughly how many people use it,
5
+
and whether a project is used by a team. That's the entire purpose. There is no
6
+
advertising, no profiling, and no way to tie any data back to a person.
7
+
8
+
If you'd rather send nothing, see [How to opt out](#how-to-opt-out) — it's one
9
+
command or one environment variable.
10
+
11
+
## What is collected
12
+
13
+
Every time you run a `mex` command, **one** event is sent containing **exactly**
14
+
these fields and nothing else:
15
+
16
+
| Field | Example | What it is |
17
+
|-------|---------|------------|
18
+
|`machine_id`|`3f2a…` (random UUID) | A random ID generated once per machine. Not your username, hostname, or anything derived from you. |
19
+
|`scaffold_id`|`9b1c…` (random UUID) | A random ID for the mex scaffold (project). Only present when you run inside a scaffold. Lets us tell "one team on one project" apart from "one person on many machines." |
20
+
|`command`|`check`| The command **name only** — e.g. `check`, `sync`, `log`. |
21
+
|`mex_version`|`0.5.1`| The installed mex version. |
22
+
|`os`|`darwin`| The platform string (`darwin` / `linux` / `win32`). |
23
+
|`node_version`|`v22.17.1`| The Node.js version. |
24
+
25
+
You can see the literal payload that would be sent, at any time, without sending
26
+
anything:
27
+
28
+
```bash
29
+
mex telemetry inspect
30
+
```
31
+
32
+
## What is NEVER collected
33
+
34
+
-**No personal data** — no name, email, username, hostname, or git identity.
35
+
-**No IP address or location** — geolocation is explicitly disabled.
36
+
-**No command arguments, flags, or paths.**
37
+
-**No file names or file contents.**
38
+
-**No repository name or git remote URL.**
39
+
40
+
`machine_id` and `scaffold_id` are random UUIDs. They are **not** derived from
41
+
your path, repo, email, or anything identifying — they are just random numbers
0 commit comments