mirror of
https://github.com/block/buzz.git
synced 2026-10-29 13:31:44 +00:00
## Problem User report: ``` Buzz Node mismatch: Buzz supplies Node 24.14.0; OpenClaw requires >=24.15.0. All 10 ACP workers immediately crash. ``` Buzz supplies Node to agent processes from two places, and both were below OpenClaw's floor: | Supply path | Was | Now | |---|---|---| | hermit dev env (`bin/.node-*.pkg`) — the 24.14.0 in the report | 24.14.0 | **24.15.0** (newest hermit publishes; satisfies `>=24.15.0`) | | Desktop managed runtime (`managed_node.rs` / `managed_node_paths.rs`) | v24.11.0 | **v24.18.0** (current latest v24) | The managed runtime sits **first** on the worker PATH (`managed_agents/runtime/path.rs`), so a user-installed newer Node can't mask a stale managed one — the pin itself has to move. ## Verification - SHA-256 digests for all six platform artifacts taken from `https://nodejs.org/dist/v24.18.0/SHASUMS256.txt`; darwin-arm64 independently re-verified by downloading the tarball (hash match), extracting, and running `bin/node --version` → `v24.18.0`. - All artifacts within `MANAGED_NODE_MAX_BYTES` (largest linux-x64 at 57 MB < 90 MB cap); tar.gz layout keeps the `node-vX-platform/bin/node` shape `verify_node_tree` expects. - `cargo test --lib` in `desktop/src-tauri`: **1801 passed, 0 failed** at this commit; `cargo fmt --check` + `cargo clippy --lib -D warnings` clean. - Existing readiness check (`node --version == MANAGED_NODE_VERSION`) makes upgrade automatic: installed v24.11.0 trees fail readiness and the installer stages v24.18.0 atomically (rename with `.old` rollback — existing logic, unchanged). Note: CI `node-version: 24.14.1` pins in `release.yml`/`windows-canary.yml` are build-env only (already `>=` nothing OpenClaw touches) and left alone to keep this minimal. Signed-off-by: Tyler Longwell <tlongwell@block.xyz> Co-authored-by: npub1qyvc0c5kl4gqv2fd97fsk46tu378sqgy35vc83rvgfwne90sel7s0ed67d <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@buzz.block.builderlab.xyz> Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
102 lines
2.8 KiB
Rust
102 lines
2.8 KiB
Rust
use std::path::PathBuf;
|
|
|
|
pub(crate) fn buzz_managed_npm_prefix() -> Option<PathBuf> {
|
|
dirs::data_dir().map(|dir| dir.join("Buzz").join("node-tools"))
|
|
}
|
|
|
|
const BUZZ_MANAGED_NODE_VERSION: &str = "v24.18.0";
|
|
|
|
pub(crate) fn buzz_managed_node_root() -> Option<PathBuf> {
|
|
dirs::data_dir().map(|dir| dir.join("Buzz").join("runtimes").join("node"))
|
|
}
|
|
|
|
pub(crate) fn buzz_managed_node_bin_dir() -> Option<PathBuf> {
|
|
let (platform, bin_subdir): (&str, Option<&str>) =
|
|
match (std::env::consts::OS, std::env::consts::ARCH) {
|
|
("macos", "aarch64") => ("darwin-arm64", Some("bin")),
|
|
("macos", "x86_64") => ("darwin-x64", Some("bin")),
|
|
("linux", "x86_64") => ("linux-x64", Some("bin")),
|
|
("linux", "aarch64") => ("linux-arm64", Some("bin")),
|
|
// Windows zips have node.exe + npm.cmd at the archive root — no bin/ subdir
|
|
("windows", "x86_64") => ("win-x64", None),
|
|
("windows", "aarch64") => ("win-arm64", None),
|
|
_ => return None,
|
|
};
|
|
buzz_managed_node_root().map(|root| {
|
|
let dir = root.join(BUZZ_MANAGED_NODE_VERSION).join(platform);
|
|
match bin_subdir {
|
|
Some(sub) => dir.join(sub),
|
|
None => dir,
|
|
}
|
|
})
|
|
}
|
|
|
|
pub(crate) fn buzz_managed_node_bin_path() -> Option<PathBuf> {
|
|
buzz_managed_node_bin_dir().map(|bin| {
|
|
#[cfg(windows)]
|
|
{
|
|
bin.join("node.exe")
|
|
}
|
|
#[cfg(not(windows))]
|
|
{
|
|
bin.join("node")
|
|
}
|
|
})
|
|
}
|
|
|
|
pub(crate) fn buzz_managed_npm_bin_dir() -> Option<PathBuf> {
|
|
buzz_managed_npm_prefix().map(|prefix| {
|
|
#[cfg(windows)]
|
|
{
|
|
prefix
|
|
}
|
|
#[cfg(not(windows))]
|
|
{
|
|
prefix.join("bin")
|
|
}
|
|
})
|
|
}
|
|
|
|
pub(crate) fn buzz_managed_command_path(command: &str, basename: &str) -> Option<PathBuf> {
|
|
if command.contains(std::path::MAIN_SEPARATOR)
|
|
|| !matches!(
|
|
command,
|
|
"codex-acp" | "claude-agent-acp" | "claude-code-acp" | "node" | "npm"
|
|
)
|
|
{
|
|
return None;
|
|
}
|
|
|
|
let mut dirs = Vec::new();
|
|
if let Some(managed_bin) = buzz_managed_npm_bin_dir() {
|
|
dirs.push(managed_bin);
|
|
}
|
|
if let Some(managed_node_bin) = buzz_managed_node_bin_dir() {
|
|
dirs.push(managed_node_bin);
|
|
}
|
|
|
|
dirs.into_iter()
|
|
.map(|dir| dir.join(basename))
|
|
.find(|candidate| is_executable_file(candidate))
|
|
}
|
|
|
|
fn is_executable_file(path: &std::path::Path) -> bool {
|
|
let Ok(metadata) = path.metadata() else {
|
|
return false;
|
|
};
|
|
if !metadata.is_file() {
|
|
return false;
|
|
}
|
|
|
|
#[cfg(unix)]
|
|
{
|
|
use std::os::unix::fs::PermissionsExt;
|
|
metadata.permissions().mode() & 0o111 != 0
|
|
}
|
|
|
|
#[cfg(not(unix))]
|
|
{
|
|
true
|
|
}
|
|
}
|