Skip to content

Releases: aubepkg/aube

v2.2.4: Trust the lockfile, skip the revalidation

Choose a tag to compare

@jdx jdx released this 31 Aug 15:45
Immutable release. Only release title and notes can be modified.
dbbb7f0

A small but impactful release: aube now treats versions recorded in your lockfile as already-accepted trust decisions, eliminating a costly per-package metadata re-fetch on frozen and repeat installs. In benchmarking this cut a cold install with a frozen lockfile by roughly 62% (from ~7.1s to ~2.7s), with lockfile trust resolution dropping from ~5.7s to ~15ms.

Fixed

  • Trust locked packages without revalidation (#1418 by @jdx) — With trustPolicy=no-downgrade (the default), aube previously re-fetched publishing trust evidence for every package name in the lockfile on each install, which dominated cold-install time. Now no-downgrade is enforced only when a version is newly resolved; versions already present in the active lockfile are trusted without re-fetching their evidence. Integrity checks and the rest of the install-time security pipeline are unchanged, and paranoid still forces the full pipeline.

Behavior Notes

  • Trust downgrade detection for a locked version no longer re-runs on every reuse — it applies when the version is first resolved. A fresh resolve (e.g. a new or changed dependency) still enforces no-downgrade as before. See the updated security docs for details on the lockfile trust boundary.

Full Changelog: v2.2.3...v2.2.4

💚 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.

v2.2.3: Land the ARM64 PGO Binary on the Host

Choose a tag to compare

@jdx jdx released this 02 Sep 13:00
Immutable release. Only release title and notes can be modified.
4e9341f

Another small release-plumbing patch that continues fixing the ARM64 Linux PGO build. The writable-home fix from v2.2.2 let the build complete, but Namespace mounts the cached target directory as a separate mount that the parent workspace bind didn't expose inside Docker — so the finished binary was stranded in a container-only tree and later host steps couldn't find it. This release wires that mount through so ARM64 builds can validate and publish. There are no user-facing changes to aube itself.

Fixed

  • Mount the cached ARM64 build target into the container (#1412 by @jdx) — The ARM64 PGO container now explicitly bind-mounts $GITHUB_WORKSPACE/target to /workspace/target, so the PGO+BOLT output and the Namespace-cached target directory are the same on the host. This lets the glibc validation, archive, and upload/attest steps find the built binary.

Full Changelog: v2.2.2...v2.2.3

💚 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.

v2.2.2: Unblock ARM64 PGO release builds

Choose a tag to compare

@jdx jdx released this 02 Sep 13:01
Immutable release. Only release title and notes can be modified.
981ec70

A tiny release-plumbing patch. The v2.2.1 ARM64 Linux PGO build failed because HOME=/tmp/aube-home was backed only by nested Docker mounts, leaving the home directory itself root-owned and unwritable, so mise couldn't create its state directory. This release fixes the workflow so those builds can publish. There are no user-facing changes to aube itself.

Fixed

  • Mount a writable home for ARM64 PGO builds (#1409 by @jdx) — The ARM64 PGO release container now bind-mounts a runner-owned writable home at /tmp/aube-home (with the Cargo registry and git caches nested inside), so the non-root container user can write mise state and Cargo metadata during the build.

Full Changelog: v2.2.1...v2.2.2

💚 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.

v2.2.1: Install path self-healing and cold-install speedups

Choose a tag to compare

@jdx jdx released this 02 Sep 13:01
Immutable release. Only release title and notes can be modified.
88c7215

A patch release focused on the install path: several fixes make aube install recover from stale caches and links on its own, node-gyp shims stay correct after dependency builds, peer resolution more closely matches pnpm, and cold/repeat installs on large repos get meaningfully faster.

Fixed

  • Self-heal stale node-gyp caches (#1407 by @jdx) — The node-gyp bootstrap cache no longer treats leftover .bin wrappers as healthy after their virtual-store targets are gone. A cache hit is now accepted only when the decoded wrapper's target still exists, so deleting the global virtual store triggers a clean re-bootstrap instead of returning a broken node-gyp path.
  • Self-heal stale links on non-workspace installs (#1406 by @jdx) — A non-workspace aube install could fail repeatedly with failed to link node_modules when a node_modules/.aube/<dep> entry still resolved but pointed at an outdated virtual-store subdir. The fetch phase now verifies the resolved target against the subdir the current graph expects, so a mismatched entry is re-fetched and the install recovers on the next run.
  • Refresh bin shims after dependency builds (#1404 by @jdx) — Approved dependency lifecycle scripts can change what a bin actually is (for example, pnpm 12's preinstall swaps a text placeholder for a native executable). Aube now relinks node_modules/.bin shims after dependency builds and side-effects-cache restores, while preserving lifecycle-created replacements, so shims reflect the final binaries before root scripts or user commands run.
  • Match pnpm importer peer semantics (#1399 by @jdx) — With autoInstallPeers, only an importer's own required peers (respecting peerDependenciesMeta.optional) are seeded as direct dependencies and linked at the workspace root; peers required by transitive dependencies stay in their peer context instead of getting synthetic importer rows and top-level links. Frozen-lockfile drift checks accept pnpm-generated importer peers and rewrite legacy Aube hoists, and aube check now reports a new dangling issue (human-readable and JSON) when an importer's virtual-store cell is missing.

Performance

  • Faster cold installs under the default trust policy (#1403 by @jdx) — With the default trustPolicy=no-downgrade, lockfile validation no longer downloads and re-serializes full packuments for every locked package. It now fetches one compact trust history per registry name, decodes only what the check reads, and caches it under trust-history-v1/. On the benchmark fixture this cut on-disk cache from 739 MB to 381 MB and shaved the resolve phase from 6.1s to 5.4s. Online installs can also skip re-validation via a lockfile-content stamp when validation would have been a cache hit anyway.
  • Cut freshness and repeat-install overhead on large repos (#1400 by @jdx) — Several structural costs behind slow no-op/repeat installs on big monorepos were removed: parallelized virtual-store link scans, a single parse of state.json in finalize, an early exit in project-link detection, a (size, mtime) fast path for the root lockfile on every aube run/exec/test startup, and compact JSON for state.json/fresh.json. Measured at −2.33% install instructions with no regressions.

Full Changelog: v2.2.0...v2.2.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.

v2.2.0: Bundled compatibility catalog and embeddable node-gyp bootstrap

Choose a tag to compare

@jdx jdx released this 25 Aug 20:51
Immutable release. Only release title and notes can be modified.
cf278e3

A small release that gives standalone aube a bundled package-extensions compatibility catalog and exposes its node-gyp bootstrap through the public embedding facade.

Added

  • Embeddable node-gyp bootstrap (#1365 by @jdx) — aube's locked, in-process node-gyp bootstrap is now available through the stable embedding facade and returns the resolved executable path. This lets embedders (e.g. mise) service aube's lazy shim command without an ambient npm or a separately installed aube binary, while aube keeps ownership of the node-gyp version, cache layout, npmrc propagation, and cross-process locking. Standalone aube's hidden __node-gyp-bootstrap command now routes through the same API, and binary lookup uses is_file() across platform names so Windows .exe/.cmd caches resolve correctly.

Fixed

  • Bundled curated package extensions (#1369 by @jdx) — Standalone aube now ships a bundled compatibility catalog (~161 curated rules from Yarn's @yarnpkg/extensions@2.0.7 plus pnpm's Rust CLI additions) that repairs missing or incompatible peer/optional dependencies across common ecosystems (Angular, Nuxt, React, Vue, Gatsby, GraphQL, Webpack, Parcel, and more). The phantom rules removed upstream by pnpm are excluded. These defaults are applied at the lowest precedence — user and project packageExtensions always win — and are kept out of packageExtensionsChecksum, so catalog updates never invalidate existing lockfiles or break --frozen-lockfile. Set ignoreCompatibilityDb=true to opt out of the bundled repairs; malformed bundled entries are skipped with a WARN_AUBE_INVALID_BUNDLED_PACKAGE_EXTENSION warning rather than failing the install.

Full Changelog: v2.1.0...v2.2.0

💚 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.

v2.1.0: Faster script runs and echoed commands

Choose a tag to compare

@jdx jdx released this 23 Aug 22:33
Immutable release. Only release title and notes can be modified.
b337f6a

This release centers on aube run: scripts now echo their expanded command line the way npm, pnpm, and bun do, and a series of startup and process-handoff optimizations trim overhead off every invocation. It also fixes global virtual store flags being dropped during aube ci.

Added

  • aube run echoes the script command line (#1358 by @jdx) — Before running a script, aube now prints its expanded command line to stderr prefixed with $, matching npm/pnpm/bun. This makes CI logs self-documenting: a failed aube run build now records exactly what build expanded to. The echoed line is the post-injection command (so a forwarded --inspect shows up), pre/post scripts each get their own line, and parallel recursive runs carry the same <package>: prefix as the rest of their output. Suppress it with --silent / -s / --loglevel silent.

    $ aube run build
    $ tsc -p .

    Note: this changes default stderr output for every script run — anything parsing aube's stderr will see the new line. Use --silent to opt out.

Fixed

  • aube ci honors global virtual store flags (#1355 by @jdx) — --disable-global-virtual-store / --enable-global-virtual-store (including via the clean-install alias) were being dropped by the CI install path and now correctly control whether packages are materialized locally or linked from the global store. The CI hard-disable of dependency builds is unchanged.

Performance

The run hot path saw several improvements. Individual gains are modest but compound on warm invocations, and after them aube run edges out bun run on plain script bodies:

  • Exec plain single-command scripts without a shell (#1363 by @jdx) — A script body that is one plain command (e.g. tsc -p ., vitest run, node build.js) is now resolved and exec'd directly instead of going through sh -c, eliminating a resident shell process. Anything with operators, expansion, quoting, globs, a custom scriptShell/shellEmulator, or --inspect still uses the shell path, and a resolution miss falls back to sh so exit-127 semantics are preserved.
  • Exec the final script shell on Unix (#1360 by @jdx) — For direct aubr runs on Unix, aube now replaces its own process with the final script shell (same PID) instead of supervising a child, removing a parent-process wait/exit handoff. Skipped when a post script still needs to run and for recursive/filtered/embedded runs.
  • Lightweight startup runtime for aubr scripts (#1357 by @jdx) — Warm script runs now start on a current-thread Tokio runtime instead of spinning up multi-thread workers; a full parallel install runtime is created lazily only when a stale tree actually needs installing.
  • Only rewrite node-gyp shims when they change (#1361 by @jdx) — The lazy node-gyp shims were rewritten (temp file + rename + chmod, twice per run) on every invocation. aube now compares content and mode first and leaves matching shims alone — worth ~6% of wall time on a trivial script — while still self-healing shipped shim fixes or a stripped exec bit.
  • Reuse manifest and settings contexts (#1359 by @jdx) — Consolidates redundant settings-source loads and a duplicate package.json read on the run path; the manifest used to select Node is now the same value used to select the script.

Full Changelog: v2.0.1...v2.1.0

💚 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.

v2.0.1: Aube's own global home, leaner resolver, and dramatically lower install memory

Choose a tag to compare

@jdx jdx released this 23 Aug 03:01
Immutable release. Only release title and notes can be modified.
fef0d5b

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-direct becomes a first-class resolution mode on the public resolver API (#1345).

Added

  • lowest-direct resolution mode (#1345 by @jdx) — pnpm's lowest-direct mode (resolve direct dependencies to the lowest compatible version) is now exposed directly through the public resolver API as ResolutionMode::LowestDirect, and CLI settings route through the enum. ResolutionMode is 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 --json now 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
    
  • EngineContext runtime embedder seam (#1326 by @jdalton) — A process-global EngineContext complements the compile-time Embedder profile, letting embedders supply per-invocation runtime values. The first wired seam lets an embedder provide bundled ecosystem packageExtensions defaults, applied as the lowest-precedence layer at resolve time (user/project extensions always win). Bundled extensions are kept out of the packageExtensionsChecksum, 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. For opencode-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 bundled node-gyp toolchain 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 the opencode-ai benchmark to ~77% (and ~24% faster wall time) versus the previous release. store prune also 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-gyp rebuilds) 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 pack and directory-based aube publish now rewrite default and named catalog: specifiers to resolved semver ranges across dependencies, devDependencies, optionalDependencies, and peerDependencies before writing the archive, so consumers no longer receive unresolvable catalog: protocol specifiers. The on-disk package.json is 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 -g no 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_HOME is no longer read, and macOS now honors an explicit XDG_DATA_HOME instead of always using ~/Library/pnpm. AUBE_HOME keeps 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, but aube list -g / aube remove -g no longer see them. To recover, put the new bin dir on PATH and re-run aube add -g <pkg>, or set AUBE_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) and WARN_AUBE_GLOBAL_BIN_DIR_NOT_ON_PATH (add -g linked a bin into a directory missing from $PATH). This release also fixes a related bug where remove -g left every global bin behind as a dangling symlink when the global virtual store was enabled.

  • Resolver API: ResolutionMode change (#1345 by @jdx) — For embedders using the resolver crate directly: Resolver::with_lowest_direct is removed in favor of Resolver::with_resolution_mode(ResolutionMode::LowestDirect), and ResolutionMode is 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.

v1.41.0: Faster removes, safer package extensions, and catalog pruning

Choose a tag to compare

@jdx jdx released this 16 Aug 20:49
Immutable release. Only release title and notes can be modified.
1268e21

This release adds a cache path command and pnpm-style catalog pruning, makes aube remove avoid unnecessary resolution and network requests, validates packageExtensions up front, and fixes several install/linker correctness issues around hoisted workspaces and global-virtual-store links.

Added

  • aube cache path command (#1302 by @jdx) — Prints the resolved metadata/policy cache root so CI jobs have one stable path to cache packuments, runtime metadata, and lockfile policy-verification records. It honors cacheDir/cache-dir overrides and platform defaults, and resolves the cache relative to the workspace/project root (so nested workspace packages share one root). Mirrors the command added in pnpm 11.22.

    aube cache path
    
  • catalogPrune setting (#1308 by @jdx) — Adds pnpm 11.22's catalogPrune as the canonical setting for pruning unused workspace catalog entries after install. The previous cleanupUnusedCatalogs name is retained as a deprecated alias; when both are set, catalogPrune wins. Configurable via env, .npmrc, workspace YAML, and settings.toml.

Fixed

  • Validate packageExtensions before resolution (#1304 by @jdx) — Malformed packageExtensions (non-object shapes, non-string dependency ranges like a null version, invalid peerDependenciesMeta) were previously dropped silently, quietly changing the effective policy. They now fail early with a stable ERR_AUBE_INVALID_PACKAGE_EXTENSION diagnostic that names the offending field path, applied consistently across install, update, remove, dedupe, and audit. aube remove validates before writing package.json so a bad policy can't leave the manifest and lockfile inconsistent.

  • Repair stale nested global-virtual-store links (#1299 by @jdx) — Warm installs and GVS cache hits could leave nested node_modules links inside shared global-virtual-store packages pointing at an outdated dependency identity even after the lockfile graph moved on. The linker now reconciles nested links in cached GVS entries (fixing stale, missing, or wrongly-targeted links), and the warm fast path is invalidated when shared topology drifts. Fixes #1298.

  • Keep hoisted workspace installs warm (#1295 by @jdx) — In hoisted workspaces where a member's direct dependency is satisfied from the root node_modules, install state previously always recorded a member-local path that is intentionally empty, so every freshness check treated a valid layout as stale and reinstalled the whole tree (and re-triggered "Auto-installing" on repeated aube run). Install state now records the actual ancestor-visible placement for hoisted direct dependencies. Fixes #1292.

  • SBOM output reflects the current host (#1309 by @jdx) — Default aube sbom output now filters out platform-incompatible optional packages using effective supportedArchitectures and ignoredOptionalDependencies, and aligns optional-edge traversal with pnpm/Yarn Berry semantics. A new --lockfile-only flag retains the complete platform-independent lockfile graph in the CycloneDX/SPDX output.

  • lowest-direct resolution is now distinct from time-based (#1307, #1311 by @jdx) — resolution-mode=lowest-direct now picks the oldest satisfying version for direct dependencies (with transitives still on the newest satisfying version) without computing a publish-time cutoff or writing a time: block into the lockfile, instead of being folded into time-based mode. The public aube_resolver::ResolutionMode enum stays stable for embedders — the behavior is driven through additive builder state rather than a new enum variant.

  • Embedded install memory diagnostics (#1303 by @jdx) — Embedded hosts such as mise now honor the same AUBE_DIAG_* env surface as the CLI, initializing and flushing diagnostics at operation boundaries. Adds OOM-safe per-event flushing (AUBE_DIAG_FLUSH=1), periodic current/peak RSS samples (AUBE_DIAG_KERNEL=1), and richer resolver/extraction metrics to help distinguish resolver retention from extraction spikes. Install behavior is unchanged. Supports #1301.

Changed

  • Faster aube remove without unnecessary resolution (#1306 by @jdx) — For single-project installs with a fresh lockfile, remove now prunes the removed roots and their unreachable transitive closure directly from the existing graph and relinks in frozen/offline mode, avoiding registry metadata requests entirely. Multi-importer workspaces, patch/catalog/manifest drift, removed overrides, and surviving peer contexts still fall back to full resolution.

Full Changelog: v1.40.0...v1.41.0

💚 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.

v1.40.0: Lifecycle script output for embedders

Choose a tag to compare

@jdx jdx released this 13 Aug 15:29
Immutable release. Only release title and notes can be modified.
71e0783

A small release whose only user-facing change lets embedding hosts capture lifecycle script output as tagged install events.

Added

  • Report lifecycle script output as install events (#1284 by @jdx) — When an install runs in event output mode, lifecycle script stdout and stderr are now piped and forwarded line-by-line as tagged InstallEvent::Output events (code AUBE_LIFECYCLE_SCRIPT_OUTPUT) instead of being written directly to the shared terminal. This lets embedding hosts such as mise render lifecycle logs through their own progress UI without corrupting it. The standalone Aube CLI and non-event installs are unchanged and keep inheriting stdio.

Full Changelog: v1.39.0...v1.40.0

💚 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.

v1.39.0: Configurable lockfile format & smarter store pruning

Choose a tag to compare

@jdx jdx released this 12 Aug 15:36
Immutable release. Only release title and notes can be modified.
7237e12

This release adds a configurable default lockfile format, lets store prune reclaim stale global-virtual-store entries, tightens devEngines version enforcement, and lets embedders drop the comment-preserving workspace-YAML dependency chain.

Added

  • Configurable default lockfile format (#1271 by @jdx) — New defaultLockfileFormat setting ("aube" or "pnpm", default "aube") chooses which lockfile to create when no supported lockfile is present on disk. Existing lockfiles remain authoritative, so the setting never converts a lockfile or writes a duplicate alongside one that already exists. This makes the aube clean --lockfile → reinstall workflow reliably regenerate pnpm-lock.yaml for projects that need pnpm compatibility. Configurable via workspace config, settings.toml, .npmrc, and env, and applied consistently across install and the add/remove/update/dedupe/audit write paths. Addresses #1264.

    # settings.toml
    defaultLockfileFormat = "pnpm"
    
  • Optional workspace YAML preservation for embedders (#1278 by @jdx) — Comment- and format-preserving pnpm-workspace.yaml edits are now gated behind a default-on workspace-yaml-preserve feature. The standalone Aube CLI is unchanged, but embedders (e.g. mise) can disable the feature to drop the yamlpatch/yamlpath/tree-sitter dependency chain — which required Rust 1.97+ — falling back to a canonical full-document rewrite.

Fixed

  • Prune unused global virtual store entries (#1273 by @jdx) — aube store prune previously only walked the content-addressable store, leaving hashed graph directories under <cacheDir>/virtual-store behind even after their projects were deleted. Installs that use the global virtual store now register the project (including warm/fast-path installs after upgrading), and prune uses that registry to keep entries still linked from live projects while removing unreachable ones before continuing with normal content-store cleanup. Installs and pruning coordinate via shared/exclusive locks, registry-managed entries live under a versioned virtual-store/v1/ namespace so older releases' entries are untouched, and registry failures fail closed with ERR_AUBE_GVS_PRUNE_FAILED. --dry-run covers the new phase. Addresses #1268.

  • Enforce devEngines aube version errors (#1269 by @jdx) — An explicit devEngines.packageManager.onFail: "error" now correctly rejects the invoking aube when its version does not satisfy the declared aube version, instead of silently re-execing to an already-installed match. The same self-version policy is now enforced for aube --version (which previously returned before self-version handling), and aube --version --workspace-root works outside a workspace. devEngines.packageManager entries naming pnpm or other package managers keep their existing compatibility behavior. Fixes #1263.

Full Changelog: v1.38.1...v1.39.0

💚 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.