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.

Add boxd CLI package from official boxd.sh binaries

Package the multi-platform static CLI (linux amd64/arm64, darwin arm64)
with a url-manifest-binary updater type that tracks version manifests.

+286
+50
README.md
··· 29 29 | `vit` | [solpbc/vit](https://github.com/solpbc/vit) | `npm install -g vit` | 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 + | `boxd` | [boxd.sh](https://boxd.sh) / [docs](https://docs.boxd.sh/quickstart) | `curl -fsSL https://boxd.sh/downloads/install.sh \| sh` | 32 33 | `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` | 33 34 34 35 ## Usage ··· 38 39 nix build .#vit 39 40 nix build .#rook 40 41 nix build .#spinel 42 + nix build .#boxd # x86_64-linux / aarch64-linux / aarch64-darwin 41 43 nix build .#zed-preview # x86_64-linux only 42 44 43 45 # run without installing ··· 45 47 nix run .#rook -- --help 46 48 nix run .#spinel -- --help 47 49 nix run .#spin -- new myapp # spin project tool (from the spinel package) 50 + nix run .#boxd -- --help 48 51 nix run .#zed-preview -- --version 49 52 50 53 # install into your profile 51 54 nix profile install .#vit 52 55 nix profile install .#rook 53 56 nix profile install .#spinel 57 + nix profile install .#boxd 54 58 nix profile install .#zed-preview 55 59 ``` 56 60 ··· 122 126 `{tag_prefix}{semver}{tag_suffix}` and refreshes the `fetchurl` hash for 123 127 `asset`. Used by `zed-preview` (x86_64-linux only). 124 128 129 + **url-manifest-binary** — prebuilt multi-platform binaries via a version 130 + manifest URL (not GitHub releases): 131 + 132 + ```json 133 + { 134 + "type": "url-manifest-binary", 135 + "manifest_url": "https://boxd.sh/downloads/cli/latest-{platform}.json", 136 + "platforms": { 137 + "x86_64-linux": "linux-amd64", 138 + "aarch64-linux": "linux-arm64", 139 + "aarch64-darwin": "darwin-arm64" 140 + } 141 + } 142 + ``` 143 + 144 + `{platform}` is replaced per entry in `platforms`. Each manifest must expose 145 + `version` + `url`; the updater prefetches every platform hash and rewrites the 146 + `sources = { … }` block in `default.nix`. Used by `boxd`. 147 + 125 148 ### Manual steps (vit / rook) 126 149 127 150 If you prefer to bump by hand (same flow for either npm-github package): ··· 187 210 ``` 188 211 3. Paste the SRI hash into `fetchurl.hash`, then `nix build .#zed-preview` and 189 212 smoke-test `./result/bin/zed-preview --version`. 213 + 214 + ### Manual steps (boxd) 215 + 216 + `boxd` ships official static CLI binaries from [boxd.sh](https://boxd.sh) 217 + (see [quickstart](https://docs.boxd.sh/quickstart)). Prefer the updater: 218 + 219 + ```bash 220 + ./scripts/update-packages.sh boxd 221 + ``` 222 + 223 + By hand: 224 + 225 + 1. Read the manifests and note the shared version: 226 + ```bash 227 + curl -fsSL https://boxd.sh/downloads/cli/latest-linux-amd64.json 228 + curl -fsSL https://boxd.sh/downloads/cli/latest-linux-arm64.json 229 + curl -fsSL https://boxd.sh/downloads/cli/latest-darwin-arm64.json 230 + ``` 231 + 2. Bump `version` in `packages/boxd/default.nix`. 232 + 3. Prefetch each platform binary hash into the matching `sources.<system>.hash`: 233 + ```bash 234 + nix-prefetch-url "https://boxd.sh/downloads/cli/boxd-linux-amd64" 235 + nix-prefetch-url "https://boxd.sh/downloads/cli/boxd-linux-arm64" 236 + nix-prefetch-url "https://boxd.sh/downloads/cli/boxd-darwin-arm64" 237 + nix hash convert --hash-algo sha256 --to sri <base32> 238 + ``` 239 + 4. `nix build .#boxd` and smoke-test `./result/bin/boxd --version`.
+30
flake.nix
··· 21 21 system: 22 22 let 23 23 pkgs = nixpkgs.legacyPackages.${system}; 24 + # boxd is a binary-only redistributable CLI (unfreeRedistributable). 25 + # Import a pkgs set that only allows that attr so `nix build .#boxd` 26 + # works without a global allowUnfree. 27 + pkgsUnfree = import nixpkgs { 28 + inherit system; 29 + config.allowUnfreePredicate = 30 + pkg: builtins.elem (nixpkgs.lib.getName pkg) [ "boxd" ]; 31 + }; 24 32 in 25 33 { 26 34 vit = pkgs.callPackage ./packages/vit { }; ··· 28 36 rook = pkgs.callPackage ./packages/rook { }; 29 37 default = self.packages.${system}.vit; 30 38 } 39 + // pkgs.lib.optionalAttrs ( 40 + builtins.elem system [ 41 + "x86_64-linux" 42 + "aarch64-linux" 43 + "aarch64-darwin" 44 + ] 45 + ) { 46 + # Official prebuilt CLI (static binary); no darwin-x86_64 upstream. 47 + boxd = pkgsUnfree.callPackage ./packages/boxd { }; 48 + } 31 49 // pkgs.lib.optionalAttrs (system == "x86_64-linux") { 32 50 # Official preview tarball is only fetched for x86_64-linux. 33 51 zed-preview = pkgs.callPackage ./packages/zed-preview { }; ··· 55 73 program = "${self.packages.${system}.rook}/bin/rook"; 56 74 }; 57 75 default = self.apps.${system}.vit; 76 + } 77 + // nixpkgs.lib.optionalAttrs ( 78 + builtins.elem system [ 79 + "x86_64-linux" 80 + "aarch64-linux" 81 + "aarch64-darwin" 82 + ] 83 + ) { 84 + boxd = { 85 + type = "app"; 86 + program = "${self.packages.${system}.boxd}/bin/boxd"; 87 + }; 58 88 } 59 89 // nixpkgs.lib.optionalAttrs (system == "x86_64-linux") { 60 90 zed-preview = {
+60
packages/boxd/default.nix
··· 1 + { 2 + lib, 3 + stdenv, 4 + fetchurl, 5 + versionCheckHook, 6 + }: 7 + 8 + let 9 + # Prebuilt static CLI from https://boxd.sh/downloads/cli (see quickstart). 10 + # Platforms match the installer's PLATFORM matrix (no darwin-x86_64). 11 + sources = { 12 + x86_64-linux = { 13 + url = "https://boxd.sh/downloads/cli/boxd-linux-amd64"; 14 + hash = "sha256-TlUeF41JcsMekeGx4y8dKyjTQ/oyHwJrSxRFLD2nYpc="; 15 + }; 16 + aarch64-linux = { 17 + url = "https://boxd.sh/downloads/cli/boxd-linux-arm64"; 18 + hash = "sha256-TVCIe9i6AdfltOBGiGWbpor0lPNX40sK3Xt35IJWOeE="; 19 + }; 20 + aarch64-darwin = { 21 + url = "https://boxd.sh/downloads/cli/boxd-darwin-arm64"; 22 + hash = "sha256-rSJjp67z+yES7DGDiUIKpi6jThGpN7nb8UwuOJ4zAT4="; 23 + }; 24 + }; 25 + 26 + srcAttrs = 27 + sources.${stdenv.hostPlatform.system} or (throw "boxd: unsupported system ${stdenv.hostPlatform.system}"); 28 + in 29 + stdenv.mkDerivation (finalAttrs: { 30 + pname = "boxd"; 31 + version = "0.1.23"; 32 + 33 + src = fetchurl { 34 + inherit (srcAttrs) url hash; 35 + }; 36 + 37 + dontUnpack = true; 38 + 39 + installPhase = '' 40 + runHook preInstall 41 + install -Dm755 $src $out/bin/boxd 42 + runHook postInstall 43 + ''; 44 + 45 + nativeInstallCheckInputs = [ versionCheckHook ]; 46 + versionCheckProgram = "${placeholder "out"}/bin/boxd"; 47 + versionCheckProgramArg = "--version"; 48 + doInstallCheck = true; 49 + 50 + meta = { 51 + description = "CLI for boxd cloud VMs — create, fork, exec, and manage remote Linux machines"; 52 + homepage = "https://boxd.sh"; 53 + changelog = "https://docs.boxd.sh"; 54 + # Binary-only distribution; no open-source license published with the CLI. 55 + license = lib.licenses.unfreeRedistributable; 56 + mainProgram = "boxd"; 57 + platforms = builtins.attrNames sources; 58 + sourceProvenance = with lib.sourceTypes; [ binaryNativeCode ]; 59 + }; 60 + })
+10
packages/boxd/upstream.json
··· 1 + { 2 + "type": "url-manifest-binary", 3 + "manifest_url": "https://boxd.sh/downloads/cli/latest-{platform}.json", 4 + "platforms": { 5 + "x86_64-linux": "linux-amd64", 6 + "aarch64-linux": "linux-arm64", 7 + "aarch64-darwin": "darwin-arm64" 8 + }, 9 + "description": "Official boxd CLI static binaries. Tracks version + per-platform hashes from boxd.sh download manifests." 10 + }
+136
scripts/update-packages.sh
··· 525 525 log "${name}: updated successfully to ${latest}" 526 526 } 527 527 528 + update_url_manifest_binary() { 529 + # Prebuilt multi-platform binaries discovered via a version manifest URL. 530 + # upstream.json: 531 + # type: url-manifest-binary 532 + # manifest_url: "https://…/latest-{platform}.json" ({platform} substituted) 533 + # platforms: { "x86_64-linux": "linux-amd64", … } 534 + # 535 + # default.nix is expected to declare: 536 + # version = "…"; 537 + # sources = { <nix-system> = { url = "…"; hash = "…"; }; … }; 538 + local name="$1" 539 + local pkg_dir="$ROOT/packages/${name}" 540 + local default_nix="$pkg_dir/default.nix" 541 + local upstream="$pkg_dir/upstream.json" 542 + local manifest_url 543 + manifest_url="$(read_field "$upstream" manifest_url)" 544 + [[ -n "$manifest_url" ]] || die "${name}: upstream.json missing manifest_url" 545 + 546 + local cur latest 547 + cur="$(current_version "$default_nix")" 548 + log "${name}: current=${cur}" 549 + 550 + # Fetch all platform manifests; require a single shared version. 551 + local platform_data 552 + platform_data="$(python3 -c ' 553 + import json, os, re, subprocess, sys, urllib.request 554 + 555 + upstream = json.load(open(sys.argv[1])) 556 + manifest_tmpl = upstream["manifest_url"] 557 + platforms = upstream["platforms"] 558 + if not platforms: 559 + sys.exit("platforms map is empty") 560 + 561 + entries = {} 562 + versions = set() 563 + for nix_system, platform in platforms.items(): 564 + url = manifest_tmpl.replace("{platform}", platform) 565 + with urllib.request.urlopen(url) as r: 566 + m = json.load(r) 567 + ver = m.get("version") or "" 568 + bin_url = m.get("url") or "" 569 + if not ver or not bin_url: 570 + sys.exit(f"invalid manifest for {platform}: {m!r}") 571 + versions.add(ver) 572 + entries[nix_system] = {"url": bin_url, "platform": platform} 573 + if len(versions) != 1: 574 + sys.exit(f"platform versions disagree: {sorted(versions)}") 575 + version = versions.pop() 576 + print(json.dumps({"version": version, "entries": entries})) 577 + ' "$upstream")" 578 + 579 + latest="$(python3 -c 'import json,sys; print(json.load(sys.stdin)["version"])' <<<"$platform_data")" 580 + log "${name}: latest upstream=${latest}" 581 + 582 + if [[ "$latest" == "$cur" ]]; then 583 + # Still refresh hashes if any platform URL/hash drifted without a version bump. 584 + # Compare by re-prefetching only when check mode is off and we force-check 585 + # via full equality of the sources block after a dry rewrite. 586 + if [[ "$CHECK_ONLY" -eq 1 ]]; then 587 + log "${name}: already up to date" 588 + return 0 589 + fi 590 + # Fall through only if sources need rewriting (handled below with hash refresh). 591 + fi 592 + 593 + if [[ "$latest" != "$cur" ]]; then 594 + if [[ "$CHECK_ONLY" -eq 1 ]]; then 595 + log "${name}: OUTDATED (${cur} -> ${latest})" 596 + return 10 597 + fi 598 + log "${name}: updating ${cur} -> ${latest}" 599 + set_field_string "$default_nix" version "$latest" 600 + elif [[ "$CHECK_ONLY" -eq 1 ]]; then 601 + log "${name}: already up to date" 602 + return 0 603 + fi 604 + 605 + # Prefetch each platform binary and rewrite the sources = { … } block. 606 + local updated_sources 607 + updated_sources="$(python3 -c ' 608 + import json, re, subprocess, sys 609 + 610 + platform_data = json.loads(sys.argv[1]) 611 + entries = platform_data["entries"] 612 + out = {} 613 + for nix_system, e in entries.items(): 614 + url = e["url"] 615 + base32 = subprocess.check_output( 616 + ["nix-prefetch-url", url], text=True 617 + ).strip().splitlines()[-1] 618 + sri = subprocess.check_output( 619 + ["nix", "hash", "convert", "--hash-algo", "sha256", "--to", "sri", base32], 620 + text=True, 621 + ).strip() 622 + out[nix_system] = {"url": url, "hash": sri} 623 + print(f" {nix_system}: {sri}", file=sys.stderr) 624 + print(json.dumps(out)) 625 + ' "$platform_data")" 626 + 627 + python3 -c ' 628 + import json, re, sys 629 + 630 + path, sources_json = sys.argv[1], sys.argv[2] 631 + sources = json.loads(sources_json) 632 + text = open(path).read() 633 + 634 + # Prefer a stable system order. 635 + order = ["x86_64-linux", "aarch64-linux", "x86_64-darwin", "aarch64-darwin"] 636 + keys = [k for k in order if k in sources] + sorted(k for k in sources if k not in order) 637 + 638 + def fmt_entry(sysname): 639 + e = sources[sysname] 640 + return ( 641 + f" {sysname} = {{\n" 642 + f" url = \"{e['url']}\";\n" 643 + f" hash = \"{e['hash']}\";\n" 644 + f" }};" 645 + ) 646 + 647 + block = "sources = {\n" + "\n".join(fmt_entry(k) for k in keys) + "\n };" 648 + pat = re.compile(r"sources\s*=\s*\{.*?\n \};", re.S) 649 + new, n = pat.subn(block, text, count=1) 650 + if n != 1: 651 + sys.exit(f"failed to rewrite sources block in {path} (matches={n})") 652 + open(path, "w").write(new) 653 + ' "$default_nix" "$updated_sources" 654 + 655 + log "${name}: sources refreshed" 656 + 657 + verify_build "$name" 658 + log "${name}: updated successfully to ${latest}" 659 + } 660 + 528 661 update_github_unstable() { 529 662 # Track tip of a branch for projects without release tags. 530 663 # version format: 0-unstable-YYYY-MM-DD ··· 594 727 ;; 595 728 github-release-binary) 596 729 update_github_release_binary "$name" || status=$? 730 + ;; 731 + url-manifest-binary) 732 + update_url_manifest_binary "$name" || status=$? 597 733 ;; 598 734 *) 599 735 die "${name}: unsupported upstream type '${type}'"