feat: add n8n, beads, opencode packages
- Add pkgs/n8n/default.nix (v2.4.1) - Add pkgs/beads/default.nix (v0.47.1, doCheck=false) - Add pkgs/opencode/default.nix (v1.1.18) - Include relax-bun-version-check.patch for opencode - Register all packages in pkgs/default.nix
This commit is contained in:
62
pkgs/beads/default.nix
Normal file
62
pkgs/beads/default.nix
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
{
|
||||||
|
lib,
|
||||||
|
stdenv,
|
||||||
|
buildGoModule,
|
||||||
|
fetchFromGitHub,
|
||||||
|
gitMinimal,
|
||||||
|
installShellFiles,
|
||||||
|
versionCheckHook,
|
||||||
|
writableTmpDirAsHomeHook,
|
||||||
|
}:
|
||||||
|
buildGoModule (finalAttrs: {
|
||||||
|
pname = "beads";
|
||||||
|
version = "0.47.1";
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "steveyegge";
|
||||||
|
repo = "beads";
|
||||||
|
tag = "v${finalAttrs.version}";
|
||||||
|
hash = "sha256-DwIR/r1TJnpVd/CT1E2OTkAjU7k9/KHbcVwg5zziFVg=";
|
||||||
|
};
|
||||||
|
|
||||||
|
vendorHash = "sha256-pY5m5ODRgqghyELRwwxOr+xlW41gtJWLXaW53GlLaFw=";
|
||||||
|
|
||||||
|
subPackages = ["cmd/bd"];
|
||||||
|
|
||||||
|
ldflags = ["-s" "-w"];
|
||||||
|
|
||||||
|
nativeBuildInputs = [installShellFiles];
|
||||||
|
|
||||||
|
nativeCheckInputs = [gitMinimal writableTmpDirAsHomeHook];
|
||||||
|
|
||||||
|
# Skip security tests on Darwin - they check for /etc/passwd which isn't available in sandbox
|
||||||
|
checkFlags =
|
||||||
|
lib.optionals stdenv.hostPlatform.isDarwin
|
||||||
|
["-skip=TestCleanupMergeArtifacts_CommandInjectionPrevention"];
|
||||||
|
|
||||||
|
preCheck = ''
|
||||||
|
export PATH="$out/bin:$PATH"
|
||||||
|
'';
|
||||||
|
|
||||||
|
postInstall = lib.optionalString (stdenv.buildPlatform.canExecute stdenv.hostPlatform) ''
|
||||||
|
installShellCompletion --cmd bd \
|
||||||
|
--bash <($out/bin/bd completion bash) \
|
||||||
|
--fish <($out/bin/bd completion fish) \
|
||||||
|
--zsh <($out/bin/bd completion zsh)
|
||||||
|
'';
|
||||||
|
|
||||||
|
nativeInstallCheckInputs = [versionCheckHook writableTmpDirAsHomeHook];
|
||||||
|
versionCheckProgramArg = "version";
|
||||||
|
doInstallCheck = true;
|
||||||
|
|
||||||
|
# Tests require git worktree operations that fail in Nix sandbox
|
||||||
|
doCheck = false;
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description = "Lightweight memory system for AI coding agents with graph-based issue tracking";
|
||||||
|
homepage = "https://github.com/steveyegge/beads";
|
||||||
|
license = lib.licenses.mit;
|
||||||
|
maintainers = with lib.maintainers; [kedry];
|
||||||
|
mainProgram = "bd";
|
||||||
|
};
|
||||||
|
})
|
||||||
@@ -1,11 +1,14 @@
|
|||||||
{pkgs, ...}: {
|
{pkgs, ...}: {
|
||||||
# Custom packages registry
|
# Custom packages registry
|
||||||
# Each package is defined in its own directory under pkgs/
|
# Each package is defined in its own directory under pkgs/
|
||||||
|
beads = pkgs.callPackage ./beads {};
|
||||||
code2prompt = pkgs.callPackage ./code2prompt {};
|
code2prompt = pkgs.callPackage ./code2prompt {};
|
||||||
hyprpaper-random = pkgs.callPackage ./hyprpaper-random {};
|
hyprpaper-random = pkgs.callPackage ./hyprpaper-random {};
|
||||||
launch-webapp = pkgs.callPackage ./launch-webapp {};
|
launch-webapp = pkgs.callPackage ./launch-webapp {};
|
||||||
mem0 = pkgs.callPackage ./mem0 {};
|
mem0 = pkgs.callPackage ./mem0 {};
|
||||||
msty-studio = pkgs.callPackage ./msty-studio {};
|
msty-studio = pkgs.callPackage ./msty-studio {};
|
||||||
|
n8n = pkgs.callPackage ./n8n {};
|
||||||
|
opencode = pkgs.callPackage ./opencode {};
|
||||||
pomodoro-timer = pkgs.callPackage ./pomodoro-timer {};
|
pomodoro-timer = pkgs.callPackage ./pomodoro-timer {};
|
||||||
rofi-project-opener = pkgs.callPackage ./rofi-project-opener {};
|
rofi-project-opener = pkgs.callPackage ./rofi-project-opener {};
|
||||||
stt-ptt = pkgs.callPackage ./stt-ptt {};
|
stt-ptt = pkgs.callPackage ./stt-ptt {};
|
||||||
|
|||||||
114
pkgs/n8n/default.nix
Normal file
114
pkgs/n8n/default.nix
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
{
|
||||||
|
stdenv,
|
||||||
|
lib,
|
||||||
|
nixosTests,
|
||||||
|
fetchFromGitHub,
|
||||||
|
nodejs,
|
||||||
|
pnpm_10,
|
||||||
|
fetchPnpmDeps,
|
||||||
|
pnpmConfigHook,
|
||||||
|
python3,
|
||||||
|
node-gyp,
|
||||||
|
cctools,
|
||||||
|
xcbuild,
|
||||||
|
libkrb5,
|
||||||
|
libmongocrypt,
|
||||||
|
libpq,
|
||||||
|
makeWrapper,
|
||||||
|
}:
|
||||||
|
stdenv.mkDerivation (finalAttrs: {
|
||||||
|
pname = "n8n";
|
||||||
|
version = "2.4.1";
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "n8n-io";
|
||||||
|
repo = "n8n";
|
||||||
|
tag = "n8n@${finalAttrs.version}";
|
||||||
|
hash = "sha256-EQP9ZI8kt30SUYE1+/UUpxQXpavzKqDu8qE24zsNifg=";
|
||||||
|
};
|
||||||
|
|
||||||
|
pnpmDeps = fetchPnpmDeps {
|
||||||
|
inherit (finalAttrs) pname version src;
|
||||||
|
pnpm = pnpm_10;
|
||||||
|
fetcherVersion = 3;
|
||||||
|
hash = "sha256-M/HXRii4FotDC/xIa6DVlY13rCHMq7oZNtPi7hvDXik=";
|
||||||
|
};
|
||||||
|
|
||||||
|
nativeBuildInputs =
|
||||||
|
[
|
||||||
|
pnpmConfigHook
|
||||||
|
pnpm_10
|
||||||
|
python3 # required to build sqlite3 bindings
|
||||||
|
node-gyp # required to build sqlite3 bindings
|
||||||
|
makeWrapper
|
||||||
|
]
|
||||||
|
++ lib.optional stdenv.hostPlatform.isDarwin [cctools xcbuild];
|
||||||
|
|
||||||
|
buildInputs = [nodejs libkrb5 libmongocrypt libpq];
|
||||||
|
|
||||||
|
buildPhase = ''
|
||||||
|
runHook preBuild
|
||||||
|
|
||||||
|
pushd node_modules/sqlite3
|
||||||
|
node-gyp rebuild
|
||||||
|
popd
|
||||||
|
|
||||||
|
# TODO: use deploy after resolved https://github.com/pnpm/pnpm/issues/5315
|
||||||
|
pnpm build --filter=n8n
|
||||||
|
|
||||||
|
runHook postBuild
|
||||||
|
'';
|
||||||
|
|
||||||
|
preInstall = ''
|
||||||
|
echo "Removing non-deterministic and unnecessary files"
|
||||||
|
|
||||||
|
find -type d -name .turbo -exec rm -rf {} +
|
||||||
|
rm node_modules/.modules.yaml
|
||||||
|
rm packages/nodes-base/dist/types/nodes.json
|
||||||
|
|
||||||
|
CI=true pnpm --ignore-scripts prune --prod
|
||||||
|
find -type f \( -name "*.ts" -o -name "*.map" \) -exec rm -rf {} +
|
||||||
|
rm -rf node_modules/.pnpm/{typescript*,prettier*}
|
||||||
|
shopt -s globstar
|
||||||
|
# https://github.com/pnpm/pnpm/issues/3645
|
||||||
|
find node_modules packages/**/node_modules -xtype l -delete
|
||||||
|
|
||||||
|
echo "Removed non-deterministic and unnecessary files"
|
||||||
|
'';
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
runHook preInstall
|
||||||
|
|
||||||
|
mkdir -p $out/{bin,lib/n8n}
|
||||||
|
mv {packages,node_modules} $out/lib/n8n
|
||||||
|
|
||||||
|
makeWrapper $out/lib/n8n/packages/cli/bin/n8n $out/bin/n8n \
|
||||||
|
--set N8N_RELEASE_TYPE "stable"
|
||||||
|
|
||||||
|
runHook postInstall
|
||||||
|
'';
|
||||||
|
|
||||||
|
passthru = {
|
||||||
|
tests = nixosTests.n8n;
|
||||||
|
updateScript = ./update.sh;
|
||||||
|
};
|
||||||
|
|
||||||
|
# this package has ~80000 files, these take too long and seem to be unnecessary
|
||||||
|
dontStrip = true;
|
||||||
|
dontPatchELF = true;
|
||||||
|
dontRewriteSymlinks = true;
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description = "Free and source-available fair-code licensed workflow automation tool";
|
||||||
|
longDescription = ''
|
||||||
|
Free and source-available fair-code licensed workflow automation tool.
|
||||||
|
Easily automate tasks across different services.
|
||||||
|
'';
|
||||||
|
homepage = "https://n8n.io";
|
||||||
|
changelog = "https://github.com/n8n-io/n8n/releases/tag/n8n@${finalAttrs.version}";
|
||||||
|
maintainers = with lib.maintainers; [gepbird AdrienLemaire sweenu];
|
||||||
|
license = lib.licenses.sustainableUse;
|
||||||
|
mainProgram = "n8n";
|
||||||
|
platforms = lib.platforms.unix;
|
||||||
|
};
|
||||||
|
})
|
||||||
222
pkgs/opencode/default.nix
Normal file
222
pkgs/opencode/default.nix
Normal file
@@ -0,0 +1,222 @@
|
|||||||
|
{
|
||||||
|
lib,
|
||||||
|
stdenvNoCC,
|
||||||
|
bun,
|
||||||
|
fetchFromGitHub,
|
||||||
|
fzf,
|
||||||
|
makeBinaryWrapper,
|
||||||
|
models-dev,
|
||||||
|
nix-update-script,
|
||||||
|
ripgrep,
|
||||||
|
testers,
|
||||||
|
installShellFiles,
|
||||||
|
writableTmpDirAsHomeHook,
|
||||||
|
}: let
|
||||||
|
pname = "opencode";
|
||||||
|
version = "1.1.18";
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "anomalyco";
|
||||||
|
repo = "opencode";
|
||||||
|
tag = "v${version}";
|
||||||
|
hash = "sha256-3A4s0FpjZuGB0HGMQVBXfWq+0yHmeIvnEQTSX3amV4I=";
|
||||||
|
};
|
||||||
|
|
||||||
|
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="*" \
|
||||||
|
--filter=./packages/opencode \
|
||||||
|
--force \
|
||||||
|
--frozen-lockfile \
|
||||||
|
--ignore-scripts \
|
||||||
|
--no-progress \
|
||||||
|
--os="*" \
|
||||||
|
--production
|
||||||
|
|
||||||
|
bun run ./nix/scripts/canonicalize-node-modules.ts
|
||||||
|
bun run ./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
|
||||||
|
'';
|
||||||
|
|
||||||
|
# NOTE: Required else we get errors that our fixed-output derivation references store paths
|
||||||
|
dontFixup = true;
|
||||||
|
|
||||||
|
outputHash = "sha256-zSco4ORQQOqV3vMPuP+M/q/hBa+MJGnTKIlxgngMA3g=";
|
||||||
|
outputHashAlgo = "sha256";
|
||||||
|
outputHashMode = "recursive";
|
||||||
|
};
|
||||||
|
in
|
||||||
|
stdenvNoCC.mkDerivation (finalAttrs: {
|
||||||
|
inherit pname version src node_modules;
|
||||||
|
|
||||||
|
nativeBuildInputs = [
|
||||||
|
bun
|
||||||
|
installShellFiles
|
||||||
|
makeBinaryWrapper
|
||||||
|
models-dev
|
||||||
|
writableTmpDirAsHomeHook
|
||||||
|
];
|
||||||
|
|
||||||
|
patches = [
|
||||||
|
# NOTE: Relax Bun version check to be a warning instead of an error
|
||||||
|
./relax-bun-version-check.patch
|
||||||
|
];
|
||||||
|
|
||||||
|
dontConfigure = true;
|
||||||
|
|
||||||
|
env.MODELS_DEV_API_JSON = "${models-dev}/dist/_api.json";
|
||||||
|
env.OPENCODE_VERSION = finalAttrs.version;
|
||||||
|
env.OPENCODE_CHANNEL = "stable";
|
||||||
|
|
||||||
|
buildPhase = ''
|
||||||
|
runHook preBuild
|
||||||
|
|
||||||
|
# Copy all node_modules including the .bun directory with actual packages
|
||||||
|
cp -r ${finalAttrs.node_modules}/node_modules .
|
||||||
|
cp -r ${finalAttrs.node_modules}/packages .
|
||||||
|
|
||||||
|
(
|
||||||
|
cd packages/opencode
|
||||||
|
|
||||||
|
# Fix symlinks to workspace packages
|
||||||
|
chmod -R u+w ./node_modules
|
||||||
|
mkdir -p ./node_modules/@opencode-ai
|
||||||
|
rm -f ./node_modules/@opencode-ai/{script,sdk,plugin}
|
||||||
|
ln -s $(pwd)/../../packages/script ./node_modules/@opencode-ai/script
|
||||||
|
ln -s $(pwd)/../../packages/sdk/js ./node_modules/@opencode-ai/sdk
|
||||||
|
ln -s $(pwd)/../../packages/plugin ./node_modules/@opencode-ai/plugin
|
||||||
|
|
||||||
|
# Use upstream bundle.ts for Nix-compatible bundling
|
||||||
|
cp ../../nix/bundle.ts ./bundle.ts
|
||||||
|
chmod +x ./bundle.ts
|
||||||
|
bun run ./bundle.ts
|
||||||
|
)
|
||||||
|
|
||||||
|
runHook postBuild
|
||||||
|
'';
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
runHook preInstall
|
||||||
|
|
||||||
|
cd packages/opencode
|
||||||
|
if [ ! -d dist ]; then
|
||||||
|
echo "ERROR: dist directory missing after bundle step"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p $out/lib/opencode
|
||||||
|
cp -r dist $out/lib/opencode/
|
||||||
|
chmod -R u+w $out/lib/opencode/dist
|
||||||
|
|
||||||
|
# Select bundled worker assets deterministically (sorted find output)
|
||||||
|
worker_file=$(find "$out/lib/opencode/dist" -type f \( -path '*/tui/worker.*' -o -name 'worker.*' \) | sort | head -n1)
|
||||||
|
parser_worker_file=$(find "$out/lib/opencode/dist" -type f -name 'parser.worker.*' | sort | head -n1)
|
||||||
|
if [ -z "$worker_file" ]; then
|
||||||
|
echo "ERROR: bundled worker not found"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
main_wasm=$(printf '%s\n' "$out"/lib/opencode/dist/tree-sitter-*.wasm | sort | head -n1)
|
||||||
|
wasm_list=$(find "$out/lib/opencode/dist" -maxdepth 1 -name 'tree-sitter-*.wasm' -print)
|
||||||
|
for patch_file in "$worker_file" "$parser_worker_file"; do
|
||||||
|
[ -z "$patch_file" ] && continue
|
||||||
|
[ ! -f "$patch_file" ] && continue
|
||||||
|
if [ -n "$wasm_list" ] && grep -q 'tree-sitter' "$patch_file"; then
|
||||||
|
# Rewrite wasm references to absolute store paths to avoid runtime resolve failures.
|
||||||
|
bun --bun ../../nix/scripts/patch-wasm.ts "$patch_file" "$main_wasm" $wasm_list
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
mkdir -p $out/lib/opencode/node_modules
|
||||||
|
cp -r ../../node_modules/.bun $out/lib/opencode/node_modules/
|
||||||
|
mkdir -p $out/lib/opencode/node_modules/@opentui
|
||||||
|
|
||||||
|
# Generate and install JSON schema
|
||||||
|
mkdir -p $out/share/opencode
|
||||||
|
HOME=$TMPDIR bun --bun script/schema.ts $out/share/opencode/schema.json
|
||||||
|
|
||||||
|
mkdir -p $out/bin
|
||||||
|
makeWrapper ${lib.getExe bun} $out/bin/opencode \
|
||||||
|
--add-flags "run" \
|
||||||
|
--add-flags "$out/lib/opencode/dist/src/index.js" \
|
||||||
|
--prefix PATH : ${lib.makeBinPath [fzf ripgrep]} \
|
||||||
|
--argv0 opencode
|
||||||
|
|
||||||
|
runHook postInstall
|
||||||
|
'';
|
||||||
|
|
||||||
|
postInstall = ''
|
||||||
|
# Add symlinks for platform-specific native modules
|
||||||
|
pkgs=(
|
||||||
|
$out/lib/opencode/node_modules/.bun/@opentui+core-*
|
||||||
|
$out/lib/opencode/node_modules/.bun/@opentui+solid-*
|
||||||
|
$out/lib/opencode/node_modules/.bun/@opentui+core@*
|
||||||
|
$out/lib/opencode/node_modules/.bun/@opentui+solid@*
|
||||||
|
)
|
||||||
|
for pkg in "''${pkgs[@]}"; do
|
||||||
|
if [ -d "$pkg" ]; then
|
||||||
|
pkgName=$(basename "$pkg" | sed 's/@opentui+\([^@]*\)@.*/\1/')
|
||||||
|
ln -sf ../.bun/$(basename "$pkg")/node_modules/@opentui/$pkgName \
|
||||||
|
$out/lib/opencode/node_modules/@opentui/$pkgName
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
${lib.optionalString
|
||||||
|
((stdenvNoCC.buildPlatform.canExecute stdenvNoCC.hostPlatform)
|
||||||
|
&& (stdenvNoCC.hostPlatform.system != "x86_64-darwin")) ''
|
||||||
|
installShellCompletion --cmd opencode \
|
||||||
|
--bash <($out/bin/opencode completion)
|
||||||
|
''}
|
||||||
|
'';
|
||||||
|
|
||||||
|
passthru = {
|
||||||
|
jsonschema = "${placeholder "out"}/share/opencode/schema.json";
|
||||||
|
tests.version = testers.testVersion {
|
||||||
|
package = finalAttrs.finalPackage;
|
||||||
|
command = "HOME=$(mktemp -d) opencode --version";
|
||||||
|
inherit (finalAttrs) version;
|
||||||
|
};
|
||||||
|
updateScript =
|
||||||
|
nix-update-script {extraArgs = ["--subpackage" "node_modules"];};
|
||||||
|
};
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description = "AI coding agent built for the terminal";
|
||||||
|
longDescription = ''
|
||||||
|
OpenCode is a terminal-based agent that can build anything.
|
||||||
|
It combines a TypeScript/JavaScript core with a Go-based TUI
|
||||||
|
to provide an interactive AI coding experience.
|
||||||
|
'';
|
||||||
|
homepage = "https://github.com/anomalyco/opencode";
|
||||||
|
license = lib.licenses.mit;
|
||||||
|
maintainers = with lib.maintainers; [delafthi];
|
||||||
|
sourceProvenance = with lib.sourceTypes; [fromSource];
|
||||||
|
platforms = ["aarch64-linux" "x86_64-linux" "aarch64-darwin" "x86_64-darwin"];
|
||||||
|
mainProgram = "opencode";
|
||||||
|
};
|
||||||
|
})
|
||||||
28
pkgs/opencode/relax-bun-version-check.patch
Normal file
28
pkgs/opencode/relax-bun-version-check.patch
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
From 0e07ea8225f5667e39c6aa59eea726266f0afab0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= <joerg@thalheim.io>
|
||||||
|
Date: Thu, 13 Nov 2025 10:16:31 +0100
|
||||||
|
Subject: [PATCH] Change Bun version check from error to warning
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Signed-off-by: Jörg Thalheim <joerg@thalheim.io>
|
||||||
|
---
|
||||||
|
packages/script/src/index.ts | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/packages/script/src/index.ts b/packages/script/src/index.ts
|
||||||
|
index 141d2b75..de06d0dc 100644
|
||||||
|
--- a/packages/script/src/index.ts
|
||||||
|
+++ b/packages/script/src/index.ts
|
||||||
|
@@ -10,7 +10,7 @@ if (!expectedBunVersion) {
|
||||||
|
}
|
||||||
|
|
||||||
|
if (process.versions.bun !== expectedBunVersion) {
|
||||||
|
- throw new Error(`This script requires bun@${expectedBunVersion}, but you are using bun@${process.versions.bun}`)
|
||||||
|
+ console.warn(`Warning: This script expects bun@${expectedBunVersion}, but you are using bun@${process.versions.bun}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const CHANNEL = process.env["OPENCODE_CHANNEL"] ?? (await $`git branch --show-current`.text().then((x) => x.trim()))
|
||||||
|
--
|
||||||
|
2.51.0
|
||||||
Reference in New Issue
Block a user