Initialize Nix overlay repository with blueprint, goose-cli, and docs

Add the complete overlay structure using numtide/blueprint with:
- Two overlay strategies (default and shared-nixpkgs)
- goose-cli package with custom librusty_v8 fetcher
- Interactive package launcher via fzf
- Flake input caching utility
- Comprehensive README and AGENTS.md documentation
This commit is contained in:
2026-04-29 16:04:58 +03:00
parent 216f59f65b
commit fb5db6e302
14 changed files with 918 additions and 1 deletions

273
AGENTS.md Normal file
View File

@@ -0,0 +1,273 @@
# AGENTS.md - Instructions for AI Agents
This file provides guidance to AI agents (such as Claude, GPT, Goose, etc.) when working with this Nix overlay repository.
## Project Overview
This is a **Nix flake overlay** repository that provides additional packages for Nix/NixOS users. It uses [numtide/blueprint](https://github.com/numtide/blueprint) as its foundation, which simplifies flake development by providing sensible defaults and automatic package discovery.
**Repository URL**: `git+https://git.millerson.name/alex/millerson-overlay.nix.git`
## Key Concepts
### Blueprint Framework
This project uses `numtide/blueprint` which:
- Automatically discovers packages in the `packages/` directory
- Provides `perSystem` outputs for multi-system builds
- Handles formatting, checking, and devShell generation
- Exposes `mkPackagesFor` function to build packages against any nixpkgs instance
### Two Overlay Strategies
1. **`overlays.default`** - Binary-cache-friendly
- Uses packages built against this flake's nixpkgs revision
- Better for binary cache hits when using the same nixpkgs
2. **`overlays.shared-nixpkgs`** - Dependency-sharing
- Builds packages against the consumer's nixpkgs (`final`)
- Shares dependencies with the rest of the system
- No second nixpkgs evaluation
- Trade-off: binary cache only hits when consumer's nixpkgs matches ours
## Repository Structure
```
nix-overlay/
├── flake.nix # Main flake definition with inputs and outputs
├── overlays/
│ ├── default.nix # Overlay using pre-built packages (binary cache friendly)
│ └── shared-nixpkgs.nix # Overlay building against consumer's nixpkgs
├── packages/
│ ├── default/ # Meta-package listing all visible packages
│ │ ├── default.nix
│ │ └── package.nix
│ ├── goose-cli/ # Example package: Goose AI agent CLI
│ │ ├── default.nix
│ │ ├── package.nix # Main package definition
│ │ ├── fetchers.nix # Custom fetchers (if needed)
│ │ ├── librusty_v8.nix # V8 library pre-built binary
│ │ └── update.py # Update script for version bumps
│ └── flake-inputs/ # Utility to cache all flake inputs
│ └── default.nix
├── README.md # User-facing documentation
├── AGENTS.md # This file - AI agent instructions
├── LICENSE
└── flake.lock
```
## Package Definition Pattern
### Standard Package Structure
Each package should follow this structure:
```
packages/<package-name>/
├── default.nix # Wrapper that receives blueprint args (pkgs, perSystem, etc.)
└── package.nix # Actual package definition using pkgs.callPackage pattern
```
### `default.nix` Pattern
```nix
{
pkgs,
perSystem,
...
}:
pkgs.callPackage ./package.nix {
# Pass any extra arguments here
}
```
### `package.nix` Pattern
```nix
{
lib,
stdenv,
# ... package-specific dependencies
}:
stdenv.mkDerivation rec {
pname = "my-package";
version = "1.0.0";
src = fetchFromGitHub {
owner = "user";
repo = "repo";
rev = "v${version}";
hash = "sha256-...";
};
# ... build instructions
meta = with lib; {
description = "Brief description";
homepage = "https://...";
license = licenses.mit;
maintainers = with maintainers; [ ];
platforms = platforms.all;
mainProgram = "program-name";
};
}
```
### Rust Packages
For Rust packages, use `rustPlatform.buildRustPackage`:
```nix
{
lib,
rustPlatform,
fetchFromGitHub,
...
}:
rustPlatform.buildRustPackage rec {
pname = "my-rust-app";
version = "1.0.0";
src = fetchFromGitHub { ... };
cargoHash = "sha256-...";
# ... build instructions
meta = { ... };
}
```
## Adding a New Package
When adding a new package:
1. **Create the directory**: `mkdir -p packages/<package-name>`
2. **Create `package.nix`** with the actual derivation
3. **Create `default.nix`** as a wrapper:
```nix
{ pkgs, ... }:
pkgs.callPackage ./package.nix { }
```
4. **Test the package**:
```bash
nix build .#<package-name>
nix run .#<package-name>
```
5. **Update README.md** to document the new package in the Available Packages table
6. **Set appropriate metadata**:
- `meta.description` - Required, shown in package listings
- `meta.mainProgram` - Set for packages providing a CLI executable
- `meta.passthru.category` - Optional, used for organization (e.g., "AI Coding Agents")
- `meta.passthru.hideFromDocs` - Set to `true` to exclude from documentation
## Common Tasks
### Updating a Package Version
1. Update `version` in `package.nix`
2. Update `src.hash` (use `nix-prefetch-github` or let Nix tell you the correct hash)
3. Update `cargoHash` for Rust packages (build will fail and tell you the correct hash)
4. Test: `nix build .#<package-name>`
5. Update README if needed
### Testing Changes
```bash
# Build specific package
nix build .#goose-cli
# Build all packages for current system
nix build .#packages
# Enter dev shell
nix develop
# Check formatting
nix flake check
```
### Working with Overlays
When modifying overlay behavior:
- **`overlays/default.nix`**: Receives `packages` from blueprint outputs, maps them to `final.stdenv.hostPlatform.system`
- **`overlays/shared-nixpkgs.nix`**: Receives `mkPackagesFor`, uses it to build against consumer's `final`
## Important Notes
### Do's
- ✅ Use `pkgs.callPackage` pattern for package definitions
- ✅ Set proper `meta` attributes (description, license, homepage)
- ✅ Test packages with `nix build` before committing
- ✅ Use `passthru.category` for organizational grouping
- ✅ Follow Nixpkgs conventions for package naming and structure
### Don'ts
- ❌ Don't modify `flake.lock` manually - use `nix flake update`
- ❌ Don't hardcode system-specific paths or assumptions
- ❌ Don't forget to set `meta.mainProgram` for CLI tools
- ❌ Don't use `with pkgs;` at top level (can cause scope issues)
- ❌ Don't commit packages that don't build
## Debugging Tips
### Package Doesn't Build
1. Check the error message carefully
2. Verify all dependencies are listed
3. Check if the source hash is correct
4. For Rust packages, verify `cargoHash` matches
### Overlay Not Working
1. Verify the overlay is correctly imported
2. Check if the package exists in `packages` output
3. For `shared-nixpkgs`, ensure `mkPackagesFor` is available
### Binary Cache Issues
- The `default` overlay is more likely to get cache hits
- The `shared-nixpkgs` overlay builds from source unless nixpkgs revisions match
## Resources
- [Nixpkgs Manual](https://nixos.org/manual/nixpkgs/stable/)
- [Blueprint Documentation](https://github.com/numtide/blueprint)
- [Nix Flake Patterns](https://github.com/NixOS/flake-patterns)
- [Rust in Nixpkgs](https://nixos.org/manual/nixpkgs/stable/#rust)
## Example Workflow: Adding a New Package
```bash
# 1. Create package directory
mkdir -p packages/my-tool
# 2. Create package.nix (use appropriate template above)
# 3. Create default.nix wrapper
cat > packages/my-tool/default.nix << 'EOF'
{ pkgs, ... }:
pkgs.callPackage ./package.nix { }
EOF
# 4. Test build
nix build .#my-tool
# 5. If build fails, fix issues, then retry
# 6. Update README.md with new package info
# 7. Commit changes
git add packages/my-tool README.md
git commit -m "Add my-tool package"
```

127
README.md
View File

@@ -1,2 +1,127 @@
# nix-overlay # millerson.name Nix Overlay
A custom Nix overlay and flake providing additional packages not found in upstream nixpkgs, built using [numtide/blueprint](https://github.com/numtide/blueprint) for streamlined flake development.
## Features
- **Custom packages** - Additional software packaged for Nix
- **Two overlay strategies** - Choose between binary-cache-friendly or dependency-sharing overlays
- **Blueprint-based** - Uses modern Nix flake patterns with `numtide/blueprint`
## Available Packages
| Package | Description | Category |
|---------|-------------|----------|
| `goose-cli` | CLI for Goose - a local, extensible, open source AI agent that automates engineering tasks | AI Coding Agents |
## Usage
### As a Flake
Add to your `flake.nix` inputs:
```nix
inputs.millerson-nix-overlay.url = "git+https://git.millerson.name/alex/millerson-overlay.nix.git";
```
Then use in your outputs:
```nix
outputs = { nixpkgs, millerson-nix-overlay, ... }: {
nixosConfigurations.your-host = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
millerson-nix-overlay.nixosModules.default
# ... your other modules
];
};
};
```
### As an Overlay
#### Option 1: Default Overlay (Binary Cache Friendly)
Uses the packages built against this flake's nixpkgs revision. Binary cache hits work best when using the same nixpkgs revision.
```nix
nixpkgs.overlays = [ millerson-nix-overlay.overlays.default ];
```
#### Option 2: Shared Nixpkgs Overlay (Dependency Sharing)
Builds packages against your system's nixpkgs, sharing dependencies with the rest of your system. No second nixpkgs evaluation, but binary cache only hits when your nixpkgs revision matches ours.
```nix
nixpkgs.overlays = [ millerson-nix-overlay.overlays.shared-nixpkgs ];
```
### Installing Packages
With flakes enabled:
```bash
# Try a package
nix run git+https://git.millerson.name/alex/millerson-overlay.nix.git#goose-cli
# Install permanently
nix profile install git+https://git.millerson.name/alex/millerson-overlay.nix.git#goose-cli
```
## Development
### Prerequisites
- Nix with flakes enabled
- [treefmt-nix](https://github.com/numtide/treefmt-nix) for formatting (optional)
### Building Packages
```bash
# Build all packages for current system
nix build .#packages
# Build specific package
nix build .#goose-cli
# Enter development shell
nix develop
```
### Project Structure
```
nix-overlay/
├── flake.nix # Flake definition
├── overlays/ # Overlay implementations
│ ├── default.nix # Binary-cache-friendly overlay
│ └── shared-nixpkgs.nix # Dependency-sharing overlay
├── packages/ # Package definitions
│ ├── default/ # Meta-package listing all packages
│ ├── goose-cli/ # Goose CLI package
│ └── flake-inputs/ # Utility for caching flake inputs
└── README.md
```
### Adding New Packages
1. Create a new directory under `packages/<package-name>/`
2. Add a `package.nix` with the package definition
3. Create a `default.nix` that imports `package.nix` with proper arguments
4. The package will be automatically picked up by blueprint
Example structure:
```
packages/my-package/
├── default.nix # Import wrapper
└── package.nix # Actual package definition
```
## License
See [LICENSE](LICENSE) file for details.
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.

140
flake.lock generated Normal file
View File

@@ -0,0 +1,140 @@
{
"nodes": {
"blueprint": {
"inputs": {
"nixpkgs": [
"nixpkgs"
],
"systems": [
"systems"
]
},
"locked": {
"lastModified": 1776249299,
"narHash": "sha256-Dt9t1TGRmJFc0xVYhttNBD6QsAgHOHCArqGa0AyjrJY=",
"owner": "numtide",
"repo": "blueprint",
"rev": "56131e8628f173d24a27f6d27c0215eff57e40dd",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "blueprint",
"type": "github"
}
},
"bun2nix": {
"inputs": {
"flake-parts": [
"flake-parts"
],
"nixpkgs": [
"nixpkgs"
],
"systems": [
"systems"
],
"treefmt-nix": [
"treefmt-nix"
]
},
"locked": {
"lastModified": 1777369708,
"narHash": "sha256-1xW7cRZNsFNPQD+cE0fwnLVStnDth0HSoASEIFeT7uI=",
"owner": "nix-community",
"repo": "bun2nix",
"rev": "e659e1cc4b8e1b21d0aa85f1c481f9db61ecfa98",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "staging-2.1.0",
"repo": "bun2nix",
"type": "github"
}
},
"flake-parts": {
"inputs": {
"nixpkgs-lib": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1775087534,
"narHash": "sha256-91qqW8lhL7TLwgQWijoGBbiD4t7/q75KTi8NxjVmSmA=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "3107b77cd68437b9a76194f0f7f9c55f2329ca5b",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1777270315,
"narHash": "sha256-yKB4G6cKsQsWN7M6rZGk6gkJPDNPIzT05y4qzRyCDlI=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "6368eda62c9775c38ef7f714b2555a741c20c72d",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"blueprint": "blueprint",
"bun2nix": "bun2nix",
"flake-parts": "flake-parts",
"nixpkgs": "nixpkgs",
"systems": "systems",
"treefmt-nix": "treefmt-nix"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"treefmt-nix": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1775636079,
"narHash": "sha256-pc20NRoMdiar8oPQceQT47UUZMBTiMdUuWrYu2obUP0=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "790751ff7fd3801feeaf96d7dc416a8d581265ba",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

51
flake.nix Normal file
View File

@@ -0,0 +1,51 @@
{
description = "Various packages for Nix";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
systems.url = "github:nix-systems/default";
blueprint = {
url = "github:numtide/blueprint";
inputs.nixpkgs.follows = "nixpkgs";
inputs.systems.follows = "systems";
};
treefmt-nix = {
url = "github:numtide/treefmt-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
flake-parts = {
url = "github:hercules-ci/flake-parts";
inputs.nixpkgs-lib.follows = "nixpkgs";
};
bun2nix = {
# TODO(#4001): drop the branch pin once catalog support
# (nix-community/bun2nix#86) reaches the default branch.
url = "github:nix-community/bun2nix/staging-2.1.0";
inputs.nixpkgs.follows = "nixpkgs";
inputs.systems.follows = "systems";
inputs.treefmt-nix.follows = "treefmt-nix";
inputs.flake-parts.follows = "flake-parts";
};
};
outputs =
inputs:
let
blueprintOutputs = inputs.blueprint {
inherit inputs;
nixpkgs.config.allowUnfree = true;
};
in
blueprintOutputs
// {
overlays = {
default = import ./overlays {
inherit (blueprintOutputs) packages;
};
shared-nixpkgs = import ./overlays/shared-nixpkgs.nix {
inherit (blueprintOutputs) mkPackagesFor;
};
};
};
}

6
overlays/default.nix Normal file
View File

@@ -0,0 +1,6 @@
{
packages,
}:
final: _prev: {
millerson-nix-overlay = packages.${final.stdenv.hostPlatform.system} or { };
}

View File

@@ -0,0 +1,10 @@
{
mkPackagesFor,
}:
# Builds the packages/ tree against the consumer's `final`, so deps are
# shared with the rest of their system and no second nixpkgs is
# evaluated. Trade-off vs overlays.default: the binary cache only hits
# when the consumer's nixpkgs revision matches ours.
final: _prev: {
millerson-nix-overlay = mkPackagesFor final;
}

View File

@@ -0,0 +1,19 @@
{
pkgs,
perSystem,
...
}:
let
allPackages = perSystem.self;
# Filter to visible, runnable packages
visibleNames = builtins.filter (
name: name != "default" && !(allPackages.${name}.passthru.hideFromDocs or false)
) (builtins.attrNames allPackages);
# Build "name\tdescription" lines
packageLines = map (name: "${name}\t${allPackages.${name}.meta.description or ""}") visibleNames;
packageList = builtins.concatStringsSep "\n" packageLines;
in
pkgs.callPackage ./package.nix { inherit packageList; }

View File

@@ -0,0 +1,60 @@
{
lib,
writeShellApplication,
fzf,
nix,
util-linux,
packageList,
}:
let
packageListFile = builtins.toFile "millerson-overlay-packages.tsv" packageList;
in
writeShellApplication {
name = "millerson-overlay-launcher";
runtimeInputs = [
fzf
nix
util-linux # column
];
text = ''
# Format for fzf: "name description" (tab-aligned)
entries=$(column -t -s $'\t' < "${packageListFile}")
if [[ -z $entries ]]; then
echo "No packages found" >&2
exit 1
fi
# Let user pick with fzf
selected=$(echo "$entries" | fzf \
--header="Select an pkg to run (ESC to cancel)" \
--preview-window=hidden \
--no-multi \
--height=~40% \
--layout=reverse) || exit 0
# Extract package name (first word)
pkg_name=$(echo "$selected" | awk '{print $1}')
if [[ -z $pkg_name ]]; then
exit 0
fi
echo " Running: nix run git.millerson.name/alex/nix-overlay.git#$pkg_name"
exec nix run "git.millerson.name/alex/nix-overlay.git#$pkg_name"
'';
meta = with lib; {
description = "Interactive fzf launcher for millerson-overlay.nix packages";
license = licenses.mit;
mainProgram = "millerson-overlay-launcher";
platforms = platforms.all;
};
passthru = {
hideFromDocs = true;
};
}

View File

@@ -0,0 +1,12 @@
{
inputs,
pkgs,
...
}:
# A derivation that references all flake inputs to ensure they get cached
pkgs.runCommand "flake-inputs" { } ''
echo ${pkgs.lib.concatMapStringsSep " " (name: inputs.${name}) (builtins.attrNames inputs)} > $out
''
// {
passthru.hideFromDocs = true;
}

View File

@@ -0,0 +1,9 @@
{
pkgs,
...
}:
pkgs.callPackage ./package.nix {
librusty_v8 = pkgs.callPackage ./librusty_v8.nix {
inherit (pkgs.callPackage ./fetchers.nix { }) fetchLibrustyV8;
};
}

View File

@@ -0,0 +1,21 @@
# Fetchers for goose-cli pre-built dependencies
# Based on deno's approach for handling rusty_v8
{
lib,
stdenv,
fetchurl,
}:
{
fetchLibrustyV8 =
args:
fetchurl {
name = "librusty_v8-${args.version}";
url = "https://github.com/denoland/rusty_v8/releases/download/v${args.version}/librusty_v8_release_${stdenv.hostPlatform.rust.rustcTarget}.a.gz";
sha256 = args.shas.${stdenv.hostPlatform.system};
meta = {
inherit (args) version;
sourceProvenance = with lib.sourceTypes; [ binaryNativeCode ];
};
};
}

View File

@@ -0,0 +1,13 @@
# Pre-built librusty_v8 library for goose-cli
# This file specifies the rusty_v8 version and hashes for all supported platforms
{ fetchLibrustyV8 }:
fetchLibrustyV8 {
version = "145.0.0";
shas = {
x86_64-linux = "sha256-chV1PAx40UH3Ute5k3lLrgfhih39Rm3KqE+mTna6ysE=";
aarch64-linux = "sha256-4IivYskhUSsMLZY97+g23UtUYh4p5jk7CzhMbMyqXyY=";
x86_64-darwin = "sha256-1jUuC+z7saQfPYILNyRJanD4+zOOhXU2ac/LFoytwho=";
aarch64-darwin = "sha256-yHa1eydVCrfYGgrZANbzgmmf25p7ui1VMas2A7BhG6k=";
};
}

View File

@@ -0,0 +1,71 @@
{
lib,
fetchFromGitHub,
rustPlatform,
pkg-config,
openssl,
libxcb,
dbus,
versionCheckHook,
librusty_v8,
}:
rustPlatform.buildRustPackage rec {
pname = "goose-cli";
version = "1.33.1";
src = fetchFromGitHub {
owner = "block";
repo = "goose";
rev = "v${version}";
hash = "sha256-FBICGOfVs2jbOdLWSInqfTYBdnCcbcGWHwqY/b6v8eg=";
};
cargoHash = "sha256-fN0FKDYFkZrQQPWdUlemOaGzIAZhqFyskz9TEmG+X4o=";
nativeBuildInputs = [ pkg-config ];
buildInputs = [
openssl
libxcb
dbus
];
# The v8 package will try to download a `librusty_v8.a` release at build time to our read-only filesystem
# To avoid this we pre-download the file and export it via RUSTY_V8_ARCHIVE
env.RUSTY_V8_ARCHIVE = librusty_v8;
# Build only the CLI package
cargoBuildFlags = [
"--package"
"goose-cli"
];
# Enable tests with proper environment
doCheck = true;
checkPhase = ''
export HOME=$(mktemp -d)
export XDG_CONFIG_HOME=$HOME/.config
export XDG_DATA_HOME=$HOME/.local/share
export XDG_STATE_HOME=$HOME/.local/state
export XDG_CACHE_HOME=$HOME/.cache
mkdir -p $XDG_CONFIG_HOME $XDG_DATA_HOME $XDG_STATE_HOME $XDG_CACHE_HOME
# Run tests for goose-cli package only
cargo test --package goose-cli --release
'';
doInstallCheck = true;
nativeInstallCheckInputs = [ versionCheckHook ];
passthru.category = "AI Coding Agents";
meta = with lib; {
description = "CLI for Goose - a local, extensible, open source AI agent that automates engineering tasks";
homepage = "https://github.com/block/goose";
changelog = "https://github.com/block/goose/releases/tag/v${version}";
license = licenses.asl20;
sourceProvenance = with sourceTypes; [ fromSource ];
mainProgram = "goose";
};
}

107
packages/goose-cli/update.py Executable file
View File

@@ -0,0 +1,107 @@
#!/usr/bin/env nix
#! nix shell --inputs-from .# nixpkgs#python3 --command python3
"""Update script for goose-cli package.
This script updates both the goose-cli version and the librusty_v8 hashes.
The v8 version is extracted from the Cargo.lock file of the goose repository.
"""
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent.parent.parent / "scripts"))
from updater import (
calculate_platform_hashes,
fetch_text,
load_hashes,
save_hashes,
)
HASHES_FILE = Path(__file__).parent / "librusty_v8_hashes.json"
PLATFORMS = {
"x86_64-linux": "x86_64-unknown-linux-gnu",
"aarch64-linux": "aarch64-unknown-linux-gnu",
"x86_64-darwin": "x86_64-apple-darwin",
"aarch64-darwin": "aarch64-apple-darwin",
}
def fetch_v8_version_from_cargo_lock(goose_version: str) -> str:
"""Extract the v8 version from goose's Cargo.lock file."""
url = f"https://raw.githubusercontent.com/block/goose/v{goose_version}/Cargo.lock"
cargo_lock = fetch_text(url)
# Parse the Cargo.lock to find v8 version
lines = cargo_lock.split("\n")
for i, line in enumerate(lines):
if line.strip() == 'name = "v8"':
# Look for version in the next few lines
for j in range(i + 1, min(i + 10, len(lines))):
if "version = " in lines[j]:
return lines[j].split('"')[1]
msg = "Could not find v8 version in Cargo.lock"
raise ValueError(msg)
def main() -> None:
"""Update the librusty_v8 hashes for goose-cli."""
# Read the current goose-cli version from package.nix
package_nix = (Path(__file__).parent / "package.nix").read_text()
for line in package_nix.split("\n"):
if "version = " in line and '"' in line:
goose_version = line.split('"')[1]
break
else:
msg = "Could not find version in package.nix"
raise ValueError(msg)
print(f"Goose version: {goose_version}")
# Get the v8 version from Cargo.lock
v8_version = fetch_v8_version_from_cargo_lock(goose_version)
print(f"V8 version: {v8_version}")
# Check if we need to update
try:
data = load_hashes(HASHES_FILE)
current_v8 = data.get("version", "")
if current_v8 == v8_version:
print(f"V8 hashes already up to date ({v8_version})")
return
except FileNotFoundError:
print("No existing hashes file, creating new one")
# Calculate hashes for all platforms
url_template = f"https://github.com/denoland/rusty_v8/releases/download/v{v8_version}/librusty_v8_release_{{platform}}.a.gz"
hashes = calculate_platform_hashes(url_template, PLATFORMS)
# Save the hashes
save_hashes(HASHES_FILE, {"version": v8_version, "hashes": hashes})
# Update librusty_v8.nix
librusty_v8_nix = Path(__file__).parent / "librusty_v8.nix"
content = f"""# Pre-built librusty_v8 library for goose-cli
# This file specifies the rusty_v8 version and hashes for all supported platforms
{{ fetchLibrustyV8 }}:
fetchLibrustyV8 {{
version = "{v8_version}";
shas = {{
x86_64-linux = "{hashes["x86_64-linux"]}";
aarch64-linux = "{hashes["aarch64-linux"]}";
x86_64-darwin = "{hashes["x86_64-darwin"]}";
aarch64-darwin = "{hashes["aarch64-darwin"]}";
}};
}}
"""
librusty_v8_nix.write_text(content)
print(f"Updated librusty_v8 to {v8_version}")
if __name__ == "__main__":
main()