{ lib, stdenvNoCC, bun, fetchFromGitHub, makeBinaryWrapper, models-dev, ripgrep, sysctl, installShellFiles, versionCheckHook, writableTmpDirAsHomeHook, }: let pname = "opencode"; version = "1.2.27"; src = fetchFromGitHub { owner = "anomalyco"; repo = "opencode"; tag = "v${version}"; hash = "sha256-smGIc6lYWSjfmGAikoYpP7GbB6mWacrPWrRtp/+HJ3E="; }; nodeModulesHashes = { x86_64-linux = "sha256-4kjoJ06VNvHltPHfzQRBG0bC6R39jao10ffGzrNZ230="; aarch64-linux = "sha256-6Uio+S2rcyBWbBEeOZb9N1CCKgkbKi68lOIKi3Ws/pQ="; aarch64-darwin = "sha256-8ngN5KVN4vhdsk0QJ11BGgSVBrcaEbwSj23c77HBpgs="; x86_64-darwin = "sha256-v/ueYGb9a0Nymzy+mkO4uQr78DAuJnES1qOT0onFgnQ="; }; platform = stdenvNoCC.hostPlatform; bunCpu = if platform.isAarch64 then "arm64" else "x64"; bunOs = if platform.isLinux then "linux" else "darwin"; node_modules = stdenvNoCC.mkDerivation { pname = "${pname}-node_modules"; inherit version src; impureEnvVars = lib.fetchers.proxyImpureEnvVars ++ [ "GIT_PROXY_COMMAND" "SOCKS_SERVER" ]; nativeBuildInputs = [ bun writableTmpDirAsHomeHook ]; dontConfigure = true; buildPhase = '' runHook preBuild export BUN_INSTALL_CACHE_DIR=$(mktemp -d) bun install \ --cpu="${bunCpu}" \ --os="${bunOs}" \ --filter '!./' \ --filter './packages/opencode' \ --filter './packages/desktop' \ --frozen-lockfile \ --ignore-scripts \ --no-progress bun --bun ${src}/nix/scripts/canonicalize-node-modules.ts bun --bun ${src}/nix/scripts/normalize-bun-binaries.ts runHook postBuild ''; installPhase = '' runHook preInstall mkdir -p $out find . -type d -name node_modules -exec cp -R --parents {} $out \; runHook postInstall ''; dontFixup = true; outputHashAlgo = "sha256"; outputHashMode = "recursive"; outputHash = nodeModulesHashes.${platform.system}; }; in stdenvNoCC.mkDerivation (finalAttrs: { inherit pname version src node_modules ; nativeBuildInputs = [ bun installShellFiles makeBinaryWrapper models-dev writableTmpDirAsHomeHook ]; postPatch = '' substituteInPlace packages/script/src/index.ts \ --replace-fail 'throw new Error(`This script requires bun@''${expectedBunVersionRange}' \ 'console.warn(`Warning: This script requires bun@''${expectedBunVersionRange}' ''; configurePhase = '' runHook preConfigure cp -R ${finalAttrs.node_modules}/. . runHook postConfigure ''; env.MODELS_DEV_API_JSON = "${models-dev}/dist/_api.json"; env.OPENCODE_DISABLE_MODELS_FETCH = true; env.OPENCODE_VERSION = finalAttrs.version; env.OPENCODE_CHANNEL = "stable"; buildPhase = '' runHook preBuild cd ./packages/opencode bun --bun ./script/build.ts --single --skip-install bun --bun ./script/schema.ts schema.json runHook postBuild ''; installPhase = '' runHook preInstall install -Dm755 dist/opencode-*/bin/opencode $out/bin/opencode install -Dm644 schema.json $out/share/opencode/schema.json wrapProgram $out/bin/opencode \ --prefix PATH : ${ lib.makeBinPath ( [ ripgrep ] ++ lib.optional platform.isDarwin sysctl ) } runHook postInstall ''; postInstall = lib.optionalString (stdenvNoCC.buildPlatform.canExecute platform) '' installShellCompletion --cmd opencode \ --bash <($out/bin/opencode completion) \ --zsh <(SHELL=/bin/zsh $out/bin/opencode completion) ''; nativeInstallCheckInputs = [ versionCheckHook writableTmpDirAsHomeHook ]; doInstallCheck = true; versionCheckKeepEnvironment = [ "HOME" "OPENCODE_DISABLE_MODELS_FETCH" ]; versionCheckProgramArg = "--version"; passthru = { jsonschema = "${placeholder "out"}/share/opencode/schema.json"; }; meta = { description = "The open source coding agent"; homepage = "https://opencode.ai/"; license = lib.licenses.mit; mainProgram = "opencode"; platforms = builtins.attrNames nodeModulesHashes; }; })