okami.mom/albedo

git clone https://git.nkp.pet/okami.mom/albedo

nekomimi.pettui: one delimiter table for math, bytes.Cut over hand scans, and the fork's IndentWriter for list itemse4c3bd6

main
6.4 KiB202 linesraw
1{
2  lib,
3  stdenv,
4  rustPlatform,
5  buildGoModule,
6  symlinkJoin,
7  fetchurl,
8  gleam,
9  beamPackages,
10  python311,
11  bash,
12  coreutils,
13  makeWrapper,
14  chrome-headless-shell,
15  wl-clipboard,
16  xclip,
17  zig,
18  usage-core,
19}: let
20  inherit (beamPackages) erlang;
21  clipboardTools = 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.
24  rebar3 = beamPackages.rebar3WithPlugins {plugins = [beamPackages.pc];};
25  manifest = builtins.fromTOML (builtins.readFile ./manifest.toml);
26  serverSource = lib.fileset.toSource {
27    root = ./.;
28    fileset = lib.fileset.unions [
29      ./gleam.toml
30      ./manifest.toml
31      ./src
32      (lib.fileset.fileFilter (file: !file.hasExt "pyc") ./priv)
33    ];
34  };
35  clientSource = lib.fileset.toSource {
36    root = ./.;
37    fileset = lib.fileset.unions [
38      ./cli/go.mod
39      ./cli/go.sum
40      ./cli/cmd
41      ./cli/internal
42      ./test/fixtures/build-digest
43    ];
44  };
45  hexPackages =
46    map (p: {
47      inherit (p) name version;
48      archive = fetchurl {
49        url = "https://repo.hex.pm/tarballs/${p.name}-${p.version}.tar";
50        sha256 = lib.toLower p.outer_checksum;
51      };
52    })
53    manifest.packages;
54  packageIndex = builtins.toFile "packages.toml" ("[packages]\n"
55    + lib.concatMapStrings
56    (p: "${p.name} = \"${p.version}\"\n")
57    hexPackages
58    + "\n[git]\n");
59  renderSource = lib.fileset.toSource {
60    root = ./native/render;
61    fileset = 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  };
69  render = rustPlatform.buildRustPackage {
70    pname = "albedo-render";
71    version = "0.1.0";
72    src = renderSource;
73    cargoLock.lockFile = ./native/render/Cargo.lock;
74    meta = {
75      description = "renders a range of a source file as syntax-highlighted PNG pages";
76      license = lib.licenses.wtfpl;
77      mainProgram = "albedo-render";
78      platforms = 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.
84  usageCore = stdenv.mkDerivation {
85    pname = "usage-core";
86    version = "0.1.0";
87    src = 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.
90    unpackPhase = ''
91      runHook preUnpack
92      tar -xzf $src
93      runHook postUnpack
94    '';
95    sourceRoot = "provide-usage-main";
96    nativeBuildInputs = [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.
99    buildPhase = ''
100      runHook preBuild
101      export HOME="$TMPDIR/home"
102      zig build --cache-dir "$TMPDIR/zig-cache" --global-cache-dir "$TMPDIR/zig-global-cache"
103      runHook postBuild
104    '';
105    installPhase = ''
106      runHook preInstall
107      mkdir -p $out/bin
108      cp zig-out/bin/usage $out/bin/usage
109      runHook postInstall
110    '';
111    meta = {
112      description = "stateless provider usage and quota core with a CLI";
113      mainProgram = "usage";
114      platforms = lib.platforms.unix;
115    };
116  };
117  server = stdenv.mkDerivation {
118    pname = "albedo-server";
119    version = "1.0.0";
120    src = serverSource;
121    nativeBuildInputs = [gleam erlang rebar3 makeWrapper];
122    buildPhase = ''
123      runHook preBuild
124      export HOME="$TMPDIR/home"
125      mkdir -p "$HOME" build/packages
126      ${lib.concatMapStringsSep "\n" (p: ''
127          mkdir -p build/packages/${p.name} "$TMPDIR/hex-${p.name}"
128          tar -xf ${p.archive} -C "$TMPDIR/hex-${p.name}"
129          tar -xzf "$TMPDIR/hex-${p.name}/contents.tar.gz" -C build/packages/${p.name}
130        '')
131        hexPackages}
132      cp ${packageIndex} build/packages/packages.toml
133      chmod -R u+w build/packages
134      gleam export erlang-shipment
135      runHook postBuild
136    '';
137    installPhase = ''
138      runHook preInstall
139      mkdir -p $out/lib/albedo $out/bin
140      cp -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
146      mkdir -p $out/lib/albedo/albedo/priv/bin
147      ln -s ${render}/bin/albedo-render $out/lib/albedo/albedo/priv/bin/albedo-render
148      ln -s ${usageCore}/bin/usage $out/lib/albedo/albedo/priv/bin/usage
149      makeWrapper $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]}
153      runHook postInstall
154    '';
155    meta = {
156      description = "coding agent daemon with its runtime and native helpers";
157      license = lib.licenses.wtfpl;
158      mainProgram = "albedo-daemon";
159      platforms = lib.platforms.unix;
160    };
161  };
162  client = buildGoModule {
163    pname = "albedo-client";
164    version = "1.0.0";
165    src = clientSource;
166    modRoot = "cli";
167    subPackages = ["cmd/albedo"];
168    vendorHash = "sha256-bz16aHxbvOD8rxVDCP0bns292AnAL3uEw3tC7zlNZoY=";
169    nativeBuildInputs = [python311 makeWrapper];
170    ALBEDO_NO_BROWSER = "1";
171    ALBEDO_TEST_DAEMON = "${server}/bin/albedo-daemon";
172    postInstall = ''
173      wrapProgram $out/bin/albedo \
174        --prefix PATH : ${lib.makeBinPath clipboardTools}
175    '';
176    meta = {
177      description = "Charm terminal client for the albedo coding agent";
178      license = lib.licenses.wtfpl;
179      mainProgram = "albedo";
180      platforms = lib.platforms.unix;
181    };
182  };
183in
184  symlinkJoin {
185    name = "albedo-${client.version}";
186    paths = [client server];
187    nativeBuildInputs = [makeWrapper];
188    postBuild = ''
189      rm $out/bin/albedo
190      makeWrapper ${client}/bin/albedo $out/bin/albedo \
191        --set-default ALBEDO_DAEMON ${server}/bin/albedo-daemon
192    '';
193    passthru = {
194      inherit client server render usageCore;
195      daemon = server;
196    };
197    meta =
198      client.meta
199      // {
200        description = "coding agent daemon with a Charm terminal client";
201      };
202  }