6415f94fef
Restoring files from two different pre-revert commits left the package wrappers internally inconsistent, and one of them did not compile. Found by actually building and running them rather than by grepping for removed symbols. pkg/npm — bin.js was never restored, so main's version was destructuring runtimeSetReady/acquireRuntimeLock out of an install.js restored from an older base that does not export them. `npx codebase-memory-mcp` would have died at require time on Windows. install.js, bin.js and the launcher test now all sit on the pre-externalization base, where installWindowsBinaryAtomically is the right primitive for publishing exactly one file. The runtime-set locking that goes away with it existed only to publish binary+sidecars atomically. pkg/go — main.go kept the Windows lock work while main_test.go had been reverted past it, so the package did not build at all: main.go:805: no new variables on left side of := (my edit dropped uiPack) main_test.go: undefined: windowsPayloadName (reverted past its removal) The test is back on main's base, keeping every lock-race test from #1495/#1496 (TestRuntimeSetLock*, TestExpiredLease*, TestStalledRuntimeLockCreator*, TestRuntimeSetLockSerializesProcesses). Dropped 19 whose premise -- a multi-file runtime set with content-addressed sidecars -- no longer exists, and reduced the writeTestRuntimeSet/assertRuntimeTag helpers to the single file that now ships. pkg/pypi — same base repair, keeping the lock and orphan-reconciliation tests. The three archive-SAFETY tests (hardlink members, symlink metadata, unexpected root member) were ADAPTED rather than dropped: they only named a removed file in their fixtures, and they guard traversal properties that still matter. test_release_archives_require_the_integrations_sidecar is inverted rather than deleted -- asserting the sidecar is ABSENT is the stronger guard, since a returning sidecar is exactly what broke `pip install` on Windows. Verified: go vet + go build + go test ok; pypi 24 tests OK; npm 10/10; Windows single-binary bundle contract still passes. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
82 lines
2.7 KiB
JavaScript
82 lines
2.7 KiB
JavaScript
#!/usr/bin/env node
|
|
'use strict';
|
|
// CLI shim: resolves the downloaded binary and replaces the current process with it.
|
|
// If the binary is missing (e.g. --ignore-scripts), attempts a one-time download.
|
|
|
|
const path = require('path');
|
|
const fs = require('fs');
|
|
const { spawnSync } = require('child_process');
|
|
|
|
const isWindows = process.platform === 'win32';
|
|
// npm is a portable one-shot wrapper. Every platform ships exactly ONE binary,
|
|
// so the cached file is the executed file — there is no launcher pair to keep
|
|
// in sync and no adjacent payload to validate.
|
|
const binName = isWindows ? 'codebase-memory-mcp.exe' : 'codebase-memory-mcp';
|
|
const binPath = path.join(__dirname, 'bin', binName);
|
|
const executionPath = binPath;
|
|
const cacheReady = () => {
|
|
if (!fs.existsSync(binPath)) {
|
|
return false;
|
|
}
|
|
if (!isWindows) return true;
|
|
// A cached Windows binary that cannot report its own version is not usable.
|
|
const probe = spawnSync(binPath, ['--version'], {
|
|
stdio: 'ignore',
|
|
timeout: 15_000,
|
|
windowsHide: true,
|
|
});
|
|
return !probe.error && probe.status === 0;
|
|
};
|
|
|
|
if (!cacheReady()) {
|
|
// Binary missing — try running the install script (handles --ignore-scripts case)
|
|
process.stderr.write('codebase-memory-mcp: binary not found, downloading...\n');
|
|
const installResult = spawnSync(process.execPath, [path.join(__dirname, 'install.js')], {
|
|
stdio: 'inherit',
|
|
});
|
|
if (installResult.status !== 0 || !cacheReady()) {
|
|
process.stderr.write(
|
|
'codebase-memory-mcp: download failed.\n' +
|
|
'Try reinstalling: npm install -g codebase-memory-mcp\n'
|
|
);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
function portableMutationAction(args) {
|
|
for (const argument of args) {
|
|
if (['cli', 'hook-augment', 'config', 'install', '--help', '-h', '--version'].includes(argument)) {
|
|
return null;
|
|
}
|
|
if (argument === 'update' || argument === 'uninstall') return argument;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
const result = spawnSync(executionPath, process.argv.slice(2), {
|
|
stdio: 'inherit',
|
|
windowsHide: false,
|
|
});
|
|
|
|
if (result.error) {
|
|
process.stderr.write(`codebase-memory-mcp: ${result.error.message}\n`);
|
|
process.exit(1);
|
|
}
|
|
|
|
const mutation = isWindows && result.status !== 0
|
|
? portableMutationAction(process.argv.slice(2))
|
|
: null;
|
|
if (mutation) {
|
|
const packageCommand = mutation === 'update'
|
|
? 'npm install codebase-memory-mcp@latest'
|
|
: 'npm uninstall codebase-memory-mcp';
|
|
process.stderr.write(
|
|
`This npm Windows copy is portable. Use "${packageCommand}" for package ` +
|
|
'maintenance (add -g for a global install), or run ' +
|
|
'"codebase-memory-mcp install --yes" once for a managed install with its ' +
|
|
'own install.ps1 for updates.\n',
|
|
);
|
|
}
|
|
|
|
process.exit(result.status ?? 0);
|