fix: handle permission errors for binaries on Linux/WSL

- Add automatic chmod +x when running coder.js on Unix systems
- Fix postinstall script to use octal notation for chmod (0o755)
- Add better error messages when binary is not executable
- Always try to fix permissions for existing binaries
- Bump version to 0.1.2 for hotfix release
This commit is contained in:
James Peter
2025-08-12 06:55:01 +10:00
parent aea984541c
commit 240efb844f
3 changed files with 40 additions and 8 deletions
+26 -4
View File
@@ -58,6 +58,25 @@ if (!targetTriple) {
const binaryPath = path.join(__dirname, "..", "bin", `coder-${targetTriple}`);
// Check if binary exists and try to fix permissions if needed
import { existsSync, chmodSync } from "fs";
if (existsSync(binaryPath)) {
try {
// Ensure binary is executable on Unix-like systems
if (platform !== "win32") {
chmodSync(binaryPath, 0o755);
}
} catch (e) {
// Ignore permission errors, will be caught below if it's a real problem
}
} else {
console.error(`Binary not found: ${binaryPath}`);
console.error(`Please try reinstalling the package:`);
console.error(` npm uninstall -g @just-every/coder`);
console.error(` npm install -g @just-every/coder`);
process.exit(1);
}
// Use an asynchronous spawn instead of spawnSync so that Node is able to
// respond to signals (e.g. Ctrl-C / SIGINT) while the native binary is
// executing. This allows us to forward those signals to the child process
@@ -72,10 +91,13 @@ const child = spawn(binaryPath, process.argv.slice(2), {
child.on("error", (err) => {
// Typically triggered when the binary is missing or not executable.
// Re-throwing here will terminate the parent with a non-zero exit code
// while still printing a helpful stack trace.
// eslint-disable-next-line no-console
console.error(err);
if (err.code === 'EACCES') {
console.error(`Permission denied: ${binaryPath}`);
console.error(`Try running: chmod +x "${binaryPath}"`);
console.error(`Or reinstall the package with: npm install -g @just-every/coder`);
} else {
console.error(err);
}
process.exit(1);
});
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@just-every/coder",
"version": "0.1.1",
"version": "0.1.2",
"license": "Apache-2.0",
"description": "Lightweight coding agent that runs in your terminal - fork of OpenAI Codex",
"bin": {
+13 -3
View File
@@ -78,9 +78,19 @@ async function main() {
const binaryName = `${binary}-${targetTriple}${binaryExt}`;
const localPath = join(binDir, binaryName);
// Skip if already exists
// Skip if already exists and has correct permissions
if (existsSync(localPath)) {
console.log(`✓ ${binaryName} already exists`);
// Always try to fix permissions on Unix-like systems
if (!isWindows) {
try {
chmodSync(localPath, 0o755);
console.log(`✓ ${binaryName} already exists (permissions fixed)`);
} catch (e) {
console.log(`✓ ${binaryName} already exists`);
}
} else {
console.log(`✓ ${binaryName} already exists`);
}
continue;
}
@@ -92,7 +102,7 @@ async function main() {
// Make executable on Unix-like systems
if (!isWindows) {
chmodSync(localPath, '755');
chmodSync(localPath, 0o755);
}
console.log(`✓ Downloaded ${binaryName}`);