From 6e7523b563a4ed59b41c83392a976bbc7ae85746 Mon Sep 17 00:00:00 2001 From: Matt Toohey Date: Fri, 2 Oct 2026 14:55:42 +1000 Subject: [PATCH 1/3] build: bump hermit Node to 24.21.0 and make CI watch bin/ Move the hermit-managed dev/CI Node from 24.15.0 to 24.21.0 (current 24.x LTS): bin/.node-24.15.0.pkg -> bin/.node-24.21.0.pkg, with the node/npm/npx/corepack shims retargeted. No other hermit package changes; the shipped runtime pin (node-runtime.lock.json) is left for a separate commit. Drop the `corepack enable pnpm` steps from the five workflows that use pnpm (staged-ci, staged-release, differ-ci, penpal-ci, penpal-release). Hermit already puts a standalone pnpm 10.33.0 on PATH, matching the `packageManager` field, so the step adds nothing. Worse, under the hermit PATH `corepack` resolves to bin/corepack, so `corepack enable` overwrote hermit's bin/pnpm symlink with a corepack shim that re-downloaded the same pnpm from the registry on every CI run. Node >= 25 no longer ships corepack, so the step would also break the upcoming Node 26 move. Add `bin/**` to the push and pull_request path filters of staged-ci, differ-ci and penpal-ci so a hermit toolchain bump triggers CI instead of merging untested. Verified on Node 24.21.0: pnpm install --frozen-lockfile; staged build, check (3392 files, 0 errors) and vitest (81 files, 1118 tests); differ check (3993 files, 0 errors) and build; penpal frontend vitest (25 files, 257 tests). No other references to Node 24.15 exist in the repo. Co-Authored-By: Claude Fable 5.1 Signed-off-by: Matt Toohey --- .github/workflows/differ-ci.yml | 7 +++---- .github/workflows/penpal-ci.yml | 7 +++---- .github/workflows/penpal-release.yml | 5 +---- .github/workflows/staged-ci.yml | 7 +++---- .github/workflows/staged-release.yml | 2 -- bin/{.node-24.15.0.pkg => .node-24.21.0.pkg} | 0 bin/corepack | 2 +- bin/node | 2 +- bin/npm | 2 +- bin/npx | 2 +- 10 files changed, 14 insertions(+), 22 deletions(-) rename bin/{.node-24.15.0.pkg => .node-24.21.0.pkg} (100%) diff --git a/.github/workflows/differ-ci.yml b/.github/workflows/differ-ci.yml index 5ae49fd1e..d729ad4b4 100644 --- a/.github/workflows/differ-ci.yml +++ b/.github/workflows/differ-ci.yml @@ -11,6 +11,7 @@ on: - "pnpm-workspace.yaml" - "package.json" - "rust-toolchain.toml" + - "bin/**" - ".github/workflows/differ-ci.yml" push: branches: [main] @@ -22,6 +23,7 @@ on: - "pnpm-workspace.yaml" - "package.json" - "rust-toolchain.toml" + - "bin/**" - ".github/workflows/differ-ci.yml" workflow_dispatch: @@ -37,12 +39,9 @@ jobs: steps: - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - # Install hermit (manages node, rust, just) + # Install hermit (manages node, pnpm, rust, just) - uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1.1.5 - # Enable pnpm via corepack (node ships with corepack; version comes from packageManager in package.json) - - run: corepack enable pnpm - # Cache Cargo dependencies - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 with: diff --git a/.github/workflows/penpal-ci.yml b/.github/workflows/penpal-ci.yml index 2920ee114..a21976027 100644 --- a/.github/workflows/penpal-ci.yml +++ b/.github/workflows/penpal-ci.yml @@ -9,6 +9,7 @@ on: - "pnpm-workspace.yaml" - "package.json" - "rust-toolchain.toml" + - "bin/**" - ".github/workflows/penpal-ci.yml" push: branches: [main] @@ -18,6 +19,7 @@ on: - "pnpm-workspace.yaml" - "package.json" - "rust-toolchain.toml" + - "bin/**" - ".github/workflows/penpal-ci.yml" workflow_dispatch: @@ -33,7 +35,7 @@ jobs: steps: - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - # Install hermit (manages node, rust, just, go) + # Install hermit (manages node, pnpm, rust, just, go) - uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1.1.5 # Cache Cargo dependencies @@ -60,9 +62,6 @@ jobs: librsvg2-dev \ patchelf - # Enable pnpm via corepack (node ships with corepack; version comes from packageManager in package.json) - - run: corepack enable pnpm - # Install dependencies - name: Install dependencies run: | diff --git a/.github/workflows/penpal-release.yml b/.github/workflows/penpal-release.yml index 3abe4ad95..950636db9 100644 --- a/.github/workflows/penpal-release.yml +++ b/.github/workflows/penpal-release.yml @@ -29,7 +29,7 @@ jobs: exit 1 fi - # Install hermit (manages node, rust, just, go) + # Install hermit (manages node, pnpm, rust, just, go) - uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1.1.5 # Cache Cargo dependencies @@ -38,9 +38,6 @@ jobs: workspaces: apps/penpal/frontend/src-tauri key: aarch64-apple-darwin - # Enable pnpm via corepack - - run: corepack enable pnpm - # Install dependencies - name: Install dependencies run: | diff --git a/.github/workflows/staged-ci.yml b/.github/workflows/staged-ci.yml index 3bcbdde01..51da840c1 100644 --- a/.github/workflows/staged-ci.yml +++ b/.github/workflows/staged-ci.yml @@ -11,6 +11,7 @@ on: - "pnpm-workspace.yaml" - "package.json" - "rust-toolchain.toml" + - "bin/**" - ".github/workflows/staged-ci.yml" push: branches: [main] @@ -22,6 +23,7 @@ on: - "pnpm-workspace.yaml" - "package.json" - "rust-toolchain.toml" + - "bin/**" - ".github/workflows/staged-ci.yml" workflow_dispatch: @@ -37,12 +39,9 @@ jobs: steps: - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - # Install hermit (manages node, rust, just) + # Install hermit (manages node, pnpm, rust, just) - uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1.1.5 - # Enable pnpm via corepack (node ships with corepack; version comes from packageManager in package.json) - - run: corepack enable pnpm - # Cache Cargo dependencies - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 with: diff --git a/.github/workflows/staged-release.yml b/.github/workflows/staged-release.yml index cef2016bd..89335b715 100644 --- a/.github/workflows/staged-release.yml +++ b/.github/workflows/staged-release.yml @@ -21,8 +21,6 @@ jobs: - uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1.1.5 - - run: corepack enable pnpm - - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 with: workspaces: apps/staged/src-tauri diff --git a/bin/.node-24.15.0.pkg b/bin/.node-24.21.0.pkg similarity index 100% rename from bin/.node-24.15.0.pkg rename to bin/.node-24.21.0.pkg diff --git a/bin/corepack b/bin/corepack index 4df063726..deb51a7db 120000 --- a/bin/corepack +++ b/bin/corepack @@ -1 +1 @@ -.node-24.15.0.pkg \ No newline at end of file +.node-24.21.0.pkg \ No newline at end of file diff --git a/bin/node b/bin/node index 4df063726..deb51a7db 120000 --- a/bin/node +++ b/bin/node @@ -1 +1 @@ -.node-24.15.0.pkg \ No newline at end of file +.node-24.21.0.pkg \ No newline at end of file diff --git a/bin/npm b/bin/npm index 4df063726..deb51a7db 120000 --- a/bin/npm +++ b/bin/npm @@ -1 +1 @@ -.node-24.15.0.pkg \ No newline at end of file +.node-24.21.0.pkg \ No newline at end of file diff --git a/bin/npx b/bin/npx index 4df063726..deb51a7db 120000 --- a/bin/npx +++ b/bin/npx @@ -1 +1 @@ -.node-24.15.0.pkg \ No newline at end of file +.node-24.21.0.pkg \ No newline at end of file From 174535fca8090ad493035dc63a70d4cdfb7d8d6d Mon Sep 17 00:00:00 2001 From: Matt Toohey Date: Fri, 2 Oct 2026 15:06:29 +1000 Subject: [PATCH 2/3] build(staged): bump managed Node runtime to v24.21.0 Move the Node runtime that Staged downloads onto users' machines to run the ACP bridges (@agentclientprotocol/claude-agent-acp, codex-acp) from v24.11.0 to v24.21.0, the current 24.x LTS, matching the hermit dev/CI Node bumped in 6e7523b5. node-runtime.lock.json was regenerated with `just bump-node-runtime v24.21.0`; the same four target triples are pinned and every sha256 was cross-checked against the official https://nodejs.org/dist/v24.21.0/SHASUMS256.txt (the recipe reads the checksum file through the Artifactory mirror). On next launch users download the new runtime (~55 MiB) and both bridges are reinstalled under it. The reconciler keeps the old runtime until the new one installs successfully and only then prunes it, and both bridges accept Node >= 22, so a plain revert rolls this back. Also refresh the stale comments next to the pin: the MAX_ARCHIVE_BYTES note now reflects the largest pinned tarball (linux-x64, ~55 MiB; the old "~49 MB" was the darwin-arm64 size) and the two "e.g. v24.11.0" examples in the lock struct doc and the bump script cite the current pin. Verified: cargo test managed_node in apps/staged/src-tauri, 15 passed. Co-Authored-By: Claude Fable 5.1 Signed-off-by: Matt Toohey --- apps/staged/node-runtime.lock.json | 18 +++++++++--------- .../scripts/update-node-runtime-lock.mjs | 2 +- apps/staged/src-tauri/src/managed_node.rs | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/apps/staged/node-runtime.lock.json b/apps/staged/node-runtime.lock.json index b4e593d8f..fffaf1cb6 100644 --- a/apps/staged/node-runtime.lock.json +++ b/apps/staged/node-runtime.lock.json @@ -1,21 +1,21 @@ { - "version": "v24.11.0", + "version": "v24.21.0", "artifacts": { "aarch64-apple-darwin": { - "filename": "node-v24.11.0-darwin-arm64.tar.gz", - "sha256": "0be2ab2816a4fa02d1acff014a434f29f56d8d956f5af6a98b70ced6c5f4d201" + "filename": "node-v24.21.0-darwin-arm64.tar.gz", + "sha256": "bed7eea5325e1108f32ce5228ddd6a5f0f08a499ee42aa7442aea583702f6057" }, "aarch64-unknown-linux-gnu": { - "filename": "node-v24.11.0-linux-arm64.tar.gz", - "sha256": "4786d00c4d259d3ff0b2328307f764ef3ced65f2d6e9502d433e68d66238509d" + "filename": "node-v24.21.0-linux-arm64.tar.gz", + "sha256": "724282c3b43aec998aa9527380465b45d229e021b58035f5f4f63095eabfe5d5" }, "x86_64-apple-darwin": { - "filename": "node-v24.11.0-darwin-x64.tar.gz", - "sha256": "3884671e87f46f773832d98a0a6cabcc5ec4f637084f0f3515b69e66ea27f2f1" + "filename": "node-v24.21.0-darwin-x64.tar.gz", + "sha256": "1462cb3b3046b815cf8ea436d3da450ec1a9f11dac7e5a46b0ada5305d7e8097" }, "x86_64-unknown-linux-gnu": { - "filename": "node-v24.11.0-linux-x64.tar.gz", - "sha256": "b3c071cdf47aab867c3b2aa287257df12ec5d7c962bf922b32fd33226c4295fd" + "filename": "node-v24.21.0-linux-x64.tar.gz", + "sha256": "6e1db87ef58b8819e5d5402eff1536491b18edd8eb7bee5ef7897876e88dc5ff" } } } diff --git a/apps/staged/scripts/update-node-runtime-lock.mjs b/apps/staged/scripts/update-node-runtime-lock.mjs index 044c6a9db..0b7afa246 100755 --- a/apps/staged/scripts/update-node-runtime-lock.mjs +++ b/apps/staged/scripts/update-node-runtime-lock.mjs @@ -116,7 +116,7 @@ async function main() { const version = args.version ?? (await currentLockedVersion(args.lockFile)); if (!version) { throw new Error( - "No version given and no existing lockfile to refresh; pass a version (e.g. v24.11.0)", + "No version given and no existing lockfile to refresh; pass a version (e.g. v24.21.0)", ); } diff --git a/apps/staged/src-tauri/src/managed_node.rs b/apps/staged/src-tauri/src/managed_node.rs index d1bde73c2..d2e0a9ac1 100644 --- a/apps/staged/src-tauri/src/managed_node.rs +++ b/apps/staged/src-tauri/src/managed_node.rs @@ -30,7 +30,7 @@ const UPSTREAM_NODE_DIST_BASE_URL: &str = "https://nodejs.org/dist"; const PACKAGES_LOCK_FILENAME: &str = ".lock"; /// Hard cap on the compressed tarball; the largest pinned artifact today is -/// ~49 MB, so anything near this is a wrong or corrupted download. +/// ~55 MiB, so anything near this is a wrong or corrupted download. const MAX_ARCHIVE_BYTES: u64 = 90 * 1024 * 1024; const CONNECT_TIMEOUT: Duration = Duration::from_secs(30); const DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10 * 60); @@ -41,7 +41,7 @@ const PROGRESS_LOG_STEP_BYTES: u64 = 10 * 1024 * 1024; #[derive(Clone, Debug, serde::Deserialize)] pub struct NodeRuntimeLock { - /// Pinned Node.js version, `v`-prefixed (`v24.11.0`) — the exact string + /// Pinned Node.js version, `v`-prefixed (`v24.21.0`) — the exact string /// `node --version` prints. pub version: String, /// Rust target triple → release tarball pin. From 8a06b521f18a7a01c321373df667c875620714cc Mon Sep 17 00:00:00 2001 From: Matt Toohey Date: Fri, 2 Oct 2026 15:12:54 +1000 Subject: [PATCH 3/3] ci: watch bin/ in crates-ci and refresh bump-node-runtime example crates-ci.yml runs through cashapp/activate-hermit, so cargo, rustfmt, clippy and just all resolve via the hermit symlinks in bin/ (bin/.rustup-*.pkg, bin/.just-*.pkg), but its paths filters only watched rust-toolchain.toml. A hermit rustup or just bump could therefore merge without running the crates checks. Add "bin/**" to both the pull_request and push filters, matching what 6e7523b5 did for staged-ci, differ-ci and penpal-ci. Also update the bump-node-runtime recipe comment in apps/staged/justfile from `v24.12.0` to `v24.21.0` so the example matches the current node-runtime.lock.json pin and the other "e.g." examples refreshed in 174535fc. Co-Authored-By: Claude Fable 5.1 Signed-off-by: Matt Toohey --- .github/workflows/crates-ci.yml | 2 ++ apps/staged/justfile | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/crates-ci.yml b/.github/workflows/crates-ci.yml index cbe9ab661..25148d775 100644 --- a/.github/workflows/crates-ci.yml +++ b/.github/workflows/crates-ci.yml @@ -8,6 +8,7 @@ on: - "Cargo.toml" - "Cargo.lock" - "rust-toolchain.toml" + - "bin/**" - ".github/workflows/crates-ci.yml" push: branches: [main] @@ -16,6 +17,7 @@ on: - "Cargo.toml" - "Cargo.lock" - "rust-toolchain.toml" + - "bin/**" - ".github/workflows/crates-ci.yml" workflow_dispatch: diff --git a/apps/staged/justfile b/apps/staged/justfile index 10a662a30..842387d93 100644 --- a/apps/staged/justfile +++ b/apps/staged/justfile @@ -133,7 +133,7 @@ release version: echo "Pushed tag staged/v{{version}} — CI will build and publish the release." -# Fetch official Node.js release checksums and update node-runtime.lock.json (e.g. `just bump-node-runtime v24.12.0`) +# Fetch official Node.js release checksums and update node-runtime.lock.json (e.g. `just bump-node-runtime v24.21.0`) bump-node-runtime *ARGS: node scripts/update-node-runtime-lock.mjs {{ ARGS }}