1{
  2  description = "Crush is a tool for building software with AI";
  3
  4  inputs = {
  5    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
  6  };
  7
  8  outputs =
  9    { self, nixpkgs, ... }:
 10    let
 11      allSystems = [
 12        "x86_64-linux" # 64-bit Intel/AMD Linux
 13        "aarch64-linux" # 64-bit ARM Linux
 14        "x86_64-darwin" # 64-bit Intel macOS
 15        "aarch64-darwin" # 64-bit ARM macOS
 16      ];
 17      forAllSystems =
 18        f:
 19        nixpkgs.lib.genAttrs allSystems (
 20          system:
 21          f {
 22            pkgs = import nixpkgs { inherit system; };
 23          }
 24        );
 25    in
 26    {
 27      nixosModules.default =
 28        {
 29          config,
 30          lib,
 31          pkgs,
 32          ...
 33        }:
 34        let
 35          crushOptions = import ./nix/options.nix { inherit lib; };
 36        in
 37        {
 38          options = {
 39            programs.crush = {
 40              enable = lib.mkEnableOption "Enable crush";
 41              settings = crushOptions;
 42            };
 43          };
 44
 45          config = lib.mkIf config.programs.crush.enable {
 46            environment.systemPackages = [ self.packages.${pkgs.system}.default ];
 47
 48            environment.etc."crush/crush.json" = lib.mkIf (config.programs.crush.settings != { }) {
 49              text = builtins.toJSON config.programs.crush.settings;
 50              mode = "0644";
 51            };
 52          };
 53        };
 54
 55      homeManagerModules.default =
 56        {
 57          config,
 58          lib,
 59          pkgs,
 60          ...
 61        }:
 62        let
 63          crushOptions = import ./nix/options.nix { inherit lib; };
 64        in
 65        {
 66          options = {
 67            programs.crush = {
 68              enable = lib.mkEnableOption "Enable crush";
 69              settings = crushOptions;
 70            };
 71          };
 72
 73          config = lib.mkIf config.programs.crush.enable {
 74            home.packages = [ self.packages.${pkgs.system}.default ];
 75
 76            home.file.".config/crush/crush.json" = lib.mkIf (config.programs.crush.settings != { }) {
 77              text = builtins.toJSON config.programs.crush.settings;
 78            };
 79          };
 80        };
 81
 82      packages = forAllSystems (
 83        { pkgs }:
 84        let
 85          version = if self ? rev then self.rev else "dirty";
 86          crush = pkgs.buildGoModule {
 87            pname = "crush";
 88            inherit version;
 89            subPackages = [ "." ]; # Build from root directory
 90            src = self;
 91            vendorHash = "sha256-DoOYptWZvhAHPT9/m3jAui5KMDdZpIChJboRktM/D9U=";
 92
 93            ldflags = [
 94              "-s"
 95              "-w"
 96              "-X github.com/charmbracelet/crush/internal/version.Version=${version}"
 97            ];
 98
 99            nativeBuildInputs = [ pkgs.installShellFiles ];
100
101            postInstall = ''
102              installShellCompletion --cmd crush \
103                --bash <($out/bin/crush completion bash) \
104                --fish <($out/bin/crush completion fish) \
105                --zsh <($out/bin/crush completion zsh)
106
107              # Generate and install man page
108              $out/bin/crush man > crush.1
109              installManPage crush.1
110            '';
111
112            meta = with pkgs.lib; {
113              description = "A tool for building software with AI";
114              homepage = "https://github.com/charmbracelet/crush";
115              license = licenses.mit;
116              maintainers = with maintainers; [ taciturnaxolotl ];
117              platforms = platforms.linux ++ platforms.darwin;
118            };
119          };
120        in
121        {
122          default = crush;
123        }
124      );
125
126      apps = forAllSystems (
127        { pkgs }:
128        {
129          default = {
130            type = "app";
131            program = "${self.packages.${pkgs.system}.default}/bin/crush";
132          };
133        }
134      );
135
136      formatter = forAllSystems ({ pkgs }: pkgs.nixfmt-tree);
137    };
138}