Skip to content

Releases: endevco/aube

v1.9.1: Cold install overhaul, HTTP prefetch, and workspace fixes

07 May 00:00
Immutable release. Only release title and notes can be modified.
8e28ce5

Choose a tag to compare

A performance- and correctness-focused patch release. Cold installs get a streaming tarball pipeline, Linux gets an O_TMPFILE+linkat CAS fast path, and the resolver's cold path overlaps DNS, TLS, and packument prefetch with the manifest/workspace/lockfile work that used to serialize them. On the fix side, aube run once again finds node-gyp for package scripts, and aube update / aube outdated stop trying to fetch unpublished workspace: deps from the registry.

Added

  • Pre-resolver packument prefetch + shared HTTP utilities (#529 by @imjustprism) — a new aube-util::http module consolidates client-side primitives (prewarm, priority, race, resolve, ticket_cache) so leaf crates share one warm-pool surface with consistent killswitch semantics. On install entry, aube now reads package.json and fires fire-and-forget packument GETs for every registry-shaped direct dep before workspace yaml load, settings resolve, lockfile parse, and resolver construction — by the time the resolver pops its first task, the packument cache and reqwest pool are warm. RegistryClient::prewarm_connection now covers the default registry plus every scoped (@org:registry=...) and per-uri auth registry, with parallel DNS preresolve so DNS RTT hides behind the TLS handshake. Abbreviated packument GETs also send Priority: u=0 (RFC 9218 Critical) so H2 schedulers prioritize resolver-blocking metadata over pending tarball frames. New killswitches: AUBE_DISABLE_DNS_PRERESOLVE, AUBE_DISABLE_REQUEST_RACING, AUBE_DISABLE_PREFETCH, AUBE_DISABLE_TLS_TICKET_CACHE. Prefetch is a no-op when offline or when any lockfile is present.

  • Cold install pipeline overhaul (#522 by @imjustprism) — several overlapping wins on the cold-cache path:

    • Streaming tarball pipeline (opt-in via AUBE_TARBALL_STREAM=1, killswitch AUBE_DISABLE_TARBALL_STREAM) — HTTP body chunks pipe through SHA-512 + gz + tar + CAS via an mpsc bridge instead of buffering the whole tarball; non-SHA-512 SRI falls back to buffered. Bounded by the registry's tarball_max_bytes cap.
    • Linux O_TMPFILE + linkat CAS publish with EOPNOTSUPP fallback to the tempfile path, posix_fallocate to avoid ext4 fragmentation, and posix_fadvise(DONTNEED) to free page cache after publish. Killswitch: AUBE_DISABLE_O_TMPFILE.
    • Materialize-stream into the lockfile fast path — both lockfile and no-lockfile branches now share the GVS prewarm materializer, hiding 30-200ms of GVS reflinks behind the in-flight download tail.
    • Resolver tuning — foldhash on graph_hash hot maps, pre-sized resolver caches, thread-local node_semver::Version parse cache, PARALLEL_IMPORT_THRESHOLD lowered from 256 to 16 (median npm tarball is 7 files), and pinned tokio worker_threads (cpu.min(8)) / max_blocking_threads(64) (tunable via AUBE_TOKIO_WORKERS / AUBE_TOKIO_BLOCKING).
    • Windows gets FILE_ATTRIBUTE_NOT_CONTENT_INDEXED on the store root; cross-volume detection (drive letters on Windows, dev id on Unix) is gated per-platform.

    Reported same-volume Windows cold-install ratios: 1.80x-8.75x faster than Bun across svelte/vite/next/babylon.

  • Per-project materialize pipelined into fetch (#527 by @imjustprism) — when GVS is off, each fetched (canonical_key, PackageIndex) triggers materialize_into against .aube/<dep_path>/ immediately, so by the time fetch finishes the dedicated link phase only has to create top-level node_modules/<name> symlinks. The driver now uses JoinSet instead of Vec<JoinHandle>, so on early-return all in-flight tasks abort instead of detaching and racing install cleanup. ~10% improvement on warm fresh installs in the local benchmark matrix.

Fixed

  • aube run / aube test find node-gyp (#518 by @jdx) — package scripts only had node_modules/.bin prepended to PATH, so aube test would fail with node-gyp: not found on hosts that didn't already ship it. Script execution now reuses aube's existing node-gyp bootstrap (via a lazy shim bin dir + AUBE_NODE_GYP_EXE / AUBE_NODE_GYP_PROJECT_DIR), matching pnpm/npm behavior. Ports pnpm's lifecycleScripts.ts:128 coverage into the offline node-gyp bootstrap bats suite.

  • workspace: deps in aube update / aube outdated (#523 by @jdx, fixes #520) — aube update now discovers workspace package name/version pairs and passes them into resolver workspace resolution so workspace: deps from package.json#workspaces resolve locally instead of triggering registry packument fetches. aube outdated filters out direct deps with workspace: specifiers and reports "no matching dependencies" rather than attempting a packument fetch. Adds a new WARN_AUBE_WORKSPACE_PACKAGE_MISSING_NAME warning code for workspace packages without a name field.

  • Resolver peer-context divergence is fatal (#522 by @imjustprism) — apply_peer_contexts hitting MAX_ITERATIONS used to log a warning and ship a broken graph; it now returns a fatal Error::PeerContextDivergence(usize). state::remove_state errors at --force and GVS-transition sites also propagate instead of being silently swallowed, so permission-denied or Windows-locked sidecars no longer defeat the freshness check.

  • Tarball hardening (#522 by @imjustprism) — entries declared as 0 bytes with non-zero stream payload are now rejected (synthetic-entry injection guard), and GNU LongName / LongLink metadata records are correctly accepted.

  • Patches loaded once per cwd (#529 by @imjustprism) — load_patches_for_linker walked patches/ from disk 2-3 times per install (lockfile-prewarm, no-lockfile-prewarm, and link-phase sites). Now cached per cwd via OnceLock<Mutex<HashMap<PathBuf, ...>>>.

Full Changelog: v1.9.0...v1.9.1

💚 Sponsor aube

aube is part of en.dev — an independent developer-tooling studio run by @jdx, also behind mise. Work on aube is funded entirely by sponsors.

If aube is saving your team install time or CI minutes, please consider sponsoring at en.dev. Individual and company sponsorships are what keep the project fast, free, and independent.

v1.9.0: Comment-preserving workspace edits, deploy bundling, and node --inspect

05 May 18:55
Immutable release. Only release title and notes can be modified.
81fd1ca

Choose a tag to compare

A focused release: aube deploy learns to bundle workspace siblings and local-path deps into the deploy artifact, workspace-yaml writers stop eating user comments, aube-owned settings move out of .npmrc, and aube run forwards Node debugger flags.

Added

  • Aube settings move out of .npmrc (#517 by @jdx) — known aube-owned settings now live in ~/.config/aube/config.toml (XDG-aware), while registry, auth, and unknown keys keep using .npmrc. aube config get/set/list/delete reads and writes the right file automatically, and migrating a known setting cleans up the stale .npmrc entry. .npmrc writes are also atomic against the symlink target now, so dotfile setups that symlink ~/.npmrc into a managed config repo stop having the symlink replaced by a regular file.

  • aube run --inspect / --inspect-brk (#515 by @jdx) — both flags accept an optional [host:]port (e.g. --inspect=9229, --inspect-brk=0.0.0.0:9230) and are forwarded as explicit Node argv when aube can identify a Node-backed target — direct node ... scripts in package.json and local node_modules/.bin fallbacks resolved through shims/symlinks. The flags are passed as argv rather than via NODE_OPTIONS, so the debugger doesn't attach to nested Node processes spawned by the script.

  • aube deploy --no-prod (#507 by @jdx) — opt out of the default --prod filter for deploys that need devDependencies at runtime (test-harness staging, build-step artifacts). Mutually exclusive with --prod / --dev; combine with --no-optional to keep prod + dev but drop optionals.

  • Comment-preserving workspace yaml writes (#511 by @jdx) — every workspace-yaml writer (approve-builds, patch-commit, patch-remove, the daily cleanupUnusedCatalogs install pass, and aube config set --location workspace) now routes through yamlpatch instead of round-tripping the file through a serializer. Keys, comments, and whitespace the edit didn't touch land back on disk byte-identical, so user annotations on adjacent entries survive. Empty/missing files still go through the regular serializer since there are no comments to preserve.

Fixed

  • aube deploy bundles local dependencies (#507 by @jdx) — fixes two real bugs reported in #345:

    • workspace:* siblings tried to fetch from the registry. Deploy used to rewrite workspace:* to a concrete version and ask install to resolve it — fine for published siblings, broken for the (very common) unpublished case. Reachable workspace siblings are now copied into <target>/.aube-deploy-injected/<id>/ and the manifest spec becomes a relative file: pointer. Recursion handles sibling chains where a sibling's own deps are workspace siblings.
    • file: deps resolved relative to the deploy output dir. A file:../local-vendor spec used to ride along unchanged in the deployed manifest, pointing at <target>/../local-vendor instead of the source workspace's local-vendor. Local-path deps now go through the same staging pipeline.

    When bundling occurs the lockfile-subset path is skipped, since the rewritten file: pointers don't appear in the source lockfile and would otherwise trip a frozen install.

  • aube remove preserves dependency order (#511 by @jdx) — dropping one dep used to alphabetize the remaining entries in the affected package.json section as a side effect. Surviving entries now stay in their original on-disk order, matching pnpm/npm. (aube add is unaffected — sorted inserts there are intentional.)

Full Changelog: v1.8.0...v1.9.0

💚 Sponsor aube

aube is part of en.dev — an independent developer-tooling studio run by @jdx, also behind mise. Work on aube is funded entirely by sponsors.

If aube is saving your team install time or CI minutes, please consider sponsoring at en.dev. Individual and company sponsorships are what keep the project fast, free, and independent.

v1.8.0: Stable error codes, smarter run/dlx, and a new install progress UI

03 May 20:55
Immutable release. Only release title and notes can be modified.
7f8608b

Choose a tag to compare

A polish-and-plumbing release: install progress gets a from-scratch redesign, errors and warnings now carry stable identifiers (with bespoke exit codes and dep-chain context), aube run / aube dlx prefer locally-installed binaries, and a handful of workspace-from-subpackage and aube add ergonomics get fixed.

Added

  • Redesigned install progress UI (#501 by @jdx) — fixed 15-char bar on the left, stats on the right, phase-aware label (resolving / fetching / linking), ETA, transfer rate, and an estimated install size derived from the resolve stream:

    aube 1.8.0 by en.dev
    █████░░░░░░░░░░ 23/142 pkgs · 4.2 MB / ~13.8 MB · 1.4 MB/s · ETA 5s
    ███████████████ 1230/1230 pkgs · linking
    ✓ resolved 1230 · reused 98 · downloaded 1132 (54.6 MB) in 6.8s
    

    Installs that finish before the first 2s heartbeat now print a single self-identifying summary line (✓ installed 5 packages in 423ms) instead of a partial bar. Also fixes two real bookkeeping bugs (a 2/1 packages overflow on platform-mismatched non-optional deps, and the "stuck at 90%" undercount caused by filter_graph dropping packages after the denominator was inflated).

  • Local bins for aube run and aube dlx (#502 by @jdx) — aube run <name> falls back to node_modules/.bin/<name> when no package.json script matches, and aube dlx / aubx will execute an already-installed local binary instead of doing a throwaway install. Pass -p / --package (or a versioned spec) to force the install path.

  • Stable error and warning codes (#492 by @jdx) — every error and warning aube emits now carries an ERR_AUBE_* or WARN_AUBE_* identifier in a structured field, so CI scripts and ndjson consumers can branch on the code instead of substring-matching English messages. A curated subset maps to bespoke Unix exit codes (10–99 in 10-wide ranges by category) so shells can react to specific failures without parsing stderr — e.g. aube install --frozen-lockfile in an empty dir exits with 10 (ERR_AUBE_NO_LOCKFILE). Post-resolver errors that mention a specific package now also include the dependency chain back to the importer (chain: a@1 > b@2 > leaf@3) so a tarball-integrity or fetch failure tells you why your install pulled that transitive dep. The full code list lives at docs/error-codes.md.

Fixed

  • aube why / list / query from a workspace subpackage (#504 by @jdx) — these commands resolved cwd via the nearest package.json, so running them inside packages/foo/ errored with No lockfile found. Run aube install first. even though the workspace lockfile sat one level up. They now walk up to the workspace root when one is present.

  • Workspace lifecycle scripts and pnpm-lock npm aliases (#500 by @jdx) — recursive workspace installs now run preinstall/install/postinstall/prepare for each linked workspace importer in dependency order (not just the root), and the build-script policy merges pnpm.allowBuilds / onlyBuiltDependencies / neverBuiltDependencies across all participating manifests so a member can approve its own dep's builds. pnpm-lock.yaml now writes npm aliases in pnpm's native <real>@<version> encoding instead of leaking aube's internal aliasOf field.

  • aube add auto-detects local paths (#499 by @jdx) — aube add /path/to/lib, ./lib, ~/lib, file:./lib, and link:./lib no longer fall through to the registry path with a confusing HTTP 405 Method Not Allowed. Bare paths default to link: for directories and file: for tarballs (pnpm parity); explicit prefixes are preserved. Tarball-suffix paths emit a clear "not yet supported in aube add" hint instead of a 405.

Changed

  • Per-command --help is bucketed (#505 by @jdx) — --frozen-lockfile / --prefer-frozen-lockfile, --registry + --fetch-*, and --disable/--enable-global-virtual-store moved off the global flag set into per-command groups under Lockfile / Network / Virtual store headings, and now appear only on commands that consume them. Seven pnpm-compat no-op flags (--workspace-packages, --ignore-workspace, --include-workspace-root, --aggregate-output, --stream, --use-stderr, --yes) are still parsed but hidden from --help. Pre-subcommand placement still works (aube --frozen-lockfile install, aube --registry=URL install) via an argv pre-pass.

    One caveat: implicit-script invocations like aube --frozen-lockfile dev (where dev is a package.json script) no longer apply the flag — write aube run --frozen-lockfile dev instead.

Full Changelog: v1.7.0...v1.8.0

💚 Sponsor aube

aube is part of en.dev — an independent developer-tooling studio run by @jdx, also behind mise. Work on aube is funded entirely by sponsors.

If aube is saving your team install time or CI minutes, please consider sponsoring at en.dev. Individual and company sponsorships are what keep the project fast, free, and independent.

v1.7.0: Local & git specs in aube add, faster cold installs

03 May 01:23
Immutable release. Only release title and notes can be modified.
b3ec965

Choose a tag to compare

A feature-heavy release: aube add learns git and local-path specs, workspace commands gain support for yaml-only "coordinator" monorepos, aube update and aube rebuild get pnpm-parity polish, and a deep performance pass speeds up cold installs by up to ~1.9×.

Highlights

  • aube add is now a one-stop shop for git, GitHub-shorthand, and link: / file: local-path dependencies — not just registry packages.
  • Performance pass on the install hot path (#469) lands streaming SHA-512, parallel CAS imports, TLS prewarm, fetch reordering, and a long tail of cold-path cleanups, with measured cold-install speedups up to ~1.9× vs v1.6.2.
  • Workspace and pnpm parity polish across update, rebuild, yaml-only roots, unversioned members, and nested link: / file: resolution.

Added

  • aube add file:./pkg / link:../sibling (#487 by @jdx) — local-path specs are routed through a non-registry branch, with the manifest key derived from the path basename (with .tgz / .tar.gz stripped) or from an explicit alias. aube add my-bundle@file:./bundle.tgz works too.

  • aube add supports git specs (#483 by @jdx) — bare GitHub shorthand, github: / gitlab: / bitbucket: prefixes, full git+ssh / git+https URLs, and aliases. The verbatim spec is written to package.json and the resolver handles the rest:

    aube add kevva/is-negative
    aube add github:kevva/is-positive
    aube add my-alias@git+https://github.com/kevva/is-negative.git
  • Yaml-only workspace roots (#486 by @jdx) — install, list, run -r, query, and why now work in pure-coordinator monorepos that have pnpm-workspace.yaml / aube-workspace.yaml at the root but no root package.json (Turborepo-style layouts). Single-project commands like add / remove still hard-error without a manifest.

  • aube update <pkg> rewrites manifest ranges by default (#479 by @jdx) — caret/tilde ranges (^1.2.0, ~1.2.0) are rewritten to track the resolved in-range max, matching pnpm. Other shapes (>=, exact pins, dist-tags, git, workspace:) stay frozen. Set update-rewrites-specifier=false to keep the previous behavior.

  • aube rebuild <pkg>... (#477 by @jdx) — runs lifecycle scripts only for the named deps, bypasses the allowBuilds / onlyBuiltDependencies policy, and skips root hooks. Composes with --filter. Bare aube rebuild continues to do a full policy-respecting rebuild.

  • Persistent unreviewed-builds warning (#476 by @jdx) — repeat warm-path installs no longer swallow the "ignored build scripts for N package(s)" nudge; the spec keys are persisted in .aube-state and re-emitted on every install.

  • aube update --depth no longer silently ignored (#473 by @jdx) — emits a one-line warning pointing at rm aube-lock.yaml && aube install for the only useful semantic case.

Fixed

  • Faster cold installs (#469 by @imjustprism) — a wide hot-path pass with measurable wins on real registries:

    Project v1.6.2 v1.7.0 Speedup
    svelte (56 pkg) 1393 ms 1386 ms 1.01×
    vue (117 pkg) 1590 ms 1360 ms 1.17×
    next.js (336 pkg) 14071 ms 9160 ms 1.54×
    babylon (21 pkg) ~6000 ms 3186 ms ~1.9×

    Highlights: streaming SHA-512 over the wire (no second buffered hash pass), two-phase parallel CAS tar import, speculative TLS/HTTP/2 prewarm behind manifest parse, native-build packages floated to the front of the fetch queue, Accept-Encoding: gzip, br, zstd on packuments, in-process DNS cache via hickory-dns, mmap+rayon BLAKE3 over 4 MiB, network concurrency default raised 64 → 128, and zero-copy packument parsing. Every change ships with an AUBE_DISABLE_* killswitch (AUBE_DISABLE_STREAMING_SHA512, AUBE_DISABLE_SPECULATIVE_TLS, AUBE_DISABLE_CRITICAL_PATH, AUBE_DISABLE_PARALLEL_IMPORT, AUBE_DISABLE_MMAP_BLAKE3, AUBE_DISABLE_SNAPSHOTS) plus an AUBE_CONCURRENCY=N clamp.

  • Nested link: / file: resolution (#470 by @jdx) — fixes the transitive local specifier link:./libs/foo cannot be resolved without the parent package source root install error in two cases: a file: / link: parent declaring a transitive link:, and a root pnpm.overrides rewriting a registry dep to a local path. Override paths now anchor at the project root like pnpm does.

  • Workspace members without version (#480 by @jdx) — fall back to 0.0.0 instead of hard-erroring. workspace:* / ^ / ~ siblings still link locally; specific ranges like workspace:^2.0.0 still correctly fail to satisfy. Unblocks repos like tuist/tuist#10584.

  • Bare user/repo parsed as GitHub shorthand (#472 by @jdx) in lockfile/spec parsing, with update --latest now skipping git-spec deps so they can't be silently rewritten into registry pins.

  • CLI short help wraps cleanly (#478 by @jdx) — many flags across add, install, publish, update, view, etc. had multi-line doc comments that clap merged into 120+ char paragraphs for -h. Now each flag has a one-line summary followed by the longer prose, restoring readable short help on standard terminals.

Full Changelog: v1.6.2...v1.7.0

💚 Sponsor aube

aube is part of en.dev — an independent developer-tooling studio run by @jdx, also behind mise. Work on aube is funded entirely by sponsors.

If aube is saving your team install time or CI minutes, please consider sponsoring at en.dev. Individual and company sponsorships are what keep the project fast, free, and independent.

If aube is saving your team install time or CI minutes, please consider sponsoring at en.dev. Individual and company sponsorships are what keep the project fast, free, and independent.

v1.6.2: Engines coverage catches up to pnpm

01 May 23:07
Immutable release. Only release title and notes can be modified.
e7b8989

Choose a tag to compare

A small patch release that closes engine-validation gaps with pnpm.

Fixed

  • Broader engines coverage (#458 by @jdx) — aube now honors engine constraints it previously skipped:
    • engines.aube and engines.pnpm on root and workspace project manifests are checked against the running aube version (aube positions itself as a pnpm-compatible drop-in, so engines.pnpm is honored as if aube were that pnpm).
    • engines.node is now enforced on workspace project manifests, not just the root.
    • Warning output labels which engine triggered the mismatch (e.g. wanted node >=20, wanted aube >=99999, wanted pnpm >=8), and the engine-strict error message stays compatible with existing assertions.
    • engines.{aube,pnpm} on transitive deps remain skipped on purpose, since wild packages routinely pin author toolchains.

Full Changelog: v1.6.1...v1.6.2

💚 Sponsor aube

aube is part of en.dev — an independent developer-tooling studio run by @jdx, also behind mise. Work on aube is funded entirely by sponsors.

If aube is saving your team install time or CI minutes, please consider sponsoring at en.dev. Individual and company sponsorships are what keep the project fast, free, and independent.

v1.6.1

01 May 21:21
Immutable release. Only release title and notes can be modified.
98cec0f

Choose a tag to compare

Fixed

  • Unblocked the v1.6.0 publishing path so missing Linux release assets and downstream package publishes could be backfilled (#460).
  • Made the resolver build script tolerate environments where the primer generator exists but node is not installed, falling back to an empty primer with a Cargo warning instead of panicking (#460).
  • Moved npm publishing and PPA upload jobs back to GitHub-hosted runners where npm provenance and Launchpad FTP uploads work correctly (#460).

Other

  • Refreshed benchmarks for the 1.5.2 baseline (#459).

v1.6.0

01 May 19:50
Immutable release. Only release title and notes can be modified.
8a60d6d

Choose a tag to compare

Highlights

  • Added broader pnpm compatibility for aube add, aube update, pnpmfile hooks, catalog saves, workspace protocol parsing, and lockfile directory configuration.
  • Added generic --config.<key>=<value> overrides plus fetch timeout, retry, backoff, --pnpmfile, and --global-pnpmfile flags.
  • Improved install, resolver, registry, linker, manifest, settings, and state hot paths with shared caches, cheaper hashes, fewer repeated filesystem probes, and compressed packument fetches.
  • Expanded pnpm parity coverage across update, hooks, allow-build review, monorepo filter, prefer-offline, and misc install behavior.

Added

  • aube update now parses <pkg>@<spec> arguments and can update indirect dependencies (#446).
  • aube add can bootstrap a missing package.json, matching pnpm behavior covered by newly ported misc tests (#417).
  • --config.<key>=<value> flags provide generic CLI config overrides (#447).
  • --lockfile-dir / lockfileDir support allows commands to target a foreign lockfile directory when valid (#431).
  • Fetch controls were added for timeout, retry count, and retry backoff behavior (#436).
  • --pnpmfile and --global-pnpmfile flags were added, with pnpmfile hooks wired into update and preResolution support (#439, #423).
  • pnpmfile ctx.log records now emit as pnpm:hook NDJSON on stdout (#440).
  • --save-catalog, workspace:* parsing, and sharedWorkspaceLockfile=false support landed together (#418).
  • Empty --allow-build values now use pnpm's verbatim error wording (#444).

Fixed

  • AUBE_VIRTUAL_STORE_DIR is honored from the environment, with additional pnpm misc parity coverage (#456).
  • aube update --latest preserves prerelease pins that are already higher than the latest stable version (#445).
  • . is rejected as a foreign --lockfile-dir importer and the related docs were corrected (#442).
  • npm package-lock.json workspace importers are preserved when parsing and writing lockfiles (#443).
  • Lifecycle script behavior closed three pnpm parity gaps (#421).
  • The resolver now ships an empty bundled metadata primer when the generator script cannot run, instead of failing the build (#425).

Performance

  • Cached hot-path work across install, resolver, registry, linker, manifest parsing, settings lookup, and install state freshness checks (#453).
  • Deduplicated and cached repeated install/resolver work, including graph hashing, patch fingerprints, lockfile parsing, env capture, script policy lookup, workspace-root scans, and registry auth token matching (#449).
  • Refreshed benchmark results for the 1.5.2 baseline (#448, #452).

Testing and Parity

  • Ported pnpm monorepo filter tests and wired --fail-if-no-match (#457).
  • Ported additional pnpm hook, allowBuilds review, update, prefer-offline, circular peer, trust-policy, peer warning, top-level plugin, and registry fixture coverage (#455, #441, #438, #454, #434, #433, #424).

v1.5.1: POSIX colon tarball filenames

29 Apr 23:47
Immutable release. Only release title and notes can be modified.
08f0594

Choose a tag to compare

A small patch release fixing tarball installs that contain : in entry filenames on POSIX platforms (e.g. redos-detector@6.1.4's dist/__mocks__/package-json:version.d.ts).

Fixed

  • POSIX colon tarball filenames — the store tarball validator and the linker's validate_index_key previously rejected : on every platform to defend against Windows drive-prefix and NTFS alternate-data-stream ambiguity. That guard was too broad for POSIX, where colon is a valid filename character, and caused installs of packages like redos-detector@6.1.4 to fail. Both guards are now platform-gated: : is still rejected on Windows, but accepted on Linux and macOS. (#386 by @jdx)

Full Changelog: v1.5.0...v1.5.1

💚 Sponsor aube

aube is part of en.dev — an independent developer-tooling studio run by @jdx, also behind mise. Work on aube is funded entirely by sponsors.

If aube is saving your team install time or CI minutes, please consider sponsoring at en.dev. Individual and company sponsorships are what keep the project fast, free, and independent.

v1.5.0: Dependency graph queries and patch/lockfile fixes

29 Apr 20:14
Immutable release. Only release title and notes can be modified.
c9a98ab

Choose a tag to compare

This release adds aube query for selector-based dependency graph inspection, fixes patch application against CRLF tarball files, repairs npm-aliased catalog dependencies in pnpm-generated lockfiles, and unifies how aube decides where to write workspace settings.

Added

  • aube query — a vlt-inspired dependency-graph query command. Supply a selector expression (attribute predicates plus pseudo-selectors like :scripts, :bin, :peer, :type(...), :license(...)), optionally scope with workspace --filter/--prod/--dev roots, and emit human-readable, --parseable, or --json output. Reads only the local lockfile. (#380 by @jdx)

Fixed

  • Patches against CRLF text files — tarballs published from Windows editors (e.g. gifuct-js@2.1.2/index.d.ts) ship CRLF, but git/pnpm-style patches always emit LF, and diffy refused to match LF hunks against CRLF context. aube now normalizes the original to LF before applying and restores CRLF on write — matching pnpm's approach — with a \r\r\n collapse so a literal \r byte mid-line doesn't gain a second carriage return. (#384 by @jdx)

  • aube patch-commit destination — previously wrote unconditionally to pnpm.patchedDependencies in package.json even on projects already using the pnpm v10+ workspace-yaml home. A single rule now applies to every command that mutates a setting which can live in either the workspace yaml or package.json#{pnpm,aube}.<key>:

    1. If a workspace yaml exists on disk → write there.
    2. Otherwise, if package.json#pnpm is already declared → write pnpm.<key> (preserve the user's namespace).
    3. Otherwise → write aube.<key>.

    aube patch-remove now strips entries from every place they could live and reports the files actually rewritten. The same rule covers aube approve-builds and install-time auto-deny seeding. (#384 by @jdx)

  • npm-aliased catalog deps from pnpm lockfilesaube install --frozen-lockfile previously accepted a pnpm lockfile with beamcoder: npm:beamcoder-prebuild@… declared via pnpm-workspace.yaml#catalog and silently produced an empty node_modules, because the importer's specifier was 'catalog:' and alias detection only fired on specifier.starts_with("npm:"). Aliases are now detected purely from the canonical <real>@<resolved> version: shape, with a peer-suffix strip so version: 18.2.0(react@18.2.0) isn't misclassified. (#384 by @jdx)

  • Bounded resolver stream — the resolved-package stream is now a bounded Tokio channel sized from the same network concurrency used by fetch workers, with awaited sends so resolver/fetch overlap applies backpressure instead of accumulating an unbounded queue. (#377 by @jdx)

Changed

  • aube-workspace.yaml is the default-write filename — when neither aube-workspace.yaml nor pnpm-workspace.yaml exists, aube approve-builds (and the install-time auto-seed of unreviewed build scripts) now creates aube-workspace.yaml so it pairs with aube-lock.yaml instead of leaving mixed vendor namespaces side by side. Existing pnpm-workspace.yaml files keep being mutated in place. (#382 by @jdx)
  • Comment-preserving workspace-yaml writes — yaml writes now skip the rewrite when the closure produces no structural change, so user comments survive every no-op update to allowBuilds, patchedDependencies, and catalog cleanup. (#384 by @jdx)
  • Install phase timing sink — set AUBE_BENCH_PHASES_FILE to append per-phase install timings (resolve/fetch/link/scripts/state/sweep) as JSONL, optionally tagged with AUBE_BENCH_SCENARIO. The benchmark harness samples aube install-shaped scenarios and benchmarks/generate-phase-results.mjs turns the JSONL into a Markdown table plus a structured JSON artifact. (#381 by @jdx)

Full Changelog: v1.4.0...v1.5.0

💚 Sponsor aube

aube is part of en.dev — an independent developer-tooling studio run by @jdx, also behind mise. Work on aube is funded entirely by sponsors.

If aube is saving your team install time or CI minutes, please consider sponsoring at en.dev. Individual and company sponsorships are what keep the project fast, free, and independent.

v1.4.0: Linux build jails, pnpm 11 audit/allowBuilds parity, and a security roundup

28 Apr 23:35
Immutable release. Only release title and notes can be modified.
fa69f13

Choose a tag to compare

This release brings aube closer to pnpm 11 parity — audit --fix=update, the allowBuilds review map, and ESM pnpmfiles all land — extends jailed dependency builds to Linux with native Landlock + seccomp enforcement, and ships a roundup of critical/high security and correctness fixes.

Highlights

  • pnpm 11 parity across audit fixing, build-script approval, and pnpmfile loading.
  • Jailed builds on Linux, with kernel-enforced filesystem and network isolation that fails closed.
  • Security & correctness roundup tightening the seccomp/Landlock policy, workspace pattern containment, resolver convergence hashing, patch atomicity, and install-state hashing.

Added

  • aube audit --fix=update — fix advisories by updating through the lockfile instead of writing overrides, matching pnpm 11. --fix is now an optional method form: bare --fix defaults to override, and --fix=override / --fix=update are both accepted. aube audit -i defaults to override fix mode to match pnpm's interactive flow. The resolver also learned advisory-range avoidance, so update mode steers sibling reuse, lockfile reuse, and version picking away from vulnerable versions when a safe alternative exists. (#363 by @jdx)
  • pnpm 11 allowBuilds review map — build-script approvals now persist as allowBuilds: { pkg: true | false } in pnpm-workspace.yaml. aube install auto-seeds unreviewed dependency builds as false, and aube approve-builds flips selected entries to true. Legacy onlyBuiltDependencies / neverBuiltDependencies remain read-compatible. (#364 by @jdx)
  • ESM pnpmfiles.pnpmfile.mjs is now preferred over .pnpmfile.cjs during default discovery and loaded via dynamic import(), while CommonJS pnpmfiles continue to load via require(). Both afterAllResolved and readPackage hooks are supported on .mjs. (#362 by @jdx)
  • Jailed builds on Linux--jail-builds / jailBuilds / AUBE_JAIL_BUILDS now enforce isolation natively on Linux using Landlock for filesystem writes and a seccomp filter for network sockets. The jail is set up in the child process via pre_exec so the parent aube stays unrestricted, and scripts fail closed if the kernel can't fully enforce the policy. TMPDIR/TMP/TEMP are redirected into the per-package temporary jail home, and network: true remains the per-package escape hatch. (#350 by @jdx)

Fixed

  • npm install reliably exposes commands — the published npm package now keeps stable extensionless bin/aube, bin/aubr, bin/aubx entries. On Unix the native binaries are still copied/hardlinked directly to those paths; on Windows, sibling .exe files are written and the extensionless paths become tiny shebang shims pointing at them, giving npm's generated .cmd shims a stable target. The native CLI also normalizes npm's interpreter-shim argv shape so multicall dispatch keeps working. (#369 by @jdx)
  • Critical/high audit roundup (#361 by @imjustprism):
    • Scripts: seccomp denylist now covers AF_NETLINK, AF_PACKET, AF_VSOCK, AF_XDP, AF_ALG, AF_BLUETOOTH, AF_RDS, AF_CAN, AF_TIPC, AF_IB, and AF_NFC in addition to AF_INET/AF_INET6 (AF_UNIX stays allowed for node-gyp IPC). /tmp was dropped from the Landlock allow-list to prevent symlink races and tmp-file reads on shared CI hosts.
    • Workspace: pnpm-workspace.yaml patterns that escape the project root (e.g. - "../sibling") are now rejected via a canonicalized containment check, instead of leaking foreign directories into the workspace package list.
    • Resolver: the peer-context convergence hash now walks (key, [(dep_name, dep_tail), ...]) for every package, so peer rewrites that change a dep tail without adding a new key can no longer ship stale linker targets.
    • CLI: aube patch-commit is now atomic — the .patch file is written via atomic_write, prior bytes are snapshotted, and a manifest write failure rolls the patch back instead of leaving an orphan invisible to load_patches.
    • Install: the install state digest now hashes user-level ~/.npmrc in addition to the project .npmrc, so a token swap or registry= change in the home file invalidates the "Already up to date" fast path.
  • Resolver excludes provenance churn packages by default — built-in trustPolicyExclude entries cover npm packages with known provenance metadata churn that previously broke benchmark fixture resolution; user-supplied entries are merged on top. (#360 by @jdx)
  • Workspace bins linked into dependents — when workspace package A declares bin and B depends on A via workspace:*, A's bins are now symlinked into B/node_modules/.bin/ so B's npm scripts can call them. Previously the linker read package.json from a non-existent .aube/<dep_path>/... location and silently produced no shim. A new link_bins_for_workspace_dep helper reads from the workspace package's own directory (cached across importers). (#353 by @jdx)
  • README on the published aube crate[workspace.package] now sets readme = "README.md" and the binary crate inherits it, so crates.io renders the project README starting with this release. (#349 by @jdx)

Changed

  • Install docs sharpened — the installation page and README now warn that the npm package depends on its preinstall lifecycle script (so --ignore-scripts or PowerShell blocking npm.ps1 can leave commands unwired), use --ignore-scripts=false in examples, and recommend mise as the primary install path with a tip on mise settings add idiomatic_version_file_enable_tools node for .nvmrc/.node-version support. (#368 by @jdx)

New Contributors

Full Changelog: v1.3.0...v1.4.0

💚 Sponsor aube

aube is part of en.dev — an independent developer-tooling studio run by @jdx, also behind mise. Work on aube is funded entirely by sponsors.

If aube is saving your team install time or CI minutes, please consider sponsoring at en.dev. Individual and company sponsorships are what keep the project fast, free, and independent.

💚 Sponsor aube

aube is part of en.dev — an independent developer-tooling studio run by @jdx, also behind mise. Work on aube is funded entirely by sponsors.

If aube is saving your team install time or CI minutes, please consider sponsoring at en.dev. Individual and company sponsorships are what keep the project fast, free, and independent.