fix(build): normalize executable bits for CLI bin outputs (#334)

Co-authored-by: Letta <noreply@letta.com>
This commit is contained in:
Sarah Wooders
2026-02-18 11:18:12 -08:00
committed by GitHub
parent 83da7069cf
commit 61c2657885
2 changed files with 55 additions and 0 deletions

View File

@@ -15,6 +15,7 @@
"setup": "tsx src/setup.ts",
"dev": "tsx src/main.ts",
"build": "tsc",
"postbuild": "node scripts/fix-bin-permissions.mjs",
"prepare": "npx patch-package || true",
"prepublishOnly": "npm run build && npm run test:run",
"start": "node dist/main.js",

View File

@@ -0,0 +1,54 @@
#!/usr/bin/env node
import { readFile } from 'node:fs/promises';
import { chmodSync, statSync } from 'node:fs';
import { dirname, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const repoRoot = resolve(__dirname, '..');
const packageJsonPath = resolve(repoRoot, 'package.json');
function normalizeBinPaths(binField) {
if (!binField) return [];
if (typeof binField === 'string') return [binField];
if (typeof binField === 'object') return Object.values(binField).filter((v) => typeof v === 'string');
return [];
}
function ensureExecutable(filePath) {
const stat = statSync(filePath);
const nextMode = stat.mode | 0o111;
if (nextMode !== stat.mode) {
chmodSync(filePath, nextMode);
return true;
}
return false;
}
async function main() {
const pkgRaw = await readFile(packageJsonPath, 'utf8');
const pkg = JSON.parse(pkgRaw);
const binPaths = normalizeBinPaths(pkg.bin);
if (binPaths.length === 0) {
console.warn('[postbuild] No bin entries found in package.json');
return;
}
let changed = 0;
for (const relativeBinPath of binPaths) {
const cleanRelPath = relativeBinPath.replace(/^\.\//, '');
const absolutePath = resolve(repoRoot, cleanRelPath);
const didChange = ensureExecutable(absolutePath);
if (didChange) changed += 1;
}
console.log(`[postbuild] Ensured executable bit on ${binPaths.length} bin file(s); updated ${changed}.`);
}
main().catch((error) => {
console.error('[postbuild] Failed to fix bin permissions:', error);
process.exit(1);
});