@extenshi/mcp 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bff.d.ts +24 -0
- package/dist/bff.d.ts.map +1 -1
- package/dist/bff.js +3 -0
- package/dist/bff.js.map +1 -1
- package/dist/extension-templates.d.ts +111 -0
- package/dist/extension-templates.d.ts.map +1 -0
- package/dist/extension-templates.js +182 -0
- package/dist/extension-templates.js.map +1 -0
- package/dist/index.js +16 -1
- package/dist/index.js.map +1 -1
- package/dist/startup.d.ts +63 -0
- package/dist/startup.d.ts.map +1 -0
- package/dist/startup.js +57 -0
- package/dist/startup.js.map +1 -0
- package/dist/telemetry.d.ts +9 -8
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/telemetry.js +23 -14
- package/dist/telemetry.js.map +1 -1
- package/dist/templates.d.ts +24 -0
- package/dist/templates.d.ts.map +1 -0
- package/dist/templates.js +56 -0
- package/dist/templates.js.map +1 -0
- package/dist/tools.d.ts +1 -1
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +144 -2
- package/dist/tools.js.map +1 -1
- package/package.json +1 -1
- package/scripts/postinstall.cjs +69 -15
package/scripts/postinstall.cjs
CHANGED
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
* and @extenshi/mcp (it figures out which one it is from its own package.json).
|
|
5
5
|
*
|
|
6
6
|
* Fires a single `cli_installed` / `mcp_installed` event when the package is
|
|
7
|
-
* installed as a real dependency
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* installed as a real dependency ON A MACHINE THAT HAS ALREADY ACCEPTED
|
|
8
|
+
* telemetry, so we can see adoption in PostHog. It is a standalone CommonJS
|
|
9
|
+
* script using ONLY Node built-ins (no posthog-node, no build step) so it can
|
|
10
|
+
* run the instant npm extracts the tarball.
|
|
10
11
|
*
|
|
11
12
|
* Hard rules (a postinstall that breaks `npm install` is unacceptable):
|
|
12
13
|
* - ALWAYS exits 0, even on any error — wrapped in try/catch + a hard timeout.
|
|
@@ -15,21 +16,58 @@
|
|
|
15
16
|
* It self-skips (no event, no network) when:
|
|
16
17
|
* - the package is NOT under node_modules — i.e. our own monorepo workspace
|
|
17
18
|
* install (tools/<pkg>), so dev installs never inflate adoption counts;
|
|
18
|
-
* -
|
|
19
|
-
*
|
|
19
|
+
* - ~/.extenshi/config.json does not hold "telemetry": true — consent must be
|
|
20
|
+
* RECORDED, not merely un-refused. A postinstall runs before the CLI can
|
|
21
|
+
* ask anything, so "no answer yet" is not permission (see the ACCEPTED-ONLY
|
|
22
|
+
* note below);
|
|
23
|
+
* - DO_NOT_TRACK is truthy or EXTENSHI_TELEMETRY is off;
|
|
20
24
|
* - CI is set (CI re-installs would massively inflate the count);
|
|
21
25
|
* - no ingestion key is configured.
|
|
22
26
|
*
|
|
23
|
-
* Privacy: sends only the package version, Node version, coarse os/arch,
|
|
24
|
-
* anonymous per-install UUID (the
|
|
25
|
-
* path, package contents, or
|
|
27
|
+
* Privacy: sends only the package version, Node version, coarse os/arch, a
|
|
28
|
+
* first-install-on-this-machine boolean, and an anonymous per-install UUID (the
|
|
29
|
+
* same id the runtime telemetry uses). Never any path, package contents, or
|
|
30
|
+
* user input.
|
|
31
|
+
*
|
|
32
|
+
* ACCEPTED-ONLY, and what that costs. Until 2026-08-13 this fired unless the
|
|
33
|
+
* user had actively opted out, which meant a first-ever install reported before
|
|
34
|
+
* anyone had been asked — the one place consent did not reach after the CLI
|
|
35
|
+
* grew a first-run question (tools/extenshi-cli/src/telemetry-consent.ts). The
|
|
36
|
+
* gate is now positive, and the consequences are deliberate:
|
|
37
|
+
* - a FIRST install never pings. Only the CLI's first-run question writes
|
|
38
|
+
* `telemetry: true`, and that happens on the first RUN, so the earliest
|
|
39
|
+
* ping is the next upgrade of an accepted machine.
|
|
40
|
+
* - @extenshi/mcp is headless and never prompts, so it can only ping on a
|
|
41
|
+
* machine where the CLI recorded consent into the shared config. Treat its
|
|
42
|
+
* install count as gone, not as a number that dropped.
|
|
43
|
+
* - `first_extenshi_install` is therefore ~always false now. It is kept so the
|
|
44
|
+
* event schema does not change under existing PostHog queries, not because
|
|
45
|
+
* it still measures anything.
|
|
46
|
+
*
|
|
47
|
+
* NB for anyone reading this as an adoption metric: it counts npm EXTRACTIONS,
|
|
48
|
+
* not users. Most of them are ecosystem scanners that install a new version once
|
|
49
|
+
* on a throwaway machine and never run the binary. The "did a client actually
|
|
50
|
+
* launch the server" signal is `mcp_server_started`, emitted from
|
|
51
|
+
* @extenshi/mcp's src/startup.ts — a relative path would be wrong in one of the
|
|
52
|
+
* two packages, since this file is vendored byte-identical into both.
|
|
26
53
|
*/
|
|
27
54
|
|
|
28
55
|
// Shared EU PostHog project key (114791) — public, write-only, already in our
|
|
29
56
|
// web bundles. Override with EXTENSHI_POSTHOG_KEY; empty disables the ping.
|
|
57
|
+
// NB: this line's NUMBER is pinned in .infisicalignore
|
|
58
|
+
// (`…/postinstall.cjs:generic-api-key:<line>`) — gitleaks fingerprints include
|
|
59
|
+
// it, so ADDING OR REMOVING LINES ABOVE HERE breaks the allowlist and turns the
|
|
60
|
+
// key into a CI secret-scan failure. Move the fingerprint with it.
|
|
30
61
|
const EMBEDDED_KEY = 'phc_fqKrAmtNZvJqe0krpYB3UwYqALLpT1WM8m5LtNs9eUu'
|
|
31
62
|
const DEFAULT_HOST = 'https://eu.i.posthog.com'
|
|
32
63
|
|
|
64
|
+
/**
|
|
65
|
+
* Every guard below calls this as `return done()`, not as a bare statement. The
|
|
66
|
+
* process.exit is what actually stops the script, but the `return` is what keeps
|
|
67
|
+
* the early exit true if this ever stops exiting synchronously — without it, a
|
|
68
|
+
* deferred done() would let the code past the consent gate run on a machine that
|
|
69
|
+
* never agreed to be measured.
|
|
70
|
+
*/
|
|
33
71
|
function done() {
|
|
34
72
|
process.exit(0)
|
|
35
73
|
}
|
|
@@ -42,22 +80,22 @@ try {
|
|
|
42
80
|
const { randomUUID } = require('node:crypto')
|
|
43
81
|
|
|
44
82
|
// Real dependency install only — workspace path has no /node_modules/ segment.
|
|
45
|
-
if (!__dirname.includes(`${path.sep}node_modules${path.sep}`)) done()
|
|
83
|
+
if (!__dirname.includes(`${path.sep}node_modules${path.sep}`)) return done()
|
|
46
84
|
|
|
47
85
|
// CI re-installs would inflate the adoption count — skip them.
|
|
48
|
-
if (process.env.CI) done()
|
|
86
|
+
if (process.env.CI) return done()
|
|
49
87
|
|
|
50
88
|
const key = (process.env.EXTENSHI_POSTHOG_KEY || EMBEDDED_KEY).trim()
|
|
51
|
-
if (!key) done()
|
|
89
|
+
if (!key) return done()
|
|
52
90
|
|
|
53
91
|
const dnt = String(process.env.DO_NOT_TRACK || '')
|
|
54
92
|
.trim()
|
|
55
93
|
.toLowerCase()
|
|
56
|
-
if (['1', 'true', 'yes', 'on'].includes(dnt)) done()
|
|
94
|
+
if (['1', 'true', 'yes', 'on'].includes(dnt)) return done()
|
|
57
95
|
const optOut = String(process.env.EXTENSHI_TELEMETRY || '')
|
|
58
96
|
.trim()
|
|
59
97
|
.toLowerCase()
|
|
60
|
-
if (['0', 'false', 'off', 'no'].includes(optOut)) done()
|
|
98
|
+
if (['0', 'false', 'off', 'no'].includes(optOut)) return done()
|
|
61
99
|
|
|
62
100
|
// Anonymous per-install id, shared with the runtime telemetry module.
|
|
63
101
|
const configPath = path.join(os.homedir(), '.extenshi', 'config.json')
|
|
@@ -65,8 +103,23 @@ try {
|
|
|
65
103
|
try {
|
|
66
104
|
cfg = JSON.parse(fs.readFileSync(configPath, 'utf8'))
|
|
67
105
|
} catch {}
|
|
68
|
-
|
|
69
|
-
|
|
106
|
+
|
|
107
|
+
// Positive consent only. An install happens before the CLI can put the
|
|
108
|
+
// question, so an absent answer is "not asked yet", never "yes" — this exits
|
|
109
|
+
// for a machine that declined AND for one that has never been asked. Every
|
|
110
|
+
// line below this point, including minting the anonymous id, is reached only
|
|
111
|
+
// with a recorded `true`, which is what stops a bare `npx` from creating an
|
|
112
|
+
// identity on a machine that never agreed to one.
|
|
113
|
+
if (!cfg || cfg.telemetry !== true) return done()
|
|
114
|
+
|
|
115
|
+
let anonId = cfg.anonId
|
|
116
|
+
// Retained for event-schema stability, but it no longer measures anything:
|
|
117
|
+
// accepting the first-run question writes `telemetry: true` and then emits an
|
|
118
|
+
// event, which mints the id — so by the time this gate opens, an anonId is
|
|
119
|
+
// already there and this is false. It stays true only in the odd case of a
|
|
120
|
+
// config that kept the answer but lost the id. Before the accepted-only gate
|
|
121
|
+
// it was the new-machine-vs-upgrade discriminator described above.
|
|
122
|
+
const firstExtenshiInstall = !anonId
|
|
70
123
|
if (!anonId) {
|
|
71
124
|
anonId = randomUUID()
|
|
72
125
|
try {
|
|
@@ -95,6 +148,7 @@ try {
|
|
|
95
148
|
arch: process.arch,
|
|
96
149
|
ci: false,
|
|
97
150
|
source: 'npm_postinstall',
|
|
151
|
+
first_extenshi_install: firstExtenshiInstall,
|
|
98
152
|
},
|
|
99
153
|
})
|
|
100
154
|
|