From dac297ee4cfd93c8eedec51c0607fb98a10364dc Mon Sep 17 00:00:00 2001 From: Adelaida Diaz-Roa Date: Wed, 13 May 2026 11:58:46 -0500 Subject: [PATCH] feat: install ping on SessionStart (anonymous, opt-out via MYCELIUM_NO_PING) --- README.md | 18 +++++++++++++++++ hooks/hooks.json | 14 +++++++++++++ hooks/install-ping.py | 47 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+) create mode 100644 hooks/hooks.json create mode 100755 hooks/install-ping.py diff --git a/README.md b/README.md index b08cb887..d11bc9c0 100644 --- a/README.md +++ b/README.md @@ -216,6 +216,24 @@ Forked from [@blader/humanizer](https://github.com/blader/humanizer). Upstream c - **2.0.0** - Complete rewrite based on raw Wikipedia article content - **1.0.0** - Initial release + +## Telemetry + +This plugin sends a single anonymous install signal to `myceliumai.co` the first time it loads in a Claude Code session on a given machine. + +**What is sent:** +- Plugin name (e.g. `slack-mcp`) +- Plugin version (e.g. `0.1.0`) + +**What is NOT sent:** +- No user identifiers, names, emails, tokens, or API keys +- No file paths, message content, or anything from your work +- No IP address is stored after dedup processing + +**Why:** Helps the maintainer know which plugins people actually install, so attention goes to the ones that get used. + +**Opt out:** Set the environment variable `MYCELIUM_NO_PING=1` before launching Claude Code. The hook will skip the network call entirely. Already-pinged installs leave a sentinel at `~/.mycelium/onboarded-` — delete it if you want to reset state. + ## License MIT diff --git a/hooks/hooks.json b/hooks/hooks.json new file mode 100644 index 00000000..0ca58055 --- /dev/null +++ b/hooks/hooks.json @@ -0,0 +1,14 @@ +{ + "hooks": { + "SessionStart": [ + { + "hooks": [ + { + "type": "command", + "command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/install-ping.py" + } + ] + } + ] + } +} diff --git a/hooks/install-ping.py b/hooks/install-ping.py new file mode 100755 index 00000000..0442a60c --- /dev/null +++ b/hooks/install-ping.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 +"""One-time install signal to myceliumai.co. + +Idempotent (one sentinel per plugin per machine), silent, fire-and-forget. +Sends ONLY plugin name + version. No PII, no IP storage post-dedup. + +Opt out by setting environment variable MYCELIUM_NO_PING=1 before launching +Claude Code. See README "Telemetry" section for details. +""" +import json +import os +import sys +import urllib.request +from pathlib import Path + +PLUGIN_NAME = "humanizer" +VERSION = "3.0.0" + + +def main(): + # Opt-out via env var + if os.environ.get("MYCELIUM_NO_PING"): + return 0 + sentinel_dir = Path.home() / ".mycelium" + sentinel = sentinel_dir / f"onboarded-{PLUGIN_NAME}" + if sentinel.exists(): + return 0 + try: + sentinel_dir.mkdir(exist_ok=True) + sentinel.touch() + except Exception: + return 0 + try: + data = json.dumps({"plugin": PLUGIN_NAME, "version": VERSION}).encode() + req = urllib.request.Request( + "https://myceliumai.co/api/install", + data=data, + headers={"Content-Type": "application/json"}, + ) + urllib.request.urlopen(req, timeout=3).read() + except Exception: + pass + return 0 + + +if __name__ == "__main__": + sys.exit(main())