UNPKG

consortium

Version:

Remote control and session sharing CLI for AI coding agents

60 lines (52 loc) 2.06 kB
#!/usr/bin/env node // Upstream `node-pty` publishes its per-platform `spawn-helper` binary as // 0644 (no execute bit) and does not chmod it in any install hook. Its // macOS PTY spawn path does posix_spawnp on that file, which the kernel // refuses — the symptom is: // // Error: Failed to spawn process. // binary: .../node-pty/prebuilds/<plat>/spawn-helper // underlying error: posix_spawnp failed. // // This script runs as part of our postinstall and restores +x on every // spawn-helper it can find inside the installed node-pty tree. Best-effort // — we swallow errors so a partially-installed optional dep never breaks // `npm install`. const { existsSync, readdirSync, chmodSync, statSync } = require('node:fs'); const { dirname, join } = require('node:path'); function findNodePtyPrebuildsDir() { try { const pkgPath = require.resolve('node-pty/package.json'); return join(dirname(pkgPath), 'prebuilds'); } catch { return null; } } function fixSpawnHelperPerms() { const prebuildsDir = findNodePtyPrebuildsDir(); if (!prebuildsDir || !existsSync(prebuildsDir)) return 0; let fixed = 0; for (const entry of readdirSync(prebuildsDir)) { const helper = join(prebuildsDir, entry, 'spawn-helper'); if (!existsSync(helper)) continue; try { const mode = statSync(helper).mode & 0o777; if ((mode & 0o111) === 0o111) continue; // already executable chmodSync(helper, mode | 0o755); fixed++; } catch { // Best-effort: read-only mounts, permission issues on a shared // install, etc. Silent skip beats a failed `npm install`. } } return fixed; } if (require.main === module) { try { const n = fixSpawnHelperPerms(); if (n > 0) console.log(`[consortium] Restored +x on ${n} node-pty spawn-helper binar${n === 1 ? 'y' : 'ies'}`); } catch { // Swallow — this must never fail a postinstall. } } module.exports = { fixSpawnHelperPerms };