# Nix flake for ai-memory.
#
# Provides:
# nix build # → result/bin/ai-memory (native release binary)
# nix run . -- --version # smoke-test without installing
# nix develop # dev shell with Rust 1.95 (pinned)
#
# The build is self-contained: SQLite is bundled via rusqlite's `bundled`
# feature, libgit2 is vendored via git2's `vendored-libgit2` feature, and
# TLS uses rustls (webpki-roots) — no OpenSSL, no system-library hunting.
# The only extra step is TAILWIND_SKIP=1 so the web crate's build script
# uses the vendored static/tailwind.css instead of downloading the
# Tailwind CLI (which a sandboxed Nix build cannot do).
#
# `doCheck = false` skips the packaging test suite. Those tests exercise
# `bin/ai-memory`, a Docker-wrapper shell script that needs `docker` or
# `podman` on PATH — they are host-environment tests, not build tests,
# and are not Nix's responsibility. Run them manually with
# `nix develop -c cargo test -p ai-memory-cli --test packaging` if your
# machine has Docker.
{
description = "Long-term memory for AI coding agents";
# Inputs are pinned to explicit revisions rather than floating branches.
#
# A flake's value is reproducibility, and `github:NixOS/nixpkgs/nixos-unstable`
# resolves to whatever that branch points at today, so two people — or the
# same person a week apart — can get different builds from identical source.
# Normally `flake.lock` handles this; pinning here achieves the same
# determinism and keeps the tree honest for contributors who do not have
# Nix installed and so cannot regenerate a lock.
#
# To update: bump these revisions deliberately, in their own commit, and
# let the `nix` CI job prove the result still builds.
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/0ae2bc1419c3f345984c2629e72e7a631820fa4d";
flake-utils.url = "github:numtide/flake-utils/11707dc2f618dd54ca8739b309ec4fc024de578b";
rust-overlay = {
url = "github:oxalica/rust-overlay/99607a06c2ea1290cd3258c11d1416dde9201f94";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs =
{
nixpkgs,
flake-utils,
rust-overlay,
...
}:
flake-utils.lib.eachDefaultSystem (
system:
let
pkgs = import nixpkgs {
inherit system;
overlays = [ (import rust-overlay) ];
};
# Read the same toolchain file the project pins for every other CI
# path — rust-toolchain.toml says `channel = "1.95"`.
rust = pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml;
rustPlatform = pkgs.makeRustPlatform {
rustc = rust;
cargo = rust;
};
in
{
packages.default = rustPlatform.buildRustPackage {
pname = "ai-memory";
version = (builtins.fromTOML (builtins.readFile ./Cargo.toml)).workspace.package.version;
src = ./.;
cargoLock.lockFile = ./Cargo.lock;
# No nativeBuildInputs needed — the build is fully self-contained
# (SQLite bundled, libgit2 vendored, rustls with webpki-roots).
# Skip the Tailwind CLI download in the sandbox. The build script
# falls back to the vendored static/tailwind.css committed to the
# repo (see crates/ai-memory-web/build.rs).
TAILWIND_SKIP = "1";
buildType = "release";
# The packaging test suite (tests/packaging.rs) exercises the
# Docker-wrapper shell script `bin/ai-memory` and needs
# docker/podman on PATH — not available in a Nix sandbox. The
# rest of the workspace test suite (unit tests + integration)
# does not need them and can be run via `nix develop -c cargo
# test --workspace` on a machine with Docker.
doCheck = false;
# Install the bundled hook scripts alongside the binary,
# mirroring what the AUR PKGBUILD does. Native binary users
# (`ai-memory serve`, `install-hooks`) look up hooks under
# the binary's share directory at runtime.
#
# `bin/ai-memory` (the Docker-wrapper shell script) is NOT
# installed — Nix users build the native binary directly and
# have no need for a Docker wrapper.
postInstall = ''
mkdir -p $out/share/ai-memory
cp -a hooks $out/share/ai-memory/
# Install the default config template so `ai-memory init`
# has a known-good starting point without a network fetch.
mkdir -p $out/etc/ai-memory
cp crates/ai-memory-cli/templates/config.default.toml \
$out/etc/ai-memory/config.default.toml
'';
meta = {
description = "Long-term memory for AI coding agents";
homepage = "https://github.com/akitaonrails/ai-memory";
license = pkgs.lib.licenses.mit;
mainProgram = "ai-memory";
};
};
devShells.default = pkgs.mkShell {
name = "ai-memory-dev";
buildInputs = [
rust
pkgs.cargo-watch
];
# Same escape hatch for local `cargo build` / `cargo test` —
# prevents the web crate from trying to download Tailwind.
TAILWIND_SKIP = "1";
shellHook = ''
echo ""
echo "ai-memory dev shell — Rust $(rustc --version)"
echo ""
echo " cargo build --workspace # build"
echo " cargo test --workspace # unit + integration tests"
echo " cargo test -p ai-memory-cli --test packaging # needs docker"
echo ""
'';
};
}
);
}