Skip to content

Add Nix flake support with source build, prebuilt, and desktop outputs - #5

Draft
levonk wants to merge 26 commits into
acryldev:mainfrom
levonk:feature/nix-flake-support
Draft

Add Nix flake support with source build, prebuilt, and desktop outputs#5
levonk wants to merge 26 commits into
acryldev:mainfrom
levonk:feature/nix-flake-support

Conversation

@levonk

@levonk levonk commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add flake.nix with #acryl (TUI from source, also #default), #prebuilt (prebuilt CLI release tarball, v0.1.36), #acryl-desktop (Electron from source), and devShells.default
  • #prebuilt is conditionally exposed only on platforms with a release asset (x86_64-linux, aarch64-linux, aarch64-darwin). v0.1.36 does not ship a darwin-x64 CLI tarball, so #prebuilt is not available on x86_64-darwin — use #default or #acryl there.
  • Add devbox.json + devbox.lock for reproducible development environments
  • Add .github/workflows/nix.yml — CI builds all outputs on x86_64-linux, aarch64-linux, aarch64-darwin, and x86_64-darwin using macos-26/macos-26-intel runners
  • Add .github/workflows/nix-release.yml — daily hash automation that detects when flake.nix lags behind the latest GitHub release, prefetches new SRI hashes, and opens a PR
  • Update README.md, README.en.md, README.zh.md with Nix and Devbox install instructions
  • Update .gitignore with /result, /result-*, and .devbox/

Platform scope

The project's CI matrix is Linux-only, but the project ships release binaries for all four Nix target systems (x86_64-linux, aarch64-linux, aarch64-darwin, x86_64-darwin). This flake supports all four systems. The detect-platform-scope.sh nixify detection script reports linux_only because it inspects .github/workflows/ CI matrices, but the release assets cover all four platforms. This override is noted here per the nixify skill's requirement.

Supported systems

  • x86_64-linux — source build + prebuilt
  • aarch64-linux — source build + prebuilt
  • aarch64-darwin — source build + prebuilt
  • x86_64-darwin — source build only (via nixpkgs-26.05-darwin legacy pin; no prebuilt tarball available for this platform)

Relationship to nixpkgs

This project is not currently in nixpkgs. If there is interest in adding it, the flake's #acryl source build derivation could serve as the basis for a nixpkgs package expression.

Test plan

  • nix flake check --no-build passes on all systems
  • nix build .#acryl succeeds on all systems
  • nix build .#acryl-desktop succeeds on all systems
  • nix build .#prebuilt succeeds on x86_64-linux, aarch64-linux, aarch64-darwin
  • nix run .#acryl -- --help works
  • nix run .#prebuilt -- --help works (where available)
  • nix run .#acryl-desktop -- --help works
  • CI workflow runs green on all four systems
  • Hash automation workflow detects version lag and opens a PR

@musichen

musichen commented Sep 2, 2026

Copy link
Copy Markdown
Member

Hi @levonk thanks for contributing!
i'll review it once CI checks are green.

levonk added a commit to levonk/acryl that referenced this pull request Sep 2, 2026
…D hash

Four fixes for the CI failures on PR acryldev#5:

1. Rebase onto upstream/main (was 11 commits behind — caused the
   "Typecheck, test, and build" failure on a test already fixed on main)

2. Add use-flakehub: false to magic-nix-cache-action (the action defaults
   to use-flakehub: true, which attempts FlakeHub OIDC auth and breaks CI
   for orgs without a FlakeHub account — root cause of the "Unable to
   authenticate to FlakeHub" error)

3. Add timeout-minutes: 20 to the build job (was missing — GitHub's
   default max is 6h, caused the aarch64-darwin job to hang)

4. Update fetchPnpmDeps hash (stale after rebase picked up new upstream
   pnpm-lock.yaml changes)
@levonk
levonk force-pushed the feature/nix-flake-support branch from aa04fae to cfa8b92 Compare September 2, 2026 20:30
@levonk
levonk marked this pull request as draft September 2, 2026 23:08
@levonk
levonk marked this pull request as ready for review September 3, 2026 03:02
@musichen

musichen commented Sep 8, 2026

Copy link
Copy Markdown
Member

Resolved the conflict against current main in 3da7171.

The resolution preserves both branches' development-log entries. I ran the repository suite in the merged worktree: 806 ACRYL tests and 274 Market tests passed. The five refreshed GitHub checks are now running; I will use those as the final merge gate.

@levonk
levonk marked this pull request as draft September 9, 2026 23:31
levonk added a commit to levonk/acryl that referenced this pull request Sep 9, 2026
…D hash

Four fixes for the CI failures on PR acryldev#5:

1. Rebase onto upstream/main (was 11 commits behind — caused the
   "Typecheck, test, and build" failure on a test already fixed on main)

2. Add use-flakehub: false to magic-nix-cache-action (the action defaults
   to use-flakehub: true, which attempts FlakeHub OIDC auth and breaks CI
   for orgs without a FlakeHub account — root cause of the "Unable to
   authenticate to FlakeHub" error)

3. Add timeout-minutes: 20 to the build job (was missing — GitHub's
   default max is 6h, caused the aarch64-darwin job to hang)

4. Update fetchPnpmDeps hash (stale after rebase picked up new upstream
   pnpm-lock.yaml changes)
@levonk
levonk force-pushed the feature/nix-flake-support branch from 19fa777 to b3309f3 Compare September 9, 2026 23:31
@musichen

Copy link
Copy Markdown
Member

Thanks for the substantial work here - reviewed the flake end to end. This is real packaging engineering: the fetchPnpmDeps v4 usage, the documented nodeLinker override, the ESBUILD_BINARY_PATH substitution, autoPatchelf + musl handling for koffi, SHA-pinned actions with PR guards - all correct. The README.i18n.yaml hash-record update was a nice touch too.

Three blockers before merge:

  1. The branch is ~154 commits behind main and conflicts - needs a rebase.
  2. The pnpmDeps fixed-output hash is stale against main's current pnpm-lock.yaml - all four builds currently fail with hash mismatch (your fork's latest Nix run shows it). Refresh the hash after rebasing. Heads-up: every future pnpm-lock.yaml change invalidates it - are you up for owning flake maintenance as our Nix maintainer?
  3. x86_64-darwin can't install Determinate Nix on the macos-13 runner anymore (Intent to Ship: Dropping support for macOS Intel (x86_64-darwin) hosts DeterminateSystems/nix-src#224) - either cross-build that target from an arm64 runner or drop it from CI and keep the derivation for local Intel builders.

Would love one fully green 4-system run on the branch before merging. Happy to review the follow-up.

musichen pushed a commit to levonk/acryl that referenced this pull request Sep 11, 2026
…D hash

Four fixes for the CI failures on PR acryldev#5:

1. Rebase onto upstream/main (was 11 commits behind — caused the
   "Typecheck, test, and build" failure on a test already fixed on main)

2. Add use-flakehub: false to magic-nix-cache-action (the action defaults
   to use-flakehub: true, which attempts FlakeHub OIDC auth and breaks CI
   for orgs without a FlakeHub account — root cause of the "Unable to
   authenticate to FlakeHub" error)

3. Add timeout-minutes: 20 to the build job (was missing — GitHub's
   default max is 6h, caused the aarch64-darwin job to hang)

4. Update fetchPnpmDeps hash (stale after rebase picked up new upstream
   pnpm-lock.yaml changes)
@musichen
musichen force-pushed the feature/nix-flake-support branch from b3309f3 to fe21243 Compare September 11, 2026 17:06
levonk added a commit to levonk/acryl that referenced this pull request Sep 12, 2026
…D hash

Four fixes for the CI failures on PR acryldev#5:

1. Rebase onto upstream/main (was 11 commits behind — caused the
   "Typecheck, test, and build" failure on a test already fixed on main)

2. Add use-flakehub: false to magic-nix-cache-action (the action defaults
   to use-flakehub: true, which attempts FlakeHub OIDC auth and breaks CI
   for orgs without a FlakeHub account — root cause of the "Unable to
   authenticate to FlakeHub" error)

3. Add timeout-minutes: 20 to the build job (was missing — GitHub's
   default max is 6h, caused the aarch64-darwin job to hang)

4. Update fetchPnpmDeps hash (stale after rebase picked up new upstream
   pnpm-lock.yaml changes)
@levonk
levonk force-pushed the feature/nix-flake-support branch from 7d21d18 to e6868a4 Compare September 12, 2026 01:01
Add Nix flake support targeting the acryl-tui terminal client. The
flake uses nixpkgs' modern PNPM hooks (fetchPnpmDeps, pnpmConfigHook)
with pnpm_11 and fetcherVersion 4.

Key design decisions:
- Targets acryl-tui (not the Electron desktop app) as the default
  package, exposing the `acryl` binary via `nix run .#acryl`
- Uses nixpkgs-26.05-darwin legacy pin for x86_64-darwin (Intel
  macOS), since nixpkgs-unstable dropped support after 26.05
- Forces nodeLinker: hoisted in pnpm-workspace.yaml during the build
  to flatten node_modules (pnpm 11 moved this setting from .npmrc)
- Builds only the TUI dependency chain (acryl-control ->
  acryl-harness-runtime -> acryl-tui) instead of the full workspace
- Sets dontStrip and dontFixup to avoid slow strip/fixup phases on
  thousands of JS files in node_modules
- ESBUILD_BINARY_PATH points to nixpkgs esbuild to avoid the
  postinstall binary download (skipped by --ignore-scripts)

Also adds:
- devbox.json for reproducible development environment
- .github/workflows/nix.yml for CI across all 4 supported systems
- /result and /result-* to .gitignore
Document the implementation commit d6d2e46
which added Nix flake support for building acryl-tui.
Add `packages.${system}.acryl-desktop` to the flake, building the
Electron desktop app alongside the existing TUI output.

Key decisions:
- Uses nixpkgs electron (43.1.0) as the runtime instead of the npm
  electron package (which downloads a platform binary via postinstall,
  blocked by --ignore-scripts in the Nix sandbox)
- Creates a CJS shim at node_modules/electron/index.js that exports
  the nixpkgs electron path, replacing the real npm package
- Skips the generate-* build scripts (they use sharp for image
  processing) since build/ assets are already tracked in git
- Builds the full dependency chain: acryl-control ->
  acryl-harness-runtime -> dsh-community-market ->
  acryl-development-canvas -> acryl-desktop
- Refactors shared derivation attrs (pnpmDeps, preConfigure, etc.)
  into commonDerivationAttrs to avoid duplication between TUI and
  desktop derivations

Both outputs verified:
  nix run .#acryl -- --help
  nix run .#acryl-desktop -- --help
Document implementation commit 397f91034cb6a6444c6dccf6f33d06e8b10bf43b
which added the Electron desktop app as a separate Nix package output.
- SHA-pin all GitHub Actions to 40-char commit SHAs (checkout@v5,
  nix-installer-action@v22, magic-nix-cache-action@v14) instead of
  mutable @v4/@main refs — prevents supply-chain attacks
- Add if: github.event_name != 'pull_request' guard on nix run steps
  to prevent PR-controlled code from reaching GITHUB_TOKEN/OIDC
- Add path filtering to nix.yml (flake.nix, flake.lock, **/*.nix,
  pnpm-lock.yaml, etc.) so CI only fires when Nix files change
- Add nix run .#default -- --help test to CI
- Add act to devbox.json packages (required for local CI validation)
- Remove invalid nixpkgs.commit field from devbox.json (devbox 0.18
  ignores it; was set to channel name not 40-char hash)
- Add .devbox/ to .gitignore (devbox generated artifacts)
- Add Nix (Flake) and Devbox install sections to README.md,
  README.en.md, and README.zh.md
- Update bilingual-docs hash record in README.i18n.yaml

devbox.lock cannot be generated on x86_64-darwin due to devbox 0.18
hardcoding a nixpkgs commit that dropped x86_64-darwin support;
generate on aarch64-darwin or Linux.
devbox 0.18 ignores the nixpkgs.commit field for regular package-name
resolution and hardcodes nixpkgs 26.11, which dropped x86_64-darwin.
Work around this by referencing every package as a flake URL pointing
at the nixpkgs-26.05-darwin commit (f6107e5) — flake-based references
bypass devbox's package index, and nixpkgs.commit controls the shell
infrastructure (mkShell). This works on all platforms: x86_64-darwin,
aarch64-darwin, and Linux.

Generate and commit devbox.lock for reproducible environments.
Use per-package platform scoping: clean package names (nodejs_22,
pnpm_11, esbuild, act) for normal platforms (Linux, aarch64-darwin),
and flake URL references to nixpkgs-26.05-darwin only for x86_64-darwin.
The nixpkgs.commit field is set to the 26.05-darwin pin for the shell
infrastructure (mkShell), which devbox 0.18 honors when all active
packages on a platform are flake-based.

On normal platforms, packages resolve from nixpkgs-unstable via
devbox's index — the same behavior as before. On x86_64-darwin, the
flake URL references bypass devbox's hardcoded nixpkgs 26.11 (which
dropped x86_64-darwin) and pull from 26.05-darwin instead.

The lock file records both resolution paths. Linux/aarch64-darwin
entries will be populated when a user on that platform runs
devbox install.
Replace all github:levonk/acryl references with github:acryldev/acryl
in flake.nix (homepage meta), README.md, README.en.md, README.zh.md,
and DEVELOPMENT-LOG.md commit links. Update bilingual-docs hash record.
Add packages.<system>.prebuilt — fetches the prebuilt CLI tarball from
GitHub releases (v0.1.19). Each tarball bundles its own Node runtime
and native addons (node-pty, koffi, sharp), so no from-source build is
needed for the prebuilt path. Uses autoPatchelfHook on Linux for glibc
linking.

The default output remains #acryl (from-source build), following Nix
convention. #prebuilt is an optional fast path for users who want the
exact release binary.

Add CI steps to build and test #prebuilt on all 4 platforms.
Update READMEs to document the #prebuilt output.
…D hash

Four fixes for the CI failures on PR acryldev#5:

1. Rebase onto upstream/main (was 11 commits behind — caused the
   "Typecheck, test, and build" failure on a test already fixed on main)

2. Add use-flakehub: false to magic-nix-cache-action (the action defaults
   to use-flakehub: true, which attempts FlakeHub OIDC auth and breaks CI
   for orgs without a FlakeHub account — root cause of the "Unable to
   authenticate to FlakeHub" error)

3. Add timeout-minutes: 20 to the build job (was missing — GitHub's
   default max is 6h, caused the aarch64-darwin job to hang)

4. Update fetchPnpmDeps hash (stale after rebase picked up new upstream
   pnpm-lock.yaml changes)
levonk and others added 11 commits September 12, 2026 12:12
The preConfigure hook checked `if ! grep -q "nodeLinker"` and only
inserted `nodeLinker: hoisted` when the key was absent. But
pnpm-workspace.yaml already had `nodeLinker: isolated`, so the sed
never ran. The isolated linker creates a .pnpm/ virtual store with
symlinks that break when copied to the Nix store, leaving
node_modules/ with only 3 entries (the workspace packages) and no
registry dependencies like @deepseek-ai/dsh-llm.

Replace the value when the key exists, instead of only inserting when
missing. After this fix, node_modules/ has 648 packages and all four
outputs (default, acryl, prebuilt, acryl-desktop) pass smoke tests.
The prebuilt release tarball bundles both glibc-linked and musl-linked
native koffi addons (musl_x64/koffi.node alongside linux_x64/koffi.node).
autoPatchelfHook was only finding glibc (stdenv.cc.cc.lib), so it failed
with "could not satisfy dependency libc.musl-x86_64.so.1" on Linux.

Add pkgs.musl to buildInputs so autoPatchelf can patch both variants.
The magic-nix-cache v14 static binary for arm64-darwin fails on the
macos-14 runner with:
  dyld: Symbol not found: __ZNSt13exception_ptr31__from_native_exception_pointerEPv
  Expected in: /usr/lib/libc++.1.dylib

This is a DeterminateSystems binary incompatibility — the binary was
built against a newer libc++ than the runner ships. The build itself
never starts; the job hangs for 20 minutes then gets cancelled.

Make the cache action Linux-only. Darwin builds work without it, just
slower (no cache acceleration). The flake and builds are unaffected.
…ntel macOS runners

The macos-13 runner can no longer bootstrap Determinate Nix
(DeterminateSystems/nix-src#224), so the x86_64-darwin CI job fails
before building anything. Keep the derivation in flake.nix for local
Intel builders; restore the job via a Rosetta cross-build from
macos-14 when feasible.
… runner

Nixify skill compliance fixes after rebasing on upstream/main:

1. Update prebuilt version from v0.1.19 to v0.1.36 (latest release).
   Refresh all three per-platform SRI hashes by prefetching the
   new release assets. Remove x86_64-darwin from prebuiltAssets
   because v0.1.36 does not ship a darwin-x64 CLI tarball.

2. Make #prebuilt conditional via optionalAttrs so it is only
   exposed on platforms with a release asset (x86_64-linux,
   aarch64-linux, aarch64-darwin). On x86_64-darwin, nix run .#prebuilt
   correctly errors "package not available" instead of failing
   with a missing attribute error.

3. Add .github/workflows/nix-release.yml — daily hash automation
   workflow (scheduled lag-check template, required by nixify Step 16
   for prebuilt tarball flakes). Detects when flake.nix lags behind
   the latest GitHub release, prefetches new SRI hashes, and opens
   a PR. Uses GITHUB_TOKEN (releases are created with GITHUB_TOKEN
   via softprops/action-gh-release, so release: published would
   never fire).

4. Update aarch64-darwin CI runner from macos-14 to macos-26
   (nixify Step 16: always use the newest runner).
- Bump the Nix tag-pinning example from v0.1.19 to v0.1.36 in all three
  READMEs (README.md, README.en.md, README.zh.md).
- Note that #prebuilt is available on x86_64-linux, aarch64-linux, and
  aarch64-darwin only (v0.1.36 does not ship a darwin-x64 CLI tarball).
- Re-record the bilingual-docs blob hashes in README.i18n.yaml.
Add a development-log entry for the v0.1.36 prebuilt bump, the new
nix-release.yml hash automation workflow, the macos-26 runner update,
and the rebase onto upstream/main 0822873. Re-point the two earlier
Nix entries (acryl-desktop output and acryl-tui flake support) at
their rebased commit hashes.
@levonk
levonk force-pushed the feature/nix-flake-support branch from e6868a4 to 6cb9194 Compare September 12, 2026 19:48
The rebase onto upstream/main 227c3f9 pulled in a new pnpm-lock.yaml
(7869 lines changed) which invalidated the fetchPnpmDeps hash. Updated
to sha256-gqs/PgXIBj8+YsH/z/qIPa68XVNO7hu4eDxvShYkyxI= as reported by
the aarch64-darwin CI failure.
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