{ description = "tarp - an infinite canvas of Ghostty terminals, built on gpui"; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; fenix = { url = "github:nix-community/fenix"; inputs.nixpkgs.follows = "nixpkgs"; }; ghostty.url = "github:ghostty-org/ghostty/a887df42c56f6de86c0fe6da9c4eeca37931e083"; gpui-canvas = { url = "git+https://tangled.org/oppi.li/gpui-canvas"; flake = false; }; gpui-terminal = { url = "git+https://tangled.org/oppi.li/gpui-terminal"; flake = false; }; }; outputs = { self, nixpkgs, fenix, ghostty, gpui-canvas, gpui-terminal, }: let lib = nixpkgs.lib; systems = ["aarch64-darwin" "x86_64-linux" "aarch64-linux"]; forAllSystems = lib.genAttrs systems; nixpkgsFor = forAllSystems (system: import nixpkgs {inherit system;}); platform = system: let pkgs = nixpkgsFor.${system}; isDarwin = pkgs.stdenv.hostPlatform.isDarwin; llvmPackages = pkgs.llvmPackages_20; rustToolchain = fenix.packages.${system}.fromToolchainFile { file = ./rust-toolchain.toml; sha256 = "sha256-9LY9sgDes2oSCyeuCFFAY37gSvElSJEwh5kiXlr76L8="; }; linuxGuiLibs = [ pkgs.fontconfig pkgs.freetype pkgs.libxkbcommon pkgs.wayland pkgs.wayland-protocols pkgs.libx11 pkgs.libxcursor pkgs.libxrandr pkgs.libxi pkgs.libxcb pkgs.libGL pkgs.mesa pkgs.vulkan-loader pkgs.vulkan-headers ]; in { inherit pkgs llvmPackages rustToolchain isDarwin linuxGuiLibs; }; source = pkgs: pkgs.runCommand "tarp-workspace" {} '' mkdir -p $out/tarp $out/gpui-canvas $out/gpui-terminal cp -r ${self}/. $out/tarp/ cp -r ${gpui-canvas}/. $out/gpui-canvas/ cp -r ${gpui-terminal}/. $out/gpui-terminal/ ''; packagesFor = system: let p = platform system; inherit (p) pkgs isDarwin; rustPlatform = pkgs.makeRustPlatform { cargo = p.rustToolchain; rustc = p.rustToolchain; }; common = { version = "0.1.0"; src = source pkgs; sourceRoot = "tarp-workspace"; cargoRoot = "tarp"; buildAndTestSubdir = "tarp"; cargoHash = "sha256-eRT1RsuHIfdb8ENuI/SkzkJIs8i48JEgqRiaO3mx6Jo="; doCheck = false; dontUseZigConfigure = true; dontUseZigBuild = true; dontUseZigCheck = true; dontUseZigInstall = true; nativeBuildInputs = [pkgs.zig_0_15 pkgs.pkg-config p.llvmPackages.bintools] ++ lib.optionals isDarwin [pkgs.cctools pkgs.xcbuild]; buildInputs = lib.optional isDarwin pkgs.libiconv; env = { GHOSTTY_SOURCE_DIR = "${ghostty}"; GHOSTTY_ZIG_SYSTEM_DIR = "${ghostty.packages.${system}.deps}"; ZIG_GLOBAL_CACHE_DIR = "zig-global-cache"; } // lib.optionalAttrs isDarwin { SDKROOT = "${pkgs.apple-sdk.sdkroot}"; DEVELOPER_DIR = "${pkgs.apple-sdk}"; }; preBuild = "unset AS"; meta = { platforms = lib.platforms.unix; mainProgram = "tarpd"; }; }; tarpd = rustPlatform.buildRustPackage (common // { pname = "tarpd"; cargoBuildFlags = ["-p" "tarpd"]; meta = common.meta // { description = "The tarp terminal daemon"; mainProgram = "tarpd"; }; }); # the tarp client: the `tarp` cli, plus the gpui interface when `ui` is set. client = {ui}: rustPlatform.buildRustPackage (common // { pname = if ui then "tarp-ui" else "tarp"; cargoBuildFlags = ["-p" "tarp"]; buildNoDefaultFeatures = true; meta = common.meta // { description = if ui then "The tarp terminal client with the gpui interface" else "The tarp terminal client (headless)"; mainProgram = "tarp"; }; } // lib.optionalAttrs ui { buildFeatures = ["ui"]; buildInputs = common.buildInputs ++ lib.optionals (!isDarwin) p.linuxGuiLibs; postInstall = lib.optionalString isDarwin '' mkdir -p $out/Applications cp -r tarp/extra/macos/Tarp.app $out/Applications/ chmod -R u+w $out/Applications/Tarp.app mkdir -p $out/Applications/Tarp.app/Contents/Resources cp ${icon}/tarp.icns $out/Applications/Tarp.app/Contents/Resources/ ln -s $out/bin $out/Applications/Tarp.app/Contents/MacOS ''; passthru = {inherit icon;}; }); tarp = client {ui = false;}; tarp-ui = client {ui = true;}; icon = pkgs.runCommand "tarp-icns" { nativeBuildInputs = [pkgs.librsvg pkgs.libicns]; } '' for size in 16 32 48 128 256 512 1024; do rsvg-convert -w $size -h $size ${./extra/macos/tarp.svg} -o tarp_$size.png done mkdir -p $out png2icns $out/tarp.icns tarp_*.png ''; in { inherit tarpd tarp tarp-ui; default = tarpd; }; in { formatter = forAllSystems (system: let p = platform system; pkgs = p.pkgs; in pkgs.treefmt.withConfig { settings.formatter = { alejandra = { command = pkgs.lib.getExe pkgs.alejandra; includes = ["*.nix"]; }; rustfmt = { command = pkgs.lib.getExe' p.rustToolchain "rustfmt"; includes = ["*.rs"]; }; taplo = { command = pkgs.lib.getExe pkgs.taplo; options = ["fmt"]; includes = ["*.toml"]; }; }; }); devShells = forAllSystems (system: let p = platform system; pkgs = p.pkgs; linuxLibs = p.linuxGuiLibs; in { default = (pkgs.mkShell.override {stdenv = p.llvmPackages.stdenv;}) { name = "tarp-dev"; packages = [ p.rustToolchain pkgs.rust-analyzer pkgs.git # ghostty a887df42 requires zig 0.15.2. pkgs.zig_0_15 ] ++ ( if p.isDarwin then [pkgs.cctools] else [] ) ++ [p.llvmPackages.bintools] ++ ( if p.isDarwin then [] else [ pkgs.pkg-config pkgs.dbus pkgs.mesa pkgs.vulkan-loader pkgs.vulkan-tools pkgs.sway pkgs.wayvnc pkgs.grim pkgs.wlr-randr ] ); buildInputs = if p.isDarwin then [pkgs.libiconv] else linuxLibs; env = { LIBCLANG_PATH = pkgs.lib.makeLibraryPath [p.llvmPackages.clang-unwrapped.lib]; SSL_CERT_FILE = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"; GHOSTTY_SOURCE_DIR = "${ghostty}"; GHOSTTY_ZIG_SYSTEM_DIR = "${ghostty.packages.${system}.deps}"; } // ( if p.isDarwin then { SDKROOT = "${pkgs.apple-sdk.sdkroot}"; DEVELOPER_DIR = "${pkgs.apple-sdk}"; } else { GBM_BACKENDS_PATH = "${pkgs.mesa}/lib/gbm"; LIBGL_DRIVERS_PATH = "${pkgs.mesa}/lib/dri"; VK_DRIVER_FILES = "${pkgs.mesa}/share/vulkan/icd.d"; LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath linuxLibs; } ); shellHook = '' unset AS export ZIG_GLOBAL_CACHE_DIR="$PWD/.zig-cache" ''; }; }); packages = forAllSystems packagesFor; nixosModules = { default = import ./nix/module.nix self; tarpd = self.nixosModules.default; }; darwinModules = { default = import ./nix/darwin-module.nix self; tarpd = self.darwinModules.default; }; homeManagerModules = { default = import ./nix/home-module.nix self; tarp = self.homeManagerModules.default; }; }; }