okami.mom/albedo
git clone https://git.nkp.pet/okami.mom/albedo
e4c3bd6
main
1{ 2lib , 3stdenv , 4rustPlatform , 5buildGoModule , 6symlinkJoin , 7fetchurl , 8gleam , 9beamPackages , 10python311 , 11bash , 12coreutils , 13makeWrapper , 14chrome-headless-shell , 15wl-clipboard , 16xclip , 17zig , 18usage-core , 19} : let 20inherit ( beamPackages ) erlang ; 21clipboardTools = lib . optionals stdenv . hostPlatform . isLinux [ wl-clipboard xclip ]; 22# esqlite loads the pc plugin during its Rebar3 build, which cannot fetch 23# plugins from Hex inside the Nix sandbox. 24rebar3 = beamPackages . rebar3WithPlugins { plugins = [ beamPackages . pc ];}; 25manifest = builtins . fromTOML ( builtins . readFile ./manifest.toml ); 26serverSource = lib . fileset . toSource { 27root = ./. ; 28fileset = lib . fileset . unions [ 29./gleam.toml 30./manifest.toml 31./src 32( lib . fileset . fileFilter ( file: ! file . hasExt "pyc" ) ./priv ) 33]; 34}; 35clientSource = lib . fileset . toSource { 36root = ./. ; 37fileset = lib . fileset . unions [ 38./cli/go.mod 39./cli/go.sum 40./cli/cmd 41./cli/internal 42./test/fixtures/build-digest 43]; 44}; 45hexPackages = 46map ( p: { 47inherit ( p ) name version ; 48archive = fetchurl { 49url = "https://repo.hex.pm/tarballs/ ${ p . name } - ${ p . version } .tar" ; 50sha256 = lib . toLower p . outer_checksum ; 51}; 52}) 53manifest . packages ; 54packageIndex = builtins . toFile "packages.toml" ( "[packages]\n" 55+ lib . concatMapStrings 56( p: " ${ p . name } = \" ${ p . version } \"\n" ) 57hexPackages 58+ "\n[git]\n" ); 59renderSource = lib . fileset . toSource { 60root = ./native/render ; 61fileset = lib . fileset . unions [ 62./native/render/Cargo.toml 63./native/render/Cargo.lock 64./native/render/src 65./native/render/fonts 66./native/render/tests 67]; 68}; 69render = rustPlatform . buildRustPackage { 70pname = "albedo-render" ; 71version = "0.1.0" ; 72src = renderSource ; 73cargoLock . lockFile = ./native/render/Cargo.lock ; 74meta = { 75description = "renders a range of a source file as syntax-highlighted PNG pages" ; 76license = lib . licenses . wtfpl ; 77mainProgram = "albedo-render" ; 78platforms = lib . platforms . unix ; 79}; 80}; 81# The provide-usage CLI: a pure Zig core the daemon drives one round at a 82# time (see robot-docs/usage-feed.md). Pinned by the flake input, built with 83# the toolchain its build.zig.zon demands. 84usageCore = stdenv . mkDerivation { 85pname = "usage-core" ; 86version = "0.1.0" ; 87src = usage-core ; 88# The knot serves the archive with a query string, so the store path has 89# no extension for unpackPhase to sniff: one explicit tar it is. 90unpackPhase = '' 91runHook preUnpack 92tar -xzf $ src 93runHook postUnpack 94'' ; 95sourceRoot = "provide-usage-main" ; 96nativeBuildInputs = [ zig ]; 97# The build.zig ranlib step hardcodes zig-out, so the default prefix it is 98# (no --prefix): artifacts are copied out in installPhase instead. 99buildPhase = '' 100runHook preBuild 101export HOME =" $ TMPDIR /home" 102zig build --cache-dir " $ TMPDIR /zig-cache" --global-cache-dir " $ TMPDIR /zig-global-cache" 103runHook postBuild 104'' ; 105installPhase = '' 106runHook preInstall 107mkdir -p $ out /bin 108cp zig-out/bin/usage $ out /bin/usage 109runHook postInstall 110'' ; 111meta = { 112description = "stateless provider usage and quota core with a CLI" ; 113mainProgram = "usage" ; 114platforms = lib . platforms . unix ; 115}; 116}; 117server = stdenv . mkDerivation { 118pname = "albedo-server" ; 119version = "1.0.0" ; 120src = serverSource ; 121nativeBuildInputs = [ gleam erlang rebar3 makeWrapper ]; 122buildPhase = '' 123runHook preBuild 124export HOME =" $ TMPDIR /home" 125mkdir -p " $ HOME " build/packages 126${ lib . concatMapStringsSep "\n" ( p : '' 127mkdir -p build/packages/ ${ p . name } "$TMPDIR/hex- ${ p . name } " 128tar -xf ${ p . archive } -C "$TMPDIR/hex- ${ p . name } " 129tar -xzf "$TMPDIR/hex- ${ p . name } /contents.tar.gz" -C build/packages/ ${ p . name } 130'' ) 131hexPackages } 132cp ${ packageIndex } build/packages/packages.toml 133chmod -R u+w build/packages 134gleam export erlang-shipment 135runHook postBuild 136'' ; 137installPhase = '' 138runHook preInstall 139mkdir -p $ out /lib/albedo $ out /bin 140cp -R build/erlang-shipment/. $ out /lib/albedo/ 141# Kernels import this python from the read-only store, where Python 142# cannot cache bytecode, so each would compile it again (megabytes per 143# kernel). Hash-checked, because the store resets every mtime. 144${ python311 } /bin/python3 -m compileall -q --invalidation-mode checked-hash \ 145$ out /lib/albedo/albedo/priv/python 146mkdir -p $ out /lib/albedo/albedo/priv/bin 147ln -s ${ render } /bin/albedo-render $ out /lib/albedo/albedo/priv/bin/albedo-render 148ln -s ${ usageCore } /bin/usage $ out /lib/albedo/albedo/priv/bin/usage 149makeWrapper $ out /lib/albedo/albedo/priv/bin/albedo-daemon $ out /bin/albedo-daemon \ 150--add-flags " $ out /lib/albedo/entrypoint.sh run" \ 151--set-default ALBEDO_BUILD $ out /bin/albedo-daemon \ 152--prefix PATH : ${ lib . makeBinPath [ erlang python311 bash coreutils render chrome-headless-shell ]} 153runHook postInstall 154'' ; 155meta = { 156description = "coding agent daemon with its runtime and native helpers" ; 157license = lib . licenses . wtfpl ; 158mainProgram = "albedo-daemon" ; 159platforms = lib . platforms . unix ; 160}; 161}; 162client = buildGoModule { 163pname = "albedo-client" ; 164version = "1.0.0" ; 165src = clientSource ; 166modRoot = "cli" ; 167subPackages = [ "cmd/albedo" ]; 168vendorHash = "sha256-bz16aHxbvOD8rxVDCP0bns292AnAL3uEw3tC7zlNZoY=" ; 169nativeBuildInputs = [ python311 makeWrapper ]; 170ALBEDO_NO_BROWSER = "1" ; 171ALBEDO_TEST_DAEMON = " ${ server } /bin/albedo-daemon" ; 172postInstall = '' 173wrapProgram $ out /bin/albedo \ 174--prefix PATH : ${ lib . makeBinPath clipboardTools } 175'' ; 176meta = { 177description = "Charm terminal client for the albedo coding agent" ; 178license = lib . licenses . wtfpl ; 179mainProgram = "albedo" ; 180platforms = lib . platforms . unix ; 181}; 182}; 183in 184symlinkJoin { 185name = "albedo- ${ client . version } " ; 186paths = [ client server ]; 187nativeBuildInputs = [ makeWrapper ]; 188postBuild = '' 189rm $ out /bin/albedo 190makeWrapper ${ client } /bin/albedo $ out /bin/albedo \ 191--set-default ALBEDO_DAEMON ${ server } /bin/albedo-daemon 192'' ; 193passthru = { 194inherit client server render usageCore ; 195daemon = server ; 196}; 197meta = 198client . meta 199// { 200description = "coding agent daemon with a Charm terminal client" ; 201}; 202}