Skip to content

Add a Nix dev shell so Node and Rust match CI - #7

Open
aarmanroy wants to merge 1 commit into
sambitcreate:mainfrom
aarmanroy:add-nix-dev-shell
Open

Add a Nix dev shell so Node and Rust match CI#7
aarmanroy wants to merge 1 commit into
sambitcreate:mainfrom
aarmanroy:add-nix-dev-shell

Conversation

@aarmanroy

Copy link
Copy Markdown

Today each contributor installs Node and Rust by hand, so no two machines match. On my Mac, Homebrew had given me cargo 1.92.0. This repo asks for 1.96.1 — that number lives in native/computer-use-broker/rust-toolchain.toml, the file rustup reads to decide which Rust version to use. The gap matters because npm test eventually runs cargo clippy --locked -- -D warnings. In plain words, that command runs Clippy (the Rust linter), forces it to use exactly the dependency versions recorded in Cargo.lock instead of picking newer ones (--locked), and turns every warning into a hard failure (-D warnings). Clippy adds new lints in almost every Rust release, so a newer Clippy rejects code an older one accepted. The result is that a change can pass on my machine and fail CI, or pass CI and then break for the next contributor. It reads like a code bug, but it is a version bug — and you are the one who ends up working that out during review.

This PR adds a Nix dev shell. Nix is a package manager that installs exact, pinned versions of tools into a temporary shell, without changing anything else on your Mac. A contributor runs one command, nix develop, and lands in a shell holding the same tools CI uses: npm 10.9.8 and cargo 1.96.1, both exact matches. The detail that matters for you is that flake.nix never writes the Rust version down a second time. It calls rust-bin.fromRustupToolchainFile and hands it the path to your existing rust-toolchain.toml, so Nix reads the version out of the file you already maintain. Bump that file and the shell follows on its own — there is no second copy to forget. Xcode and your signing identities deliberately still come from the Mac, because the Swift helper builds against Apple's real SDK and Apple does not permit Nix to redistribute it. Nothing that exists today changes: no CI edits, no new scripts, 115 lines added and none modified. It is entirely opt-in, so if you never run nix develop, your setup behaves exactly as it does now.

What each file does

  • flake.nix — declares the shell: Node 22 (your engines field asks for >=22.19), plus Rust read from your rust-toolchain.toml. It deliberately leaves DEVELOPER_DIR, SDKROOT, CC, and CXX unset so the host Xcode keeps driving every native build.
  • flake.lock — records the exact nixpkgs and rust-overlay commits used, so two contributors resolve to byte-identical tool builds rather than "whatever was current that day".
  • .envrc — optional. If you use direnv, the shell loads automatically when you cd into the repo. It also watches rust-toolchain.toml, because direnv otherwise only notices changes to flake.nix and would leave you in a stale shell after a toolchain bump.
  • .gitignore — one entry, .direnv/, the local cache direnv writes.
  • README.md — documents nix develop beneath the existing Requirements list.

Verified on macOS (aarch64): nix flake check, npm ci, npm run type-check, npm run lint, and npm run test:computer-use:native (the fmt + test + Clippy gate) all pass inside the shell.

One known gap, flagged honestly: Node resolves to 22.23.2 while CI pins 22.22.3. Both satisfy the >=22.19 requirement in package.json, and npm matches exactly at 10.9.8 because both Node versions bundle it. I chose not to force the exact patch, because pinning it needs a hand-written override that stops tracking nixpkgs and becomes the very maintenance burden this PR is trying to remove. Happy to change that if you would rather have it exact.

🤖 Generated with Claude Code

Contributors currently assemble the Node and Rust toolchains by hand, so
local versions drift from CI. On one machine here: Node 22.21.0 against
CI's 22.22.3, and Homebrew cargo 1.92.0 against the 1.96.1 pinned in
native/computer-use-broker/rust-toolchain.toml. The cargo gap is the one
that bites, because `npm test` runs `cargo clippy --locked -- -D warnings`
and clippy changes its lint set between releases, so a change can pass
locally and fail CI on lint alone.

`nix develop` now provides both, matching CI exactly on npm (10.9.8) and
cargo (1.96.1), and differing only in Node patch (22.23.2 vs 22.22.3,
both satisfying the >=22.19 engines constraint).

The shell reads rust-toolchain.toml through rust-overlay rather than
repeating the version, so bumping that file moves the shell with it and
the two cannot drift. This adds no new version state to maintain.

Deliberately out of scope: there is no package output. electron-builder,
ad-hoc signing, notarization, and the FoundationModels framework all need
the host Xcode and login keychain, which a Nix sandbox cannot reach. For
the same reason the shell leaves DEVELOPER_DIR, SDKROOT, CC, and CXX
unset so the host Xcode continues to drive every native build. Xcode and
signing identities remain host requirements, as the README now states.

Nothing existing changes: no CI edits, and the flake is opt-in. Anyone
not using Nix is unaffected.

Co-Authored-By: Claude Opus 5 <[email protected]>

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

  • Nix flakeflake.nix declares a macOS-only dev shell (arm64 and x86_64) with Node 22 from nixpkgs and Rust from rust-toolchain.toml via rust-overlay. flake.lock pins exact nixpkgs and rust-overlay revisions for byte-identical tool builds across contributors. DEVELOPER_DIR/SDKROOT/CC/CXX are deliberately left unset so the host Xcode drives native builds.
  • direnv integration.envrc auto-loads the flake on cd and watches rust-toolchain.toml so the shell reflects toolchain bumps without manual reloads.
  • Documentation — README adds a short paragraph and nix develop snippet under Requirements, plus a direnv allow alternative.
  • Gitignore.direnv/ entry keeps local direnv cache out of version control.

The flake reads the Rust version from the existing rust-toolchain.toml via fromRustupToolchainFile — no second copy to maintain. All changes are additive and opt-in; no existing code or CI configuration is modified.

Pullfrog  | View workflow run | Using DeepSeek Pro𝕏

@sambitcreate

Copy link
Copy Markdown
Owner

Review findings

I do not think this is ready to merge yet.

  1. Blocking: the Nix shell does not preserve the claimed host-Xcode boundary. flake.nix uses pkgs.mkShell, whose Darwin stdenv setup exports compiler and Apple SDK variables including CC, CXX, DEVELOPER_DIR, and SDKROOT. Aiden native-build wrappers copy the current environment and replace only DEVELOPER_DIR, so the Nix SDKROOT can remain active and divert Apple-native builds from the required host Xcode 26 SDK. Please use pkgs.mkShellNoCC or explicitly sanitize the environment, then verify npm run test:native and the relevant development/package path inside nix develop.

  2. The README overstates CI parity. It says Node and Rust are pinned to the versions CI uses, but this lock resolves Node 22.23.2 while CI pins 22.22.3. Rust is the exact match. Please either pin Node exactly or describe it as a compatible pinned Node 22 version.

  3. The real CI suite has not run. The exact-head CI run is action_required with zero jobs because this PR comes from an external fork. Only Pullfrog passed; TypeScript, lint, tests, Apple-native tests, and the production build have not executed. Please approve and run CI on commit f447695 before merge: https://github.com/sambitcreate/aiden-agent/actions/runs/30882577705

The flake locking, Rust toolchain reuse, and direnv watch setup otherwise look well scoped and additive.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants