{ lib, stdenv, bun, nodejs, writableTmpDirAsHomeHook, }: let workspacePreparePatched = [ "apps/server/package.json" "apps/web/package.json" "packages/client-runtime/package.json" "packages/contracts/package.json" "packages/effect-acp/package.json" "packages/effect-codex-app-server/package.json" "packages/shared/package.json" ]; renderBunFilters = filters: lib.concatMapStringsSep "\n" (filter: " --filter ${filter} \\") filters; in { inherit workspacePreparePatched; mkNodeModules = { pname, version, src, outputHash, filters, extraNativeBuildInputs ? [], impureEnvVars ? [], extraEnv ? "", }: stdenv.mkDerivation { pname = "${pname}-node-modules"; inherit version src impureEnvVars; nativeBuildInputs = [ bun nodejs writableTmpDirAsHomeHook ] ++ extraNativeBuildInputs; dontConfigure = true; dontFixup = true; postPatch = '' for packageJson in ${lib.concatStringsSep " " workspacePreparePatched}; do substituteInPlace "$packageJson" \ --replace-fail '"prepare": "effect-language-service patch"' '"prepare": "true"' done ''; buildPhase = '' runHook preBuild export HOME="$TMPDIR" export BUN_INSTALL_CACHE_DIR="$(mktemp -d)" ${extraEnv} bun install \ --frozen-lockfile \ --ignore-scripts \ --backend=copyfile \ --linker=hoisted \ --no-progress \ ${renderBunFilters filters} runHook postBuild ''; installPhase = '' runHook preInstall cp -LR ./node_modules $out runHook postInstall ''; inherit outputHash; outputHashAlgo = "sha256"; outputHashMode = "recursive"; }; mkNodePtyConfigurePhase = { nodeModules, chmodBins ? false, }: '' runHook preConfigure mkdir -p ./node_modules cp -R ${nodeModules}/. ./node_modules/ chmod -R u+rwX node_modules if [ ${if chmodBins then "true" else "false"} = true ] && [ -d node_modules/.bin ]; then chmod -R u+x node_modules/.bin fi patchShebangs node_modules cd node_modules/node-pty node-gyp rebuild node scripts/post-install.js cd "$NIX_BUILD_TOP/$sourceRoot" runHook postConfigure ''; }