mirror of
https://github.com/Twigpine/zero.git
synced 2026-11-11 05:01:36 -10:00
The Bun instructions told global installers to run the postinstall script manually against the global install path, because trustedDependencies only works in a project package.json. Current Bun has a simpler sanctioned path that works for both project and global installs: `bun pm trust @gitlawb/zero` (with -g for globals) runs the blocked postinstall after the fact. Verified on Bun 1.3.14 on Windows 11: `bun pm -g trust @gitlawb/zero` fetched the binary and `zero --version` runs. Lead with that in README.md, README_ZH.md, and docs/INSTALL.md, keep trustedDependencies and the manual installer as alternatives for project installs and older Bun versions, and teach the wrapper's missing-binary message the same commands for the Bun case. Co-authored-by: Claude Fable 5 <[email protected]>
105 lines
3.3 KiB
JavaScript
Executable File
105 lines
3.3 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
|
|
import { spawnSync } from 'node:child_process';
|
|
import { existsSync } from 'node:fs';
|
|
import { dirname, join } from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
function zeroBinaryName(platform = process.platform) {
|
|
return platform === 'win32' ? 'zero.exe' : 'zero';
|
|
}
|
|
|
|
function helperShimNames(name, platform = process.platform) {
|
|
if (platform === 'win32') {
|
|
return [`${name}.cmd`, `${name}.exe`, name];
|
|
}
|
|
return [name];
|
|
}
|
|
|
|
function commandForShim(path, platform = process.platform) {
|
|
if (platform === 'win32' && path.toLowerCase().endsWith('.cmd')) {
|
|
return {
|
|
command: process.env.ComSpec || 'cmd.exe',
|
|
prefixArgs: ['/d', '/s', '/c', `"${path.replace(/"/g, '""')}"`],
|
|
};
|
|
}
|
|
return { command: path, prefixArgs: [] };
|
|
}
|
|
|
|
function resolveHelper(packageRoot, name) {
|
|
const binDir = join(packageRoot, 'node_modules', '.bin');
|
|
for (const shimName of helperShimNames(name)) {
|
|
const candidate = join(binDir, shimName);
|
|
if (!existsSync(candidate)) continue;
|
|
return {
|
|
...commandForShim(candidate),
|
|
pathPrepend: [binDir],
|
|
};
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function localControlHelperManifest(packageRoot) {
|
|
const helpers = {};
|
|
for (const name of ['agent-browser', 'tuistory']) {
|
|
const helper = resolveHelper(packageRoot, name);
|
|
if (helper) helpers[name] = helper;
|
|
}
|
|
if (Object.keys(helpers).length === 0) return '';
|
|
return JSON.stringify({ version: 1, helpers });
|
|
}
|
|
|
|
const packageRoot = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
const nativePath = join(packageRoot, zeroBinaryName());
|
|
const localControlHelpers = localControlHelperManifest(packageRoot);
|
|
|
|
if (!existsSync(nativePath)) {
|
|
const postinstallScript = join(packageRoot, 'scripts', 'postinstall.mjs');
|
|
const ranByBun = process.execPath.includes('bun') || !!process.versions?.bun;
|
|
console.error(
|
|
'[zero] No native binary found next to the npm wrapper.\n' +
|
|
'The platform binary is fetched at install time by a postinstall script,\n' +
|
|
'which did not run (or was skipped) for this install.\n' +
|
|
'\n' +
|
|
'Fix it now by running the installer manually:\n' +
|
|
` node "${postinstallScript}"\n` +
|
|
'\n' +
|
|
(ranByBun
|
|
? 'You installed with Bun, which does not run dependency lifecycle scripts\n' +
|
|
'by default. Trust the package to run the blocked postinstall:\n' +
|
|
' bun pm trust @gitlawb/zero (project install)\n' +
|
|
' bun pm -g trust @gitlawb/zero (global install)\n' +
|
|
'On Bun versions without `bun pm trust`, add\n' +
|
|
' "trustedDependencies": ["@gitlawb/zero"]\n' +
|
|
'to your project package.json and reinstall.\n' +
|
|
'\n'
|
|
: '') +
|
|
'If that fails, build from source: https://github.com/Gitlawb/zero\n' +
|
|
'(go run ./cmd/zero, requires Go 1.25+).',
|
|
);
|
|
process.exit(1);
|
|
}
|
|
|
|
const env = { ...process.env };
|
|
if (localControlHelpers) {
|
|
env.ZERO_LOCAL_CONTROL_HELPERS = localControlHelpers;
|
|
} else {
|
|
delete env.ZERO_LOCAL_CONTROL_HELPERS;
|
|
}
|
|
|
|
const child = spawnSync(nativePath, process.argv.slice(2), {
|
|
stdio: 'inherit',
|
|
env,
|
|
});
|
|
|
|
if (child.error) {
|
|
console.error(`[zero] Failed to launch wrapper target: ${child.error.message}`);
|
|
process.exit(1);
|
|
}
|
|
|
|
if (child.signal) {
|
|
process.kill(process.pid, child.signal);
|
|
}
|
|
|
|
process.exit(child.status ?? 1);
|