From c6b53088dce161c0533711dceff97e518426b9e9 Mon Sep 17 00:00:00 2001 From: JF Date: Wed, 20 May 2026 18:51:10 -0400 Subject: [PATCH] fix: derive packed tarball name from package.json for stable alias (#78) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The bundle script copied "--.tgz" to a stable "mcp-debugger-latest.tgz" alias by listing all *.tgz files in the package directory, sorting them lexicographically, and pop()-ing the last entry. But "mcp-debugger-latest.tgz" itself is in that list, and 'm' > 'd', so pop() returned the alias and the script copied it onto itself — the alias never refreshed. Derive the exact tarball filename from package.json (name + version) so the alias always points at the freshly-packed artifact. Also resolves the existing inline TODO about lexicographic sort misordering semver (0.9.0 > 0.10.0) — there is no sort anymore. Verified by seeding the alias with garbage, rebuilding, and confirming the alias is overwritten with byte-identical content to the fresh versioned tarball. Co-Authored-By: Claude Opus 4.7 (1M context) --- packages/mcp-debugger/scripts/bundle-cli.js | 24 +++++++++++++-------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/packages/mcp-debugger/scripts/bundle-cli.js b/packages/mcp-debugger/scripts/bundle-cli.js index 27308a8e..afe6534a 100644 --- a/packages/mcp-debugger/scripts/bundle-cli.js +++ b/packages/mcp-debugger/scripts/bundle-cli.js @@ -243,18 +243,24 @@ async function bundleCLI() { }); console.log('npm pack artifact refreshed in packages/mcp-debugger/package/.'); - // Copy tarball to stable name for local npx testing - const tgzFiles = fs.readdirSync(path.join(packageRoot, 'package')) - .filter(f => f.endsWith('.tgz')); - if (tgzFiles.length > 0) { - // Note: lexicographic sort may misorder semver (e.g., 0.9.0 > 0.10.0). - // For robustness, derive from package.json version if precise ordering matters. - const latestTgz = tgzFiles.sort().pop(); + // Copy tarball to stable alias for local npx testing. Derive the exact + // filename from package.json — avoids two hazards in readdir-based discovery: + // the alias itself can win the lexicographic sort over the real tarball + // ('m' > 'd'), and version-named files can sort out of order (0.9.0 > 0.10.0). + const pkg = JSON.parse( + fs.readFileSync(path.join(packageRoot, 'package.json'), 'utf8') + ); + const tarballName = `${pkg.name.replace('@', '').replace('/', '-')}-${pkg.version}.tgz`; + const tarballPath = path.join(packageRoot, 'package', tarballName); + + if (fs.existsSync(tarballPath)) { fs.copyFileSync( - path.join(packageRoot, 'package', latestTgz), + tarballPath, path.join(packageRoot, 'package', 'mcp-debugger-latest.tgz') ); - console.log(`Copied ${latestTgz} → mcp-debugger-latest.tgz`); + console.log(`Copied ${tarballName} → mcp-debugger-latest.tgz`); + } else { + console.warn(`Warning: expected tarball ${tarballName} not found; mcp-debugger-latest.tgz not refreshed.`); } } finally { execSync(`node "${preparePackScript}" restore`, {