Nix packages for third-party projects that don't ship their own flakes
0

Configure Feed

Select the types of activity you want to include in your feed.

feat: add whetuu and pullrun packages

Package official multi-platform release binaries for whetuu (shell
prompt) and pullrun (OCI runtime CLI + daemon). Extend the
github-release-binary updater to rewrite multi-platform sources blocks.

author
nandi
date (Jul 23, 2026, 6:57 PM -0700) commit f7712968 parent f3377d26 change-id vkylwvlp
+335 -10
+75 -2
README.md
··· 30 30 | `rook` | [solpbc/rook](https://github.com/solpbc/rook) | `npm install -g @solpbc/rook` | 31 31 | `spinel` | [matz/spinel](https://github.com/matz/spinel) | build from source (`make deps && make && make install`) | 32 32 | `boxd` | [boxd.sh](https://boxd.sh) / [docs](https://docs.boxd.sh/quickstart) | `curl -fsSL https://boxd.sh/downloads/install.sh \| sh` | 33 + | `whetuu` | [yamafaktory/whetuu](https://github.com/yamafaktory/whetuu) | [install script](https://yamafaktory.github.io/whetuu/install.sh) / release tarballs | 34 + | `pullrun` | [pullrun/pullrun](https://github.com/pullrun/pullrun) | `curl -fsSL https://github.com/pullrun/pullrun/raw/main/install.sh \| bash` | 33 35 | `zed-preview` | [zed-industries/zed](https://github.com/zed-industries/zed) (preview channel) | [official Linux installer](https://zed.dev/docs/linux) / `zed-linux-x86_64.tar.gz` | 34 36 35 37 ## Usage ··· 40 42 nix build .#rook 41 43 nix build .#spinel 42 44 nix build .#boxd # x86_64-linux / aarch64-linux / aarch64-darwin 45 + nix build .#whetuu # linux + darwin (all four systems) 46 + nix build .#pullrun # linux + darwin (all four systems) 43 47 nix build .#zed-preview # x86_64-linux only 44 48 45 49 # run without installing ··· 48 52 nix run .#spinel -- --help 49 53 nix run .#spin -- new myapp # spin project tool (from the spinel package) 50 54 nix run .#boxd -- --help 55 + nix run .#whetuu -- --version 56 + nix run .#pullrun -- --version 51 57 nix run .#zed-preview -- --version 52 58 53 59 # install into your profile ··· 55 61 nix profile install .#rook 56 62 nix profile install .#spinel 57 63 nix profile install .#boxd 64 + nix profile install .#whetuu 65 + nix profile install .#pullrun 58 66 nix profile install .#zed-preview 59 67 ``` 60 68 ··· 112 120 113 121 **github-release-binary** — prebuilt release assets (no source build): 114 122 123 + Single-asset: 124 + 115 125 ```json 116 126 { 117 127 "type": "github-release-binary", ··· 122 132 } 123 133 ``` 124 134 135 + Multi-platform (`sources = { … }` block, like `url-manifest-binary`): 136 + 137 + ```json 138 + { 139 + "type": "github-release-binary", 140 + "github": "owner/repo", 141 + "tag_prefix": "v", 142 + "platforms": { 143 + "x86_64-linux": "tool-v{version}-x86_64-linux-musl.tar.gz", 144 + "aarch64-linux": "tool-v{version}-aarch64-linux-musl.tar.gz", 145 + "x86_64-darwin": "tool-v{version}-x86_64-macos.tar.gz", 146 + "aarch64-darwin": "tool-v{version}-aarch64-macos.tar.gz" 147 + } 148 + } 149 + ``` 150 + 125 151 Tracks the newest non-draft GitHub release whose tag matches 126 - `{tag_prefix}{semver}{tag_suffix}` and refreshes the `fetchurl` hash for 127 - `asset`. Used by `zed-preview` (x86_64-linux only). 152 + `{tag_prefix}{semver}{tag_suffix}`. Single-asset mode refreshes one `fetchurl` 153 + hash; multi-platform mode rewrites every `sources.<system>.{url,hash}`. 154 + `{version}` in asset names is the bare version (no tag prefix). Used by 155 + `zed-preview` (single) and `whetuu` (multi). 128 156 129 157 **url-manifest-binary** — prebuilt multi-platform binaries via a version 130 158 manifest URL (not GitHub releases): ··· 237 265 nix hash convert --hash-algo sha256 --to sri <base32> 238 266 ``` 239 267 4. `nix build .#boxd` and smoke-test `./result/bin/boxd --version`. 268 + 269 + ### Manual steps (whetuu) 270 + 271 + `whetuu` ships official multi-platform release tarballs (static musl on Linux). 272 + Prefer the updater: 273 + 274 + ```bash 275 + ./scripts/update-packages.sh whetuu 276 + ``` 277 + 278 + By hand: 279 + 280 + 1. Bump `version` in `packages/whetuu/default.nix` (e.g. `0.1.5`). 281 + 2. Update each `sources.<system>.url` to the matching release asset and prefetch: 282 + ```bash 283 + nix-prefetch-url "https://github.com/yamafaktory/whetuu/releases/download/vX.Y.Z/whetuu-vX.Y.Z-x86_64-linux-musl.tar.gz" 284 + nix-prefetch-url "https://github.com/yamafaktory/whetuu/releases/download/vX.Y.Z/whetuu-vX.Y.Z-aarch64-linux-musl.tar.gz" 285 + nix-prefetch-url "https://github.com/yamafaktory/whetuu/releases/download/vX.Y.Z/whetuu-vX.Y.Z-x86_64-macos.tar.gz" 286 + nix-prefetch-url "https://github.com/yamafaktory/whetuu/releases/download/vX.Y.Z/whetuu-vX.Y.Z-aarch64-macos.tar.gz" 287 + nix hash convert --hash-algo sha256 --to sri <base32> 288 + ``` 289 + 3. `nix build .#whetuu` and smoke-test `./result/bin/whetuu --version`. 290 + 291 + ### Manual steps (pullrun) 292 + 293 + `pullrun` ships official multi-platform release tarballs (CLI + runtime, static). 294 + Prefer the updater: 295 + 296 + ```bash 297 + ./scripts/update-packages.sh pullrun 298 + ``` 299 + 300 + By hand: 301 + 302 + 1. Bump `version` in `packages/pullrun/default.nix` (e.g. `0.6.7`). 303 + 2. Update each `sources.<system>.url` to the matching release asset and prefetch: 304 + ```bash 305 + nix-prefetch-url "https://github.com/pullrun/pullrun/releases/download/vX.Y.Z/pullrun-X.Y.Z-linux-amd64.tar.gz" 306 + nix-prefetch-url "https://github.com/pullrun/pullrun/releases/download/vX.Y.Z/pullrun-X.Y.Z-linux-arm64.tar.gz" 307 + nix-prefetch-url "https://github.com/pullrun/pullrun/releases/download/vX.Y.Z/pullrun-X.Y.Z-darwin-amd64.tar.gz" 308 + nix-prefetch-url "https://github.com/pullrun/pullrun/releases/download/vX.Y.Z/pullrun-X.Y.Z-darwin-arm64.tar.gz" 309 + nix hash convert --hash-algo sha256 --to sri <base32> 310 + ``` 311 + 3. `nix build .#pullrun` and smoke-test `./result/bin/pullrun --version` and 312 + `./result/bin/pullrun-runtime --version`.
+10
flake.nix
··· 34 34 vit = pkgs.callPackage ./packages/vit { }; 35 35 spinel = pkgs.callPackage ./packages/spinel { }; 36 36 rook = pkgs.callPackage ./packages/rook { }; 37 + whetuu = pkgs.callPackage ./packages/whetuu { }; 38 + pullrun = pkgs.callPackage ./packages/pullrun { }; 37 39 default = self.packages.${system}.vit; 38 40 } 39 41 // pkgs.lib.optionalAttrs ( ··· 71 73 rook = { 72 74 type = "app"; 73 75 program = "${self.packages.${system}.rook}/bin/rook"; 76 + }; 77 + whetuu = { 78 + type = "app"; 79 + program = "${self.packages.${system}.whetuu}/bin/whetuu"; 80 + }; 81 + pullrun = { 82 + type = "app"; 83 + program = "${self.packages.${system}.pullrun}/bin/pullrun"; 74 84 }; 75 85 default = self.apps.${system}.vit; 76 86 }
+77
packages/pullrun/default.nix
··· 1 + { 2 + lib, 3 + stdenv, 4 + fetchurl, 5 + versionCheckHook, 6 + }: 7 + 8 + let 9 + # Prebuilt release tarballs from https://github.com/pullrun/pullrun/releases. 10 + # Each archive has pullrun-{os}-{arch} + pullrun-runtime-{os}-{arch} (static). 11 + sources = { 12 + x86_64-linux = { 13 + url = "https://github.com/pullrun/pullrun/releases/download/v0.6.7/pullrun-0.6.7-linux-amd64.tar.gz"; 14 + hash = "sha256-aFIa59shNN+Ptt8vd39fRvY1Gjh5WghZLrAc7lmRtkw="; 15 + }; 16 + aarch64-linux = { 17 + url = "https://github.com/pullrun/pullrun/releases/download/v0.6.7/pullrun-0.6.7-linux-arm64.tar.gz"; 18 + hash = "sha256-Ct0fm26gMwqx9tw96X8TW5xnUZpwC9HXgzn5tDr7cy4="; 19 + }; 20 + x86_64-darwin = { 21 + url = "https://github.com/pullrun/pullrun/releases/download/v0.6.7/pullrun-0.6.7-darwin-amd64.tar.gz"; 22 + hash = "sha256-f9xQJcH5CpcwbHSOZg7K7fWdRjipUkiYMCywbGQ025c="; 23 + }; 24 + aarch64-darwin = { 25 + url = "https://github.com/pullrun/pullrun/releases/download/v0.6.7/pullrun-0.6.7-darwin-arm64.tar.gz"; 26 + hash = "sha256-tj1K0VKI2UnWUT8lqTiXC9MD4qM8R4iYy/AoNBLTr/8="; 27 + }; 28 + }; 29 + 30 + srcAttrs = 31 + sources.${stdenv.hostPlatform.system} 32 + or (throw "pullrun: unsupported system ${stdenv.hostPlatform.system}"); 33 + in 34 + stdenv.mkDerivation (finalAttrs: { 35 + pname = "pullrun"; 36 + version = "0.6.7"; 37 + 38 + src = fetchurl { 39 + inherit (srcAttrs) url hash; 40 + }; 41 + 42 + # Archive root is the two platform-suffixed binaries (no directory wrapper). 43 + sourceRoot = "."; 44 + 45 + installPhase = '' 46 + runHook preInstall 47 + mkdir -p $out/bin 48 + for f in pullrun-*; do 49 + case "$f" in 50 + pullrun-runtime-*) 51 + install -Dm755 "$f" $out/bin/pullrun-runtime 52 + ;; 53 + pullrun-*) 54 + install -Dm755 "$f" $out/bin/pullrun 55 + ;; 56 + esac 57 + done 58 + test -x $out/bin/pullrun 59 + test -x $out/bin/pullrun-runtime 60 + runHook postInstall 61 + ''; 62 + 63 + nativeInstallCheckInputs = [ versionCheckHook ]; 64 + versionCheckProgram = "${placeholder "out"}/bin/pullrun"; 65 + versionCheckProgramArg = "--version"; 66 + doInstallCheck = true; 67 + 68 + meta = { 69 + description = "Container runtime with zero-copy DAG storage — run OCI images as containers, Firecracker microVMs, or Apple Silicon VMs"; 70 + homepage = "https://github.com/pullrun/pullrun"; 71 + changelog = "https://github.com/pullrun/pullrun/releases/tag/v${finalAttrs.version}"; 72 + license = lib.licenses.asl20; 73 + mainProgram = "pullrun"; 74 + platforms = builtins.attrNames sources; 75 + sourceProvenance = with lib.sourceTypes; [ binaryNativeCode ]; 76 + }; 77 + })
+12
packages/pullrun/upstream.json
··· 1 + { 2 + "type": "github-release-binary", 3 + "github": "pullrun/pullrun", 4 + "tag_prefix": "v", 5 + "platforms": { 6 + "x86_64-linux": "pullrun-{version}-linux-amd64.tar.gz", 7 + "aarch64-linux": "pullrun-{version}-linux-arm64.tar.gz", 8 + "x86_64-darwin": "pullrun-{version}-darwin-amd64.tar.gz", 9 + "aarch64-darwin": "pullrun-{version}-darwin-arm64.tar.gz" 10 + }, 11 + "description": "Official multi-platform release tarballs (CLI + runtime). Tracks latest vX.Y.Z GitHub release and refreshes per-platform fetchurl hashes." 12 + }
+65
packages/whetuu/default.nix
··· 1 + { 2 + lib, 3 + stdenv, 4 + fetchurl, 5 + versionCheckHook, 6 + }: 7 + 8 + let 9 + # Prebuilt static (Linux musl) / native (macOS) binaries from GitHub releases. 10 + # Asset names: whetuu-v{version}-{target}.tar.gz — each archive is a single `whetuu`. 11 + sources = { 12 + x86_64-linux = { 13 + url = "https://github.com/yamafaktory/whetuu/releases/download/v0.1.5/whetuu-v0.1.5-x86_64-linux-musl.tar.gz"; 14 + hash = "sha256-YJ8IdY7fe1e9/H1TLer/3Dj5pl4cZUdBwR+oPuHW/4Q="; 15 + }; 16 + aarch64-linux = { 17 + url = "https://github.com/yamafaktory/whetuu/releases/download/v0.1.5/whetuu-v0.1.5-aarch64-linux-musl.tar.gz"; 18 + hash = "sha256-H3EIRQH8GGuzELr5GAPt0tuvZVSaNn85fohu7Vkbq8o="; 19 + }; 20 + x86_64-darwin = { 21 + url = "https://github.com/yamafaktory/whetuu/releases/download/v0.1.5/whetuu-v0.1.5-x86_64-macos.tar.gz"; 22 + hash = "sha256-8mkq3G4s7HFA6gC2pDUZ1aZBA3uAyqoK6zBgZG5nVAk="; 23 + }; 24 + aarch64-darwin = { 25 + url = "https://github.com/yamafaktory/whetuu/releases/download/v0.1.5/whetuu-v0.1.5-aarch64-macos.tar.gz"; 26 + hash = "sha256-WTl+7W0zww7aMZTYfBxlSo/rofJy9EYrlhs9KrqlGyo="; 27 + }; 28 + }; 29 + 30 + srcAttrs = 31 + sources.${stdenv.hostPlatform.system} 32 + or (throw "whetuu: unsupported system ${stdenv.hostPlatform.system}"); 33 + in 34 + stdenv.mkDerivation (finalAttrs: { 35 + pname = "whetuu"; 36 + version = "0.1.5"; 37 + 38 + src = fetchurl { 39 + inherit (srcAttrs) url hash; 40 + }; 41 + 42 + # Archive root is just the `whetuu` binary (no directory wrapper). 43 + sourceRoot = "."; 44 + 45 + installPhase = '' 46 + runHook preInstall 47 + install -Dm755 whetuu $out/bin/whetuu 48 + runHook postInstall 49 + ''; 50 + 51 + nativeInstallCheckInputs = [ versionCheckHook ]; 52 + versionCheckProgram = "${placeholder "out"}/bin/whetuu"; 53 + versionCheckProgramArg = "--version"; 54 + doInstallCheck = true; 55 + 56 + meta = { 57 + description = "Opinionated, zero-config cross-shell prompt written in Zig"; 58 + homepage = "https://github.com/yamafaktory/whetuu"; 59 + changelog = "https://github.com/yamafaktory/whetuu/releases/tag/v${finalAttrs.version}"; 60 + license = lib.licenses.mit; 61 + mainProgram = "whetuu"; 62 + platforms = builtins.attrNames sources; 63 + sourceProvenance = with lib.sourceTypes; [ binaryNativeCode ]; 64 + }; 65 + })
+12
packages/whetuu/upstream.json
··· 1 + { 2 + "type": "github-release-binary", 3 + "github": "yamafaktory/whetuu", 4 + "tag_prefix": "v", 5 + "platforms": { 6 + "x86_64-linux": "whetuu-v{version}-x86_64-linux-musl.tar.gz", 7 + "aarch64-linux": "whetuu-v{version}-aarch64-linux-musl.tar.gz", 8 + "x86_64-darwin": "whetuu-v{version}-x86_64-macos.tar.gz", 9 + "aarch64-darwin": "whetuu-v{version}-aarch64-macos.tar.gz" 10 + }, 11 + "description": "Official multi-platform release tarballs (static musl on Linux). Tracks latest vX.Y.Z GitHub release and refreshes per-platform fetchurl hashes." 12 + }
+84 -8
scripts/update-packages.sh
··· 465 465 } 466 466 467 467 update_github_release_binary() { 468 - # Official prebuilt release assets (e.g. zed-preview Linux tarball). 468 + # Official prebuilt release assets. 469 469 # version in default.nix is the tag without the leading "v" (e.g. 1.12.0-pre). 470 + # 471 + # Single-asset (zed-preview): 472 + # asset: "zed-linux-x86_64.tar.gz" 473 + # Multi-platform (whetuu) — rewrites sources = { … } like url-manifest-binary: 474 + # platforms: { "x86_64-linux": "whetuu-v{version}-x86_64-linux-musl.tar.gz", … } 475 + # {version} is substituted with the bare version (no tag prefix). 470 476 local name="$1" 471 477 local pkg_dir="$ROOT/packages/${name}" 472 478 local default_nix="$pkg_dir/default.nix" ··· 477 483 tag_suffix="$(read_field "$upstream" tag_suffix)" 478 484 asset="$(read_field "$upstream" asset)" 479 485 [[ -n "$repo" ]] || die "${name}: upstream.json missing github" 480 - [[ -n "$asset" ]] || die "${name}: upstream.json missing asset" 481 486 tag_prefix="${tag_prefix:-v}" 482 487 tag_suffix="${tag_suffix:-}" 488 + 489 + local has_platforms=0 490 + if python3 -c ' 491 + import json, sys 492 + u = json.load(open(sys.argv[1])) 493 + sys.exit(0 if u.get("platforms") else 1) 494 + ' "$upstream" 2>/dev/null; then 495 + has_platforms=1 496 + fi 497 + 498 + if [[ "$has_platforms" -eq 0 && -z "$asset" ]]; then 499 + die "${name}: upstream.json needs either asset or platforms" 500 + fi 483 501 484 502 local cur latest 485 503 cur="$(current_version "$default_nix")" ··· 514 532 log "${name}: updating ${cur} -> ${latest}" 515 533 set_field_string "$default_nix" version "$latest" 516 534 517 - local src_url src_hash 518 - src_url="https://github.com/${repo}/releases/download/${tag_prefix}${latest}/${asset}" 519 - log "${name}: prefetching ${src_url}" 520 - src_hash="$(sri_from_url_file "$src_url")" 521 - set_fetchurl_hash "$default_nix" "$src_hash" 522 - log "${name}: src hash ${src_hash}" 535 + if [[ "$has_platforms" -eq 1 ]]; then 536 + local updated_sources 537 + updated_sources="$(python3 -c ' 538 + import json, re, subprocess, sys 539 + 540 + upstream = json.load(open(sys.argv[1])) 541 + repo = upstream["github"] 542 + prefix = upstream.get("tag_prefix") or "v" 543 + version = sys.argv[2] 544 + platforms = upstream["platforms"] 545 + if not platforms: 546 + sys.exit("platforms map is empty") 547 + 548 + out = {} 549 + for nix_system, asset_tmpl in platforms.items(): 550 + asset = asset_tmpl.replace("{version}", version) 551 + url = f"https://github.com/{repo}/releases/download/{prefix}{version}/{asset}" 552 + base32 = subprocess.check_output( 553 + ["nix-prefetch-url", url], text=True 554 + ).strip().splitlines()[-1] 555 + sri = subprocess.check_output( 556 + ["nix", "hash", "convert", "--hash-algo", "sha256", "--to", "sri", base32], 557 + text=True, 558 + ).strip() 559 + out[nix_system] = {"url": url, "hash": sri} 560 + print(f" {nix_system}: {sri}", file=sys.stderr) 561 + print(json.dumps(out)) 562 + ' "$upstream" "$latest")" 563 + 564 + python3 -c ' 565 + import json, re, sys 566 + 567 + path, sources_json = sys.argv[1], sys.argv[2] 568 + sources = json.loads(sources_json) 569 + text = open(path).read() 570 + 571 + order = ["x86_64-linux", "aarch64-linux", "x86_64-darwin", "aarch64-darwin"] 572 + keys = [k for k in order if k in sources] + sorted(k for k in sources if k not in order) 573 + 574 + def fmt_entry(sysname): 575 + e = sources[sysname] 576 + return ( 577 + f" {sysname} = {{\n" 578 + f" url = \"{e['url']}\";\n" 579 + f" hash = \"{e['hash']}\";\n" 580 + f" }};" 581 + ) 582 + 583 + block = "sources = {\n" + "\n".join(fmt_entry(k) for k in keys) + "\n };" 584 + pat = re.compile(r"sources\s*=\s*\{.*?\n \};", re.S) 585 + new, n = pat.subn(block, text, count=1) 586 + if n != 1: 587 + sys.exit(f"failed to rewrite sources block in {path} (matches={n})") 588 + open(path, "w").write(new) 589 + ' "$default_nix" "$updated_sources" 590 + log "${name}: sources refreshed" 591 + else 592 + local src_url src_hash 593 + src_url="https://github.com/${repo}/releases/download/${tag_prefix}${latest}/${asset}" 594 + log "${name}: prefetching ${src_url}" 595 + src_hash="$(sri_from_url_file "$src_url")" 596 + set_fetchurl_hash "$default_nix" "$src_hash" 597 + log "${name}: src hash ${src_hash}" 598 + fi 523 599 524 600 verify_build "$name" 525 601 log "${name}: updated successfully to ${latest}"