From 908854e516975c80ceffe5dc8133b950b545fd9c Mon Sep 17 00:00:00 2001 From: Microck Date: Fri, 31 Jul 2026 02:10:13 +0000 Subject: [PATCH 1/3] feat: add nix flake packaging --- README.md | 17 +++++++++++++++ flake.lock | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++ flake.nix | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++ nix/kagi.nix | 39 +++++++++++++++++++++++++++++++++ 4 files changed, 177 insertions(+) create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 nix/kagi.nix diff --git a/README.md b/README.md index 65e316a..250d07e 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,23 @@ scoop install kagi yay -S kagi-cli ``` +### nix / nixos + +run it without installing: + +```bash +nix run github:Microck/kagi-cli -- search "rust async" +``` + +install it into your Nix profile: + +```bash +nix profile install github:Microck/kagi-cli +``` + +for NixOS or home-manager, add the flake as an input and use its default +package or `overlays.default`. + ### auth run the guided setup: diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..4e41dd2 --- /dev/null +++ b/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1781074563, + "narHash": "sha256-md8WlXOlfnIeHeOScMTTHFyf2d6iaTwPl2apR5EQ3P4=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "9ae611a455b90cf061d8f332b977e387bda8e1ca", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..fc90e68 --- /dev/null +++ b/flake.nix @@ -0,0 +1,60 @@ +{ + description = "terminal CLI for Kagi subscribers with JSON-first search output"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = + { + self, + nixpkgs, + flake-utils, + }: + let + overlay = final: prev: { + kagi = final.callPackage ./nix/kagi.nix { }; + }; + in + flake-utils.lib.eachDefaultSystem ( + system: + let + pkgs = import nixpkgs { + inherit system; + overlays = [ overlay ]; + }; + in + { + packages = { + default = pkgs.kagi; + kagi = pkgs.kagi; + }; + + apps.default = { + type = "app"; + program = "${pkgs.kagi}/bin/kagi"; + meta.description = "Run the kagi CLI"; + }; + + checks.kagi = pkgs.kagi; + + devShells.default = pkgs.mkShell { + inputsFrom = [ pkgs.kagi ]; + packages = with pkgs; [ + cargo + rustc + clippy + rustfmt + rust-analyzer + ]; + RUST_SRC_PATH = "${pkgs.rustPlatform.rustLibSrc}"; + }; + + formatter = pkgs.nixfmt; + } + ) + // { + overlays.default = overlay; + }; +} diff --git a/nix/kagi.nix b/nix/kagi.nix new file mode 100644 index 0000000..5420c24 --- /dev/null +++ b/nix/kagi.nix @@ -0,0 +1,39 @@ +{ + lib, + rustPlatform, + installShellFiles, + stdenv, +}: + +let + cargoToml = lib.importTOML ../Cargo.toml; +in +rustPlatform.buildRustPackage { + pname = cargoToml.package.name; + version = cargoToml.package.version; + + src = lib.cleanSource ../.; + cargoLock.lockFile = ../Cargo.lock; + + # reqwest uses rustls-tls, so the package does not need OpenSSL or pkg-config. + nativeBuildInputs = [ installShellFiles ]; + + # The test suite uses local mock servers and can run in the sandbox. + doCheck = true; + + postInstall = lib.optionalString (stdenv.buildPlatform.canExecute stdenv.hostPlatform) '' + installShellCompletion --cmd kagi \ + --bash <($out/bin/kagi --generate-completion bash) \ + --zsh <($out/bin/kagi --generate-completion zsh) \ + --fish <($out/bin/kagi --generate-completion fish) + ''; + + meta = { + description = cargoToml.package.description; + homepage = "https://github.com/Microck/kagi-cli"; + changelog = "https://github.com/Microck/kagi-cli/blob/main/CHANGELOG.md"; + license = lib.licenses.mit; + mainProgram = "kagi"; + platforms = lib.platforms.unix; + }; +} From 95f8b6b92619d4a1ad26dc7ea889f517cbf15167 Mon Sep 17 00:00:00 2001 From: Microck Date: Fri, 31 Jul 2026 02:17:32 +0000 Subject: [PATCH 2/3] fix: guard nix checks during cross builds --- nix/kagi.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nix/kagi.nix b/nix/kagi.nix index 5420c24..8331fbf 100644 --- a/nix/kagi.nix +++ b/nix/kagi.nix @@ -18,8 +18,8 @@ rustPlatform.buildRustPackage { # reqwest uses rustls-tls, so the package does not need OpenSSL or pkg-config. nativeBuildInputs = [ installShellFiles ]; - # The test suite uses local mock servers and can run in the sandbox. - doCheck = true; + # Skip tests when the build host cannot execute the target binary. + doCheck = stdenv.buildPlatform.canExecute stdenv.hostPlatform; postInstall = lib.optionalString (stdenv.buildPlatform.canExecute stdenv.hostPlatform) '' installShellCompletion --cmd kagi \ From 4a3b9bf0b9912c2f8fcf980b1ac430fb65541817 Mon Sep 17 00:00:00 2001 From: Microck Date: Fri, 31 Jul 2026 02:27:48 +0000 Subject: [PATCH 3/3] docs: add nix installation guide --- docs/guides/installation.mdx | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/docs/guides/installation.mdx b/docs/guides/installation.mdx index 5c1cd2a..bae4987 100644 --- a/docs/guides/installation.mdx +++ b/docs/guides/installation.mdx @@ -17,6 +17,7 @@ The *kagi* CLI can be installed through several methods: | Package Managers | System integration | Low | Automatic | | GitHub Releases | Specific versions | Medium | Manual | | Build from Source | Development, customization | High | Manual | +| Nix Flake | NixOS, Home Manager, reproducible installs | Medium | Manual | ## Quick Install (Recommended) @@ -191,6 +192,26 @@ cargo install --path . **Note on crates.io:** The package is not currently published to crates.io because both `kagi` and `kagi-cli` names are already taken. GitHub Releases remain the canonical distribution method. +### Nix / NixOS + +The repository includes a flake for Nix users. It provides the CLI package, a runnable app, shell completions, and a development shell. + +Run the CLI without installing it: + +```bash +nix run github:Microck/kagi-cli -- search "rust async" +``` + +Install it into your Nix profile: + +```bash +nix profile install github:Microck/kagi-cli +``` + +For NixOS or Home Manager, add `github:Microck/kagi-cli` as a flake input. Use `kagi.packages.${system}.default` for the package or `kagi.overlays.default` in your package set. + +Authentication works the same as with other installation methods. Run `kagi auth` after installation or set the required Kagi environment variable. + ## Manual Installation from GitHub Releases For users who want full control over the installation process or need to install a specific version.