v2.0.1: Aube's own global home, leaner resolver, and dramatically lower install memory
This is the first release of the aube 2.x line. It moves global installs out of pnpm-owned directories and into aube's own data root, promotes lowest-direct to a first-class resolver mode, and slashes install-time memory usage for packages with large, multi-platform optional dependency graphs. Because of the global directory change, upgrading requires action for anyone who relies on aube add -g — see Breaking Changes.
Highlights
- Global installs now live under aube's own data root instead of pnpm's directories, with warnings to guide the one-time migration (#1231).
- Up to 77% less peak memory on installs with large optional platform graphs thanks to compact optional-package histories and streaming large tar entries into the store (#1315, #1318).
lowest-directbecomes a first-class resolution mode on the public resolver API (#1345).
Added
-
lowest-directresolution mode (#1345 by @jdx) — pnpm'slowest-directmode (resolve direct dependencies to the lowest compatible version) is now exposed directly through the public resolver API asResolutionMode::LowestDirect, and CLI settings route through the enum.ResolutionModeis now#[non_exhaustive]. See Breaking Changes for the embedder-facing API change. -
Structured prune previews for
aube store prune(#1321 by @jdx) —aube store prune --dry-run --jsonnow emits a machine-readable schema-v1 plan: mutation roots, planned actions, per-subsystem (GVS/CAS) counts, reclaimable-byte upper bounds, and structured warnings. The same plan drives human previews, JSON previews, and real deletes, so what you preview is what gets pruned. Store writers are serialized against prune via a store-wide maintenance lock, and dry runs no longer migrate legacy indexes or initialize the project registry.aube store prune --dry-run --json -
EngineContextruntime embedder seam (#1326 by @jdalton) — A process-globalEngineContextcomplements the compile-timeEmbedderprofile, letting embedders supply per-invocation runtime values. The first wired seam lets an embedder provide bundled ecosystempackageExtensionsdefaults, applied as the lowest-precedence layer at resolve time (user/project extensions always win). Bundled extensions are kept out of thepackageExtensionsChecksum, so bumping the bundled list never drifts existing lockfiles or breaks--frozen-lockfile. Every field defaults to upstream-neutral behavior, so standalone aube is unaffected.
Fixed
-
Compact exact optional package histories (#1315 by @jdx) — With time-aware resolution (
minimumReleaseAge, trust no-downgrade), exact optional platform packages previously retained every historical version's full dependency and distribution metadata. Aube now decodes each exact optional dependency from a single packument response, keeping full metadata only for the selected version and just publish-time/trust evidence for the rest. Lockfile platform coverage and trust semantics are unchanged. Foropencode-ai@1.18.18, retained platform version records dropped from 136,110 to 11,890, cutting median peak RSS by ~47% and wall time by ~20% versus the previous release. The bundlednode-gyptoolchain is now also bootstrapped lazily (only when a lifecycle script actually invokes it) instead of before every approved lifecycle. -
Stream large tar entries into the store (#1318 by @jdx) — Large regular tar entries (≥8 MiB, when store compression is off) now stream into a content-addressed store tempfile while being hashed, then publish atomically, instead of being buffered fully into memory with
read_to_end. Combined with the resolver change above, this brings the total peak-memory reduction on theopencode-aibenchmark to ~77% (and ~24% faster wall time) versus the previous release.store prunealso cleans up orphaned streaming tempfiles left by crashes. -
Preserve applied builds after cache cleanup (#1339 by @jdx) — Clearing the reusable side-effects cache no longer forces dependency build scripts (e.g. native
node-gyprebuilds) to rerun for packages whose build output is already applied. Aube now treats a matching in-package side-effects marker as evidence the build is already in place, and only rebuilds when the generated output is actually missing or changed. -
Resolve
catalog:dependencies when packing and publishing (#1334 by @jdx) —aube packand directory-basedaube publishnow rewrite default and namedcatalog:specifiers to resolved semver ranges acrossdependencies,devDependencies,optionalDependencies, andpeerDependenciesbefore writing the archive, so consumers no longer receive unresolvablecatalog:protocol specifiers. The on-diskpackage.jsonis left untouched (including its indentation and line endings), and published registry metadata matches the tarball. Fixes #1333.
Breaking Changes
-
Global directories moved out of pnpm's layout (#1231 by @jdx) —
aube add -gno longer installs into pnpm-owned locations (PNPM_HOME,$XDG_DATA_HOME/pnpm,~/Library/pnpm,%LOCALAPPDATA%\pnpm). Globals now hang off aube's own data root, matching the store and runtimes:<data_root>/bin # globalBinDir — put this on PATH <data_root>/global-aube # physical installs<data_root>resolves to$XDG_DATA_HOME/<namespace>(~/.local/share/<ns>, or%LOCALAPPDATA%\<ns>on Windows).PNPM_HOMEis no longer read, and macOS now honors an explicitXDG_DATA_HOMEinstead of always using~/Library/pnpm.AUBE_HOMEkeeps its existing meaning, so anyone who already set it sees no change.Packages installed globally by aube 1.x are not migrated. Their bins keep working while the old directory is on
PATH, butaube list -g/aube remove -gno longer see them. To recover, put the new bin dir onPATHand re-runaube add -g <pkg>, or setAUBE_HOME=<old dir>to pin the previous layout. Two new warnings flag the silent failure modes:WARN_AUBE_GLOBAL_DIR_LEGACY_LOCATION(globals found only in the old pnpm-named location; the old directory is only ever read, never modified) andWARN_AUBE_GLOBAL_BIN_DIR_NOT_ON_PATH(add -glinked a bin into a directory missing from$PATH). This release also fixes a related bug whereremove -gleft every global bin behind as a dangling symlink when the global virtual store was enabled. -
Resolver API:
ResolutionModechange (#1345 by @jdx) — For embedders using the resolver crate directly:Resolver::with_lowest_directis removed in favor ofResolver::with_resolution_mode(ResolutionMode::LowestDirect), andResolutionModeis now#[non_exhaustive], so matches must include a wildcard arm. Resolution behavior is otherwise unchanged.
New Contributors
Full Changelog: v1.41.0...v2.0.1
💚 Sponsor aube
aube is maintained by @jdx, an open source developer for entire.io, the title sponsor of the jdx.dev open source tools including mise. Work on aube is funded by sponsors.
If aube is saving your team install time or CI minutes, please consider sponsoring at jdx.dev. Individual and company sponsorships are what keep the project fast, free, and independent.