From 37050ce2b64de1bbe7863c94821ce94498a7ef58 Mon Sep 17 00:00:00 2001 From: Karstein Phobic Nyvold Kvistad Date: Mon, 27 Apr 2026 20:40:02 +0200 Subject: [PATCH] fix(postinstall): use script-location-vs-INIT_CWD to detect dev (npm 11) The previous heuristic checked whether INIT_CWD's package.json had our name -- but that triggers a false positive when the user runs `npm install -g codesys-mcp-sp21-plus@latest` from a clone of the repo (very common -- they're testing the new release). My install ran from ~/Codesys-MCP and the banner stayed silent. Right discriminator: does the script's __dirname LIVE INSIDE INIT_CWD? If yes, this is the dev case (installing yourself into yourself). If no -- even when INIT_CWD is a clone of this repo -- the script lives in the global prefix and the user is doing a real install. Print the banner. Verified: - INIT_CWD == repo, __dirname == /tmp/...: banner prints - INIT_CWD == repo, __dirname == repo/dist: silent (dev case) --- src/postinstall.ts | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/postinstall.ts b/src/postinstall.ts index ce0b111..07f723e 100644 --- a/src/postinstall.ts +++ b/src/postinstall.ts @@ -18,24 +18,24 @@ function shouldSkip(): boolean { if (process.env.npm_config_ci === 'true') return true; // Skip when running inside the package's own dev clone (developer ran - // `npm install` on a checkout of this repo). Detect by checking whether - // INIT_CWD (npm sets this to the user's invocation cwd) appears to be - // a checkout of THIS package, vs a global install or a downstream consumer. - // Heuristic: if INIT_CWD contains a package.json whose name matches ours, - // it's the dev clone. + // `npm install` on a checkout of this repo). The right discriminator is + // whether the script's own directory LIVES INSIDE INIT_CWD. If yes, the + // install is targeting our own checkout (dev). If no -- even if INIT_CWD + // happens to be a clone of this repo -- the script lives in the global + // prefix and should print the banner. + // + // INIT_CWD == npm's invocation cwd. + // __dirname == /codesys-mcp-sp21-plus/dist for global + // installs, == /dist for the dev case. if (process.env.INIT_CWD) { try { - // eslint-disable-next-line @typescript-eslint/no-var-requires - const fs = require('fs'); // eslint-disable-next-line @typescript-eslint/no-var-requires const path = require('path'); - const pkgPath = path.join(process.env.INIT_CWD, 'package.json'); - if (fs.existsSync(pkgPath)) { - const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8')); - if (pkg.name === 'codesys-mcp-sp21-plus') return true; - } + const rel = path.relative(process.env.INIT_CWD, __dirname); + const livesUnderInitCwd = !rel.startsWith('..') && !path.isAbsolute(rel); + if (livesUnderInitCwd) return true; } catch { - // Not a dev clone or unreadable -- fall through and print the banner. + // Fall through and print the banner. } }