From bb3c53b40bb2ffa080a46b6fda34f36efd046409 Mon Sep 17 00:00:00 2001 From: Alexander Miroshnichenko Date: Tue, 12 May 2026 11:48:46 +0300 Subject: [PATCH] refactor(freebuff): run engine directly from nix-store Remove unnecessary copy to ~/.config/manicode/. The patched ELF binary and tree-sitter.wasm stay in the nix store alongside a minimal JS launcher that spawns the engine with terminal cleanup handling. --- packages/freebuff/package.nix | 101 +++++++--------------------------- 1 file changed, 20 insertions(+), 81 deletions(-) diff --git a/packages/freebuff/package.nix b/packages/freebuff/package.nix index 02650ae..53cda86 100644 --- a/packages/freebuff/package.nix +++ b/packages/freebuff/package.nix @@ -46,7 +46,6 @@ let hash = "sha256-fJ1D26t8qzsxM7Dmpa8UAUSCKFMWs57J9QjvrdnrzpU="; }; - # Pre-built binary release from codebuff.com binarySrc = fetchurl { url = "https://codebuff.com/api/releases/download/${version}/freebuff-linux-x64.tar.gz"; hash = "sha256-WRTEXqKDww4ZPAnDLAAkAd0jxl+z6+dRbcQORmN7QfM="; @@ -74,23 +73,17 @@ stdenv.mkDerivation rec { cp /tmp/fb-engine/freebuff "$out/bin/freebuff-engine" chmod 755 "$out/bin/freebuff-engine" - # Patch ELF interpreter and rpath for glibc on NixOS patchelf \ --set-interpreter "${glibc}/lib/ld-linux-x86-64.so.2" \ --set-rpath "${glibc}/lib:" \ "$out/bin/freebuff-engine" - # Copy tree-sitter.wasm next to the engine binary if [ -f /tmp/fb-engine/tree-sitter.wasm ]; then cp /tmp/fb-engine/tree-sitter.wasm "$out/bin/" fi rm -rf /tmp/fb-engine - # Set up JS launcher and npm dependencies - mkdir -p "$out/lib/node_modules/freebuff" - cp -r * "$out/lib/node_modules/freebuff/" - # Extract npm dependencies from pre-fetched tarballs extractNpmPkg() { local src="$1" target="$2" @@ -98,94 +91,40 @@ stdenv.mkDerivation rec { tar xzf "$src" -C "$target" --strip-components=1 } + mkdir -p "$out/lib/node_modules/tar" + mkdir -p "$out/lib/node_modules/chownr" + mkdir -p "$out/lib/node_modules/minipass" + mkdir -p "$out/lib/node_modules/minizlib" + mkdir -p "$out/lib/node_modules/yallist" + mkdir -p "$out/lib/node_modules/@isaacs/fs-minipass" + extractNpmPkg "${pkgTar}" "$out/lib/node_modules/tar" extractNpmPkg "${pkgChownr}" "$out/lib/node_modules/chownr" extractNpmPkg "${pkgMinipass}" "$out/lib/node_modules/minipass" extractNpmPkg "${pkgMinizlib}" "$out/lib/node_modules/minizlib" extractNpmPkg "${pkgYallist}" "$out/lib/node_modules/yallist" - mkdir -p "$out/lib/node_modules/@isaacs" - extractNpmPkg "${pkgFsMinipass}" "$out/lib/node_modules/@isaacs/fs-minipass" + extractNpmPkg "${pkgFsMinipass}" "$out/lib/node_modules/@isaacs/fs-minipass" - # Create wrapper launcher that uses the pre-patched binary instead of downloading - cat > "$out/lib/node_modules/freebuff/wrapper-launcher.js" << WRAPPER_EOF + # Launcher: run the patched engine directly from nix-store + cat > "$out/bin/launcher.js" << LAUNCHER_EOF #!/usr/bin/env node const { spawn } = require('child_process'); -const fs = require('fs'); -const path = require('path'); +const TERMINAL_RESET = '\x1b[?1049l\x1b[?1000l\x1b[?1002l\x1b[?1003l\x1b[?1006l\x1b[?2004l\x1b[?25h'; +const engine = '${placeholder "out"}/bin/freebuff-engine'; -// Use the Nix-store patched binary directly -const enginePath = process.env.FREEBUFF_ENGINE || '${placeholder "out"}/bin/freebuff-engine'; - -// Metadata path for version tracking -const configDir = path.join(process.env.HOME || '/', '.config', 'manicode'); -const metadataPath = path.join(configDir, 'freebuff-metadata.json'); - -function resetTerminal() { - try { - if (process.stdin.isTTY && process.stdin.setRawMode) { - process.stdin.setRawMode(false); - } - } catch {} - try { - const seqs = '\\x1b[?1049l\\x1b[?1000l\\x1b[?1002l\\x1b[?1003l\\x1b[?1006l\\x1b[?2004l\\x1b[?25h'; - if (process.stdout.isTTY) process.stdout.write(seqs); - } catch {} +function reset() { + try { if (process.stdin.isTTY && process.stdin.setRawMode) process.stdin.setRawMode(false); } catch(e){} + try { if (process.stdout.isTTY) process.stdout.write(TERMINAL_RESET); } catch(e){} } -async function main() { - // Copy patched binary to user config dir so the engine finds tree-sitter.wasm there too - fs.mkdirSync(configDir, { recursive: true }); - const targetBinary = path.join(configDir, 'freebuff'); - const targetWasm = path.join(configDir, 'tree-sitter.wasm'); +const child = spawn(engine, process.argv.slice(2), { stdio: 'inherit' }); +child.on('exit', (code, signal) => { reset(); process.exit(signal ? 1 : code || 0); }); +child.on('error', (e) => { console.error('Failed to start freebuff:', e.message); process.exit(1); }); +LAUNCHER_EOF - // Install patched binary if not present or version mismatch - let needsInstall = !fs.existsSync(targetBinary); - if (!needsInstall) { - try { - const meta = JSON.parse(fs.readFileSync(metadataPath, 'utf8')); - needsInstall = (meta.version !== '${version}'); - } catch {} - } - - if (needsInstall) { - try { fs.unlinkSync(targetBinary); } catch {} - fs.copyFileSync(enginePath, targetBinary); - fs.chmodSync(targetBinary, 0o755); - fs.writeFileSync(metadataPath, JSON.stringify({ version: '${version}' }, null, 2)); - - // Copy tree-sitter.wasm if available - const wasmSrc = '${placeholder "out"}/bin/tree-sitter.wasm'; - if (fs.existsSync(wasmSrc)) { - try { fs.copyFileSync(wasmSrc, targetWasm); } catch {} - } - } - - const child = spawn(targetBinary, process.argv.slice(2), { - stdio: 'inherit', - env: { ...process.env }, - }); - - child.on('exit', (code, signal) => { - resetTerminal(); - process.exit(signal ? 1 : (code || 0)); - }); - - child.on('error', (err) => { - console.error('Failed to start freebuff:', err.message); - process.exit(1); - }); -} - -main().catch((error) => { - console.error('Unexpected error:', error.message); - process.exit(1); -}); -WRAPPER_EOF - - # Create the main binary wrapper makeWrapper "${nodejs}/bin/node" "$out/bin/freebuff" \ --set NODE_PATH "$out/lib/node_modules" \ - --add-flags "$out/lib/node_modules/freebuff/wrapper-launcher.js" + --add-flags "$out/bin/launcher.js" runHook postInstall '';