mirror of
https://github.com/MoonshotAI/kimi-code.git
synced 2026-07-09 17:29:12 +00:00
Two distinct PTY failures: - 'Failed to load native module: pty.node' (npx/published daemon): node-pty was transitively bundled via @moonshot-ai/services (alwaysBundle), inlining its JS while its native binary can't be bundled and wasn't shipped. Mark node-pty external in tsdown (neverBundle) and declare it as a runtime dependency of @moonshot-ai/kimi-code so npm/npx installs it with its prebuilt pty.node. - 'posix_spawnp failed' (local pnpm dev): node-pty's prebuilds/*/spawn-helper loses its +x bit through pnpm's store extraction. Add a root postinstall (scripts/fix-node-pty-perms.mjs) that restores the executable bit; verified it fixes a reproducible spawn failure. Also harden defaultShell() to fall back on an empty (not just unset) $SHELL. Note: the SEA standalone binary still needs node-pty's pty.node + spawn-helper wired into scripts/native/native-deps.mjs (not addressed here; npx path covers the reported case).
46 lines
1.8 KiB
JavaScript
46 lines
1.8 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Restore the executable bit on node-pty's `spawn-helper` prebuilt binaries.
|
|
*
|
|
* Why: on macOS/Linux node-pty launches the shell through a tiny `spawn-helper`
|
|
* executable shipped under `prebuilds/<platform-arch>/`. pnpm's content-
|
|
* addressable store does not preserve the +x mode on these non-bin prebuild
|
|
* assets, so after `pnpm install` the helper lands as 0644 and any PTY spawn
|
|
* fails with "posix_spawnp failed". npm/yarn (and the published tarball) keep
|
|
* the bit, so this is a pnpm-dev-only fixup.
|
|
*
|
|
* Idempotent and never fails the install: any error is logged and ignored.
|
|
*/
|
|
import { chmodSync, existsSync, readdirSync, statSync } from 'node:fs';
|
|
import { createRequire } from 'node:module';
|
|
import { dirname, join } from 'node:path';
|
|
|
|
function nodePtyRoot() {
|
|
const require = createRequire(import.meta.url);
|
|
// Resolve from packages/services (where node-pty is declared) so we find the
|
|
// workspace's hoisted copy regardless of where this script runs.
|
|
const entry = require.resolve('node-pty', {
|
|
paths: [join(process.cwd(), 'packages/services'), process.cwd()],
|
|
});
|
|
// .../node-pty/lib/index.js -> .../node-pty
|
|
return dirname(dirname(entry));
|
|
}
|
|
|
|
try {
|
|
const root = nodePtyRoot();
|
|
const prebuilds = join(root, 'prebuilds');
|
|
if (!existsSync(prebuilds)) process.exit(0);
|
|
let fixed = 0;
|
|
for (const arch of readdirSync(prebuilds)) {
|
|
const helper = join(prebuilds, arch, 'spawn-helper');
|
|
if (!existsSync(helper)) continue;
|
|
const mode = statSync(helper).mode;
|
|
if ((mode & 0o111) === 0o111) continue; // already executable
|
|
chmodSync(helper, 0o755);
|
|
fixed++;
|
|
}
|
|
if (fixed > 0) console.log(`[fix-node-pty-perms] made ${fixed} spawn-helper binary(ies) executable`);
|
|
} catch (err) {
|
|
console.warn('[fix-node-pty-perms] skipped:', err instanceof Error ? err.message : String(err));
|
|
}
|
|
process.exit(0);
|