@extenshi/cli 0.5.1 → 0.5.3
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/cli.d.ts +5 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +57 -60
- package/dist/cli.js.map +1 -1
- package/dist/compliance-review.d.ts +53 -0
- package/dist/compliance-review.d.ts.map +1 -0
- package/dist/compliance-review.js +87 -0
- package/dist/compliance-review.js.map +1 -0
- package/dist/html-report.d.ts.map +1 -1
- package/dist/html-report.js +64 -1
- package/dist/html-report.js.map +1 -1
- package/dist/publish.d.ts.map +1 -1
- package/dist/publish.js +29 -18
- package/dist/publish.js.map +1 -1
- package/dist/render.d.ts +28 -0
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +111 -0
- package/dist/render.js.map +1 -1
- package/dist/report.d.ts.map +1 -1
- package/dist/report.js +55 -1
- package/dist/report.js.map +1 -1
- package/dist/scan.d.ts +14 -1
- package/dist/scan.d.ts.map +1 -1
- package/dist/scan.js +39 -3
- package/dist/scan.js.map +1 -1
- package/dist/telemetry.d.ts +62 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +259 -0
- package/dist/telemetry.js.map +1 -0
- package/dist/validate-artifact.d.ts +27 -0
- package/dist/validate-artifact.d.ts.map +1 -0
- package/dist/validate-artifact.js +94 -0
- package/dist/validate-artifact.js.map +1 -0
- package/package.json +5 -2
- package/scripts/postinstall.cjs +132 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@extenshi/cli",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.3",
|
|
4
4
|
"description": "Pre-publish security scanner for browser extensions",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -10,12 +10,14 @@
|
|
|
10
10
|
"extenshi": "dist/cli.js"
|
|
11
11
|
},
|
|
12
12
|
"files": [
|
|
13
|
-
"dist"
|
|
13
|
+
"dist",
|
|
14
|
+
"scripts/postinstall.cjs"
|
|
14
15
|
],
|
|
15
16
|
"scripts": {
|
|
16
17
|
"build": "tsc",
|
|
17
18
|
"dev": "tsc --watch",
|
|
18
19
|
"test": "vitest run",
|
|
20
|
+
"postinstall": "node scripts/postinstall.cjs",
|
|
19
21
|
"prepublishOnly": "yarn build"
|
|
20
22
|
},
|
|
21
23
|
"dependencies": {
|
|
@@ -24,6 +26,7 @@
|
|
|
24
26
|
"commander": "^12.1.0",
|
|
25
27
|
"jszip": "^3.10.1",
|
|
26
28
|
"ora": "^8.1.1",
|
|
29
|
+
"posthog-node": "^5.35.1",
|
|
27
30
|
"semver": "^7.6.3",
|
|
28
31
|
"undici": "^7.28.0"
|
|
29
32
|
},
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
/**
|
|
3
|
+
* Anonymous install ping — VENDORED, kept byte-identical between @extenshi/cli
|
|
4
|
+
* and @extenshi/mcp (it figures out which one it is from its own package.json).
|
|
5
|
+
*
|
|
6
|
+
* Fires a single `cli_installed` / `mcp_installed` event when the package is
|
|
7
|
+
* installed as a real dependency, so we can see adoption in PostHog. It is a
|
|
8
|
+
* standalone CommonJS script using ONLY Node built-ins (no posthog-node, no
|
|
9
|
+
* build step) so it can run the instant npm extracts the tarball.
|
|
10
|
+
*
|
|
11
|
+
* Hard rules (a postinstall that breaks `npm install` is unacceptable):
|
|
12
|
+
* - ALWAYS exits 0, even on any error — wrapped in try/catch + a hard timeout.
|
|
13
|
+
* - Fully fail-soft and fire-and-forget; the request is capped at ~2s.
|
|
14
|
+
*
|
|
15
|
+
* It self-skips (no event, no network) when:
|
|
16
|
+
* - the package is NOT under node_modules — i.e. our own monorepo workspace
|
|
17
|
+
* install (tools/<pkg>), so dev installs never inflate adoption counts;
|
|
18
|
+
* - DO_NOT_TRACK is truthy, EXTENSHI_TELEMETRY is off, or config
|
|
19
|
+
* ~/.extenshi/config.json has "telemetry": false;
|
|
20
|
+
* - CI is set (CI re-installs would massively inflate the count);
|
|
21
|
+
* - no ingestion key is configured.
|
|
22
|
+
*
|
|
23
|
+
* Privacy: sends only the package version, Node version, coarse os/arch, and an
|
|
24
|
+
* anonymous per-install UUID (the same id the runtime telemetry uses). Never any
|
|
25
|
+
* path, package contents, or user input.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
// Shared EU PostHog project key (114791) — public, write-only, already in our
|
|
29
|
+
// web bundles. Override with EXTENSHI_POSTHOG_KEY; empty disables the ping.
|
|
30
|
+
const EMBEDDED_KEY = 'phc_fqKrAmtNZvJqe0krpYB3UwYqALLpT1WM8m5LtNs9eUu'
|
|
31
|
+
const DEFAULT_HOST = 'https://eu.i.posthog.com'
|
|
32
|
+
|
|
33
|
+
function done() {
|
|
34
|
+
process.exit(0)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
const path = require('node:path')
|
|
39
|
+
const fs = require('node:fs')
|
|
40
|
+
const os = require('node:os')
|
|
41
|
+
const https = require('node:https')
|
|
42
|
+
const { randomUUID } = require('node:crypto')
|
|
43
|
+
|
|
44
|
+
// Real dependency install only — workspace path has no /node_modules/ segment.
|
|
45
|
+
if (!__dirname.includes(`${path.sep}node_modules${path.sep}`)) done()
|
|
46
|
+
|
|
47
|
+
// CI re-installs would inflate the adoption count — skip them.
|
|
48
|
+
if (process.env.CI) done()
|
|
49
|
+
|
|
50
|
+
const key = (process.env.EXTENSHI_POSTHOG_KEY || EMBEDDED_KEY).trim()
|
|
51
|
+
if (!key) done()
|
|
52
|
+
|
|
53
|
+
const dnt = String(process.env.DO_NOT_TRACK || '')
|
|
54
|
+
.trim()
|
|
55
|
+
.toLowerCase()
|
|
56
|
+
if (['1', 'true', 'yes', 'on'].includes(dnt)) done()
|
|
57
|
+
const optOut = String(process.env.EXTENSHI_TELEMETRY || '')
|
|
58
|
+
.trim()
|
|
59
|
+
.toLowerCase()
|
|
60
|
+
if (['0', 'false', 'off', 'no'].includes(optOut)) done()
|
|
61
|
+
|
|
62
|
+
// Anonymous per-install id, shared with the runtime telemetry module.
|
|
63
|
+
const configPath = path.join(os.homedir(), '.extenshi', 'config.json')
|
|
64
|
+
let cfg = {}
|
|
65
|
+
try {
|
|
66
|
+
cfg = JSON.parse(fs.readFileSync(configPath, 'utf8'))
|
|
67
|
+
} catch {}
|
|
68
|
+
if (cfg && cfg.telemetry === false) done()
|
|
69
|
+
let anonId = cfg && cfg.anonId
|
|
70
|
+
if (!anonId) {
|
|
71
|
+
anonId = randomUUID()
|
|
72
|
+
try {
|
|
73
|
+
fs.mkdirSync(path.dirname(configPath), { recursive: true })
|
|
74
|
+
fs.writeFileSync(configPath, `${JSON.stringify({ ...cfg, anonId }, null, 2)}\n`, { mode: 0o600 })
|
|
75
|
+
} catch {}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Identify the surface + version from our own package.json.
|
|
79
|
+
let pkg = {}
|
|
80
|
+
try {
|
|
81
|
+
pkg = require(path.join(__dirname, '..', 'package.json'))
|
|
82
|
+
} catch {}
|
|
83
|
+
const surface = String(pkg.name || '').includes('mcp') ? 'mcp' : 'cli'
|
|
84
|
+
const host = (process.env.EXTENSHI_POSTHOG_HOST || DEFAULT_HOST).trim()
|
|
85
|
+
|
|
86
|
+
const payload = JSON.stringify({
|
|
87
|
+
api_key: key,
|
|
88
|
+
event: `${surface}_installed`,
|
|
89
|
+
distinct_id: anonId,
|
|
90
|
+
properties: {
|
|
91
|
+
surface,
|
|
92
|
+
version: pkg.version || '0.0.0',
|
|
93
|
+
node: process.version,
|
|
94
|
+
os: process.platform,
|
|
95
|
+
arch: process.arch,
|
|
96
|
+
ci: false,
|
|
97
|
+
source: 'npm_postinstall',
|
|
98
|
+
},
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
const url = new URL('/i/v0/e/', host)
|
|
102
|
+
const req = https.request(
|
|
103
|
+
{
|
|
104
|
+
method: 'POST',
|
|
105
|
+
hostname: url.hostname,
|
|
106
|
+
port: url.port || 443,
|
|
107
|
+
path: url.pathname,
|
|
108
|
+
headers: { 'content-type': 'application/json', 'content-length': Buffer.byteLength(payload) },
|
|
109
|
+
timeout: 2000,
|
|
110
|
+
},
|
|
111
|
+
(res) => {
|
|
112
|
+
res.on('data', () => {})
|
|
113
|
+
res.on('end', done)
|
|
114
|
+
res.on('error', done)
|
|
115
|
+
},
|
|
116
|
+
)
|
|
117
|
+
req.on('error', done)
|
|
118
|
+
req.on('timeout', () => {
|
|
119
|
+
try {
|
|
120
|
+
req.destroy()
|
|
121
|
+
} catch {}
|
|
122
|
+
done()
|
|
123
|
+
})
|
|
124
|
+
req.write(payload)
|
|
125
|
+
req.end()
|
|
126
|
+
|
|
127
|
+
// Backstop: never let the ping hold the install open.
|
|
128
|
+
const guard = setTimeout(done, 2500)
|
|
129
|
+
if (guard.unref) guard.unref()
|
|
130
|
+
} catch {
|
|
131
|
+
done()
|
|
132
|
+
}
|