Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: endevco/aube
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v1.4.0
Choose a base ref
...
head repository: endevco/aube
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v1.5.0
Choose a head ref
  • 10 commits
  • 55 files changed
  • 4 contributors

Commits on Apr 29, 2026

  1. fix(lockfile): hoist npm workspace links to root importer deps (#374)

    ## Summary
    
    - npm symlinks every workspace member into the root `node_modules/`
    regardless of whether the root `package.json` declares it as a dep —
    recorded in `package-lock.json` as `node_modules/<name>: { link: true,
    resolved: "<rel>" }`. Aube was seeding the root importer only from
    `dependencies`/`devDependencies`/`optionalDependencies`, so undeclared
    workspace projects never got a top-level `node_modules/<ws-pkg>` symlink
    and Angular CLI / Nx / similar tooling that resolves workspace libraries
    from the repo root broke when migrating npm-managed monorepos to aube.
    - Surface every top-level link entry (plain or scoped, no nested
    `/node_modules/` segment) as a direct dep of the root importer in the
    npm-lockfile parser. Existing `already_added` dedupe preserves explicit
    `dependencies: { "@scope/x": "file:packages/x" }` declarations; entries
    are appended sorted by name for deterministic output.
    
    Reported in
    #345 (comment)
    (siemens/element).
    
    ## Test plan
    
    - [x] `cargo test -p aube-lockfile` (new test
    `test_parse_workspace_links_undeclared_in_root_deps` + existing
    `test_parse_workspace_links` to confirm no double-add when the workspace
    IS in root deps)
    - [x] `cargo test` workspace-wide
    - [x] Manual smoke: minimal repro repo with `workspaces:
    ["projects/foo", "projects/bar"]`, neither declared in root
    `dependencies`, package-lock.json with `node_modules/@scope/foo` +
    `node_modules/@scope/bar` link entries → `aube install` produces
    `node_modules/@scope/foo` and `node_modules/@scope/bar` symlinks
    pointing at `../../projects/<name>`
    
    🤖 Generated with [Claude Code](https://claude.com/claude-code)
    
    <!-- CURSOR_SUMMARY -->
    ---
    
    > [!NOTE]
    > **Medium Risk**
    > Medium risk because it changes how npm lockfiles are interpreted to
    seed root direct dependencies, which can affect install layout and
    hoisting behavior for workspace/linked packages.
    > 
    > **Overview**
    > Ensures npm-managed workspaces that are **not declared in the root
    `package.json` deps** still get their top-level
    `node_modules/<workspace>` symlinks recreated by `aube install`.
    > 
    > The npm lockfile parser now scans `package-lock.json` `packages` for
    top-level `node_modules/*` entries with `link: true`, de-dupes against
    already-declared direct deps, sorts them deterministically, and appends
    them to the root importer’s direct deps. Adds a regression test covering
    undeclared workspace members being surfaced as root direct deps and
    round-tripping as `LocalSource::Link`.
    > 
    > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
    c98805f. Bugbot is set up for automated
    code reviews on this repo. Configure
    [here](https://www.cursor.com/dashboard/bugbot).</sup>
    <!-- /CURSOR_SUMMARY -->
    
    Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    jdx and claude authored Apr 29, 2026
    Configuration menu
    Copy the full SHA
    7dc3692 View commit details
    Browse the repository at this point in the history
  2. fix(resolver): bound resolved package stream (#377)

    ## Summary
    - replace the resolver resolved-package stream with a bounded Tokio
    channel
    - size the install streaming buffer from the same network concurrency
    used by fetch workers
    - await stream sends so resolver/fetch overlap applies backpressure
    instead of growing an unbounded queue
    - move an existing install test module below helper items so current
    all-targets clippy stays green
    
    ## Validation
    - cargo check -p aube-resolver -p aube
    - cargo fmt --check
    - cargo clippy --all-targets -- -D warnings
    - cargo test -p aube-resolver
    
    *This PR was generated by Codex.*
    
    <!-- CURSOR_SUMMARY -->
    ---
    
    > [!NOTE]
    > **Medium Risk**
    > Changes async streaming semantics (`send().await`) between resolver
    and installer, which can affect throughput and introduce stalls if the
    receiver isn’t drained as expected. Scope is contained to the streaming
    resolution/fetch overlap path.
    > 
    > **Overview**
    > The resolver’s resolved-package stream is now **bounded**:
    `Resolver::with_stream` uses a fixed default capacity and a new
    `with_stream_capacity` constructor, and `resolved_tx` switches from
    `mpsc::UnboundedSender` to `mpsc::Sender`.
    > 
    > All resolver streaming `send` call sites now `await` to apply
    **backpressure** instead of accumulating an unbounded queue, and
    `install` sizes the stream buffer from the same network concurrency used
    by tarball fetch workers. A small test-module move keeps `--all-targets`
    clippy passing.
    > 
    > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
    7b20f7b. Bugbot is set up for automated
    code reviews on this repo. Configure
    [here](https://www.cursor.com/dashboard/bugbot).</sup>
    <!-- /CURSOR_SUMMARY -->
    jdx authored Apr 29, 2026
    Configuration menu
    Copy the full SHA
    a179f9b View commit details
    Browse the repository at this point in the history
  3. fix(lockfile): preserve pnpm registry tarball urls (#378)

    ## Summary
    
    - preserve pnpm registry packages as registry packages when
    `lockfileIncludeTarballUrl` records a tarball URL
    - add an adversarial pnpm roundtrip test covering aliases, catalogs,
    overrides, patches, skipped optionals, peer metadata, platform
    optionals, and section ordering together
    
    ## Root Cause
    
    The pnpm parser classified any `resolution.tarball` HTTP URL as a
    remote-tarball dependency. That is only correct for URL-keyed package
    entries; ordinary `name@version` registry entries can also carry tarball
    URLs when `lockfileIncludeTarballUrl=true`.
    
    ## Validation
    
    - `cargo fmt --check`
    - `cargo test -p aube-lockfile`
    
    <!-- CURSOR_SUMMARY -->
    ---
    
    > [!NOTE]
    > **Medium Risk**
    > Touches pnpm lockfile parsing/classification used by the installer;
    misclassification fixes are targeted but can change how dependencies are
    fetched/resolved for some lockfiles.
    > 
    > **Overview**
    > Preserves pnpm registry dependencies as *registry-sourced* even when
    `lockfileIncludeTarballUrl` adds an HTTP `resolution.tarball`, by only
    treating `RemoteTarball` as `local_source` for URL-keyed entries.
    > 
    > Adds an adversarial pnpm v9 parse→write→reparse test that exercises
    multiple native lockfile features together (overrides, catalogs, patched
    deps, aliasing, skipped/ignored optionals, peer metadata, platform
    constraints) and asserts top-level section ordering and tarball URL
    retention.
    > 
    > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
    e94a504. Bugbot is set up for automated
    code reviews on this repo. Configure
    [here](https://www.cursor.com/dashboard/bugbot).</sup>
    <!-- /CURSOR_SUMMARY -->
    jdx authored Apr 29, 2026
    Configuration menu
    Copy the full SHA
    97cf455 View commit details
    Browse the repository at this point in the history
  4. test(lockfile): add property roundtrip coverage (#376)

    ## Summary
    
    Adds property-based lockfile roundtrip coverage for generated
    registry-only graphs across pnpm, npm, Bun, Yarn classic, and Yarn Berry
    lockfile writers/parsers. The tests normalize dependency edges before
    comparing so they focus on structural graph preservation across each
    format.
    
    ## Validation
    
    - cargo fmt --check
    - cargo test -p aube-lockfile --test proptest
    - cargo test -p aube-lockfile
    - cargo clippy -p aube-lockfile --all-targets -- -D warnings
    
    *This PR was generated by Codex.*
    
    <!-- CURSOR_SUMMARY -->
    ---
    
    > [!NOTE]
    > **Low Risk**
    > Test-only changes plus a new dev-dependency; no production code paths
    are modified.
    > 
    > **Overview**
    > Adds property-based roundtrip tests in `aube-lockfile` that generate
    small registry-only dependency graphs, write them as each supported
    lockfile format (pnpm/npm/bun/yarn classic/yarn berry), re-parse them,
    and compare a normalized representation to ensure structural
    preservation.
    > 
    > Introduces `proptest` as a dev-dependency (and updates `Cargo.lock`)
    to support this new randomized/parametric test coverage.
    > 
    > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
    499374f. Bugbot is set up for automated
    code reviews on this repo. Configure
    [here](https://www.cursor.com/dashboard/bugbot).</sup>
    <!-- /CURSOR_SUMMARY -->
    jdx authored Apr 29, 2026
    Configuration menu
    Copy the full SHA
    f9c6c74 View commit details
    Browse the repository at this point in the history
  5. fix(resolver): require structured trust evidence (#379)

    ## Summary
    
    - require npm trusted-publisher evidence to include a structured
    non-empty `id`
    - require provenance evidence to include an SLSA `predicateType`
    - update trust policy docs and regenerated settings docs
    
    ## Why
    
    The trust downgrade policy previously treated arbitrary truthy registry
    values as trust evidence. That matched pnpm-style boolean checks, but it
    meant malformed or hostile packument metadata such as `{}` or `"oidc"`
    could satisfy aube's trust policy. This keeps the existing
    metadata-based policy but narrows the accepted shapes to the structured
    metadata npm emits after registry-side checks.
    
    ## Validation
    
    - `cargo run -p aube-settings --bin generate-settings-docs`
    - `cargo fmt --check`
    - `cargo test -p aube-resolver trust::tests`
    - `cargo test -p aube-registry provenance`
    - `cargo clippy -p aube-resolver -p aube-registry --all-targets -- -D
    warnings`
    
    *This pull request was generated by Codex.*
    
    <!-- CURSOR_SUMMARY -->
    ---
    
    > [!NOTE]
    > **Medium Risk**
    > Changes security enforcement logic for installs, which could newly
    reject packages with malformed/nonstandard registry metadata or alter
    downgrade decisions; behavior is well-covered by updated tests and docs.
    > 
    > **Overview**
    > Tightens trust-policy evidence detection so
    `_npmUser.trustedPublisher` only counts when it is an object with a
    non-empty `id`, and `dist.attestations.provenance` only counts when it
    is an object whose `predicateType` matches an SLSA provenance URI (e.g.
    `https://slsa.dev/provenance/v1`).
    > 
    > Updates resolver/unit tests and documentation/settings text to reflect
    the new structured-shape requirements and clarify that this is *metadata
    validation* (not cryptographic attestation verification).
    > 
    > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
    e4a5bb0. Bugbot is set up for automated
    code reviews on this repo. Configure
    [here](https://www.cursor.com/dashboard/bugbot).</sup>
    <!-- /CURSOR_SUMMARY -->
    jdx authored Apr 29, 2026
    Configuration menu
    Copy the full SHA
    abbe949 View commit details
    Browse the repository at this point in the history
  6. feat(cli): add dependency graph query command (#380)

    ## Summary
    
    - add `aube query` for local selector-based dependency graph inspection
    inspired by vlt's dependency selector model
    - support package/name/version/source/license selectors plus
    direct/transitive flags and JSON/parseable output
    - regenerate usage docs and add BATS coverage for the CLI path
    
    ## Validation
    
    - `cargo fmt --check`
    - `cargo test -p aube query::tests`
    - `cargo test -p aube cli_ordering_tests::test_cli_ordering`
    - `cargo clippy -p aube --bin aube --bin aubr --bin aubx -- -D warnings`
    - `mise run test:bats test/query.bats`
    - `mise run render`
    
    Note: `cargo clippy --all-targets -- -D warnings` still reports the
    existing `items_after_test_module` warning in
    `crates/aube/src/commands/install/mod.rs`.
    
    *This PR was generated by Codex.*
    
    <!-- CURSOR_SUMMARY -->
    ---
    
    > [!NOTE]
    > **Low Risk**
    > Additive CLI feature that only reads existing lockfile data and adds
    new parsing/output paths; minimal impact on existing commands aside from
    command dispatch and docs regeneration.
    > 
    > **Overview**
    > Adds a new `aube query` command that reads the local lockfile, walks
    the reachable dependency graph (optionally scoped by workspace
    `--filter` and `--prod`/`--dev` roots), and filters packages via a
    selector expression supporting attribute predicates and pseudo-selectors
    like `:scripts`, `:bin`, `:peer`, `:type(...)`, and `:license(...)`.
    > 
    > The command can emit human-readable output, tab-separated
    `--parseable` rows, or `--json` output; CLI wiring, usage spec/docs
    generation (`aube.usage.kdl`, `docs/cli/*`), and new BATS coverage are
    included.
    > 
    > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
    780bcad. Bugbot is set up for automated
    code reviews on this repo. Configure
    [here](https://www.cursor.com/dashboard/bugbot).</sup>
    <!-- /CURSOR_SUMMARY -->
    jdx authored Apr 29, 2026
    Configuration menu
    Copy the full SHA
    038e339 View commit details
    Browse the repository at this point in the history
  7. fix(workspace): default-write aube-workspace.yaml instead of pnpm-wor…

    …kspace.yaml (#382)
    
    ## Summary
    
    When `aube approve-builds` (or the install-time auto-seed of unreviewed
    build scripts) needs to create a workspace yaml from scratch, aube was
    writing `pnpm-workspace.yaml`. The lockfile companion is
    `aube-lock.yaml` — having the workspace yaml stay pnpm-prefixed is an
    asymmetry: a fresh `aube install` on a solo project produces a
    filesystem layout with both names sitting next to each other, mixing
    vendor namespaces.
    
    Switches the **default write** filename to `aube-workspace.yaml` so the
    two aube-generated files share a naming scheme.
    
    ## Backward compat
    
    Unchanged. The read path already prefers `aube-workspace.yaml` and falls
    back to `pnpm-workspace.yaml` (constant `WORKSPACE_YAML_NAMES =
    ["aube-workspace.yaml", "pnpm-workspace.yaml"]` in
    `crates/aube-manifest/src/workspace.rs:6`). The write path's
    existing-file precedence is unchanged too: a project that already ships
    `pnpm-workspace.yaml` keeps mutating that file in place. The only
    behavior change is the **fallback** when neither file exists — that
    branch now creates the aube-prefixed name.
    
    | State | Before this PR | After this PR |
    |---|---|---|
    | `aube-workspace.yaml` present | mutate it | mutate it (unchanged) |
    | `pnpm-workspace.yaml` present | mutate it | mutate it (unchanged) |
    | Both present | mutate `aube-workspace.yaml` | mutate
    `aube-workspace.yaml` (unchanged) |
    | Neither present | **create `pnpm-workspace.yaml`** | **create
    `aube-workspace.yaml`** ← change |
    
    ## Test coverage
    
    - Renames the existing
    `add_to_allow_builds_creates_pnpm_workspace_when_no_yaml` test to its
    new behavior
    (`add_to_allow_builds_creates_aube_workspace_when_no_yaml`).
    - Adds a companion
    `add_to_allow_builds_writes_to_existing_pnpm_workspace` that pins the
    backward-compat branch — a project with an existing
    `pnpm-workspace.yaml` keeps using it; no `aube-workspace.yaml` is
    created alongside.
    
    ## Test plan
    
    - [x] `cargo test -p aube-manifest workspace` — 24 pass (including the 2
    covered above)
    - [x] `cargo test --workspace --all-targets` — all green (~1500 tests)
    - [x] `cargo clippy --workspace --all-targets -- -D warnings` — clean
    - [x] `cargo fmt --check` — clean
    
    🤖 Generated with [Claude Code](https://claude.com/claude-code)
    
    <!-- CURSOR_SUMMARY -->
    ---
    
    > [!NOTE]
    > **Low Risk**
    > Behavior change is limited to the fallback filename used when creating
    a new workspace YAML; existing files and build-policy logic remain
    unchanged.
    > 
    > **Overview**
    > Changes the default workspace YAML write target for `allowBuilds`
    updates: when neither `aube-workspace.yaml` nor `pnpm-workspace.yaml`
    exists, aube now creates `aube-workspace.yaml` instead of
    `pnpm-workspace.yaml` (while still mutating an existing
    `pnpm-workspace.yaml` in place for backward compatibility).
    > 
    > Updates `approve-builds`/lifecycle-script documentation, CLI help
    text, and bats/unit tests to reflect the new filename and to add
    coverage that existing `pnpm-workspace.yaml` files are not “forked” into
    a new `aube-workspace.yaml`.
    > 
    > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
    f353258. Bugbot is set up for automated
    code reviews on this repo. Configure
    [here](https://www.cursor.com/dashboard/bugbot).</sup>
    <!-- /CURSOR_SUMMARY -->
    
    ---------
    
    Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    jdx and claude authored Apr 29, 2026
    Configuration menu
    Copy the full SHA
    d6f9a4d View commit details
    Browse the repository at this point in the history
  8. perf(bench): add install phase timings (#381)

    ## Summary
    
    - add an opt-in `AUBE_BENCH_PHASES_FILE` JSONL sink for install phase
    timings
    - sample aube install-shaped benchmark scenarios after the hyperfine
    matrix
    - generate markdown and JSON phase timing summaries from the sampled
    JSONL
    
    ## Validation
    
    - `cargo fmt --check`
    - `bash -n benchmarks/bench.sh`
    - `node --check benchmarks/generate-phase-results.mjs`
    - `cargo check -p aube`
    - smoke-tested `benchmarks/generate-phase-results.mjs` with sample JSONL
    
    <!-- CURSOR_SUMMARY -->
    ---
    
    > [!NOTE]
    > **Low Risk**
    > Changes touch core install code, but the new timing collection and
    file I/O are gated behind `AUBE_BENCH_PHASES_FILE`, so normal installs
    should be unaffected aside from minimal added timing calls.
    > 
    > **Overview**
    > Adds an opt-in install phase timing sink to `aube install`: when
    `AUBE_BENCH_PHASES_FILE` is set, the installer records per-phase
    durations (e.g. resolve/fetch/link/scripts/state/sweep) and appends a
    JSONL summary including counts and an optional `AUBE_BENCH_SCENARIO`
    label.
    > 
    > Extends `benchmarks/bench.sh` to run one extra aube-only sample per
    install-shaped scenario that writes phase timings, and adds
    `benchmarks/generate-phase-results.mjs` to convert the collected JSONL
    into a Markdown table plus a structured JSON artifact.
    > 
    > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
    0714efd. Bugbot is set up for automated
    code reviews on this repo. Configure
    [here](https://www.cursor.com/dashboard/bugbot).</sup>
    <!-- /CURSOR_SUMMARY -->
    jdx authored Apr 29, 2026
    Configuration menu
    Copy the full SHA
    b5674b3 View commit details
    Browse the repository at this point in the history
  9. fix(cli,linker,lockfile): patch-commit destination, CRLF patches, npm…

    …-alias catalog (#384)
    
    ## Summary
    
    Three bug fixes for
    [#383](#383) plus
    the supporting refactors that fell out of code review.
    
    ### Bug fixes
    
    - **Patches against CRLF text files** — tarballs published from Windows
    editors ship CRLF (e.g. `gifuct-js@2.1.2/index.d.ts`), but
    git/pnpm-style patches always emit LF. Diffy is byte-exact and refused
    to match CRLF context against LF hunks, so a clean patch failed with
    `error applying hunk #1`. Normalize the original to LF before apply and
    restore CRLF on write — same approach pnpm uses. The CRLF restore also
    collapses any `\r\r\n` so a patch line containing a literal `\r` byte
    mid-line doesn't gain a second carriage return.
    
    - **`aube patch-commit` destination** — previously wrote unconditionally
    to `pnpm.patchedDependencies` in `package.json`, even on projects
    already using the pnpm v10+ workspace-yaml home. Now follows the unified
    rule below. `aube patch-remove` now strips entries from every place they
    could live (both yaml and both `pnpm.*` / `aube.*` namespaces) and
    reports the actual files rewritten in its status output.
    
    - **npm-aliased catalog deps from pnpm-generated lockfiles**
    ([discussioncomment](#383 (comment)))
    — `aube install --frozen-lockfile` accepted a pnpm lockfile with
    `beamcoder: npm:beamcoder-prebuild@…` (declared via
    `pnpm-workspace.yaml#catalog`) and silently produced an empty
    `node_modules`. The importer's `specifier:` was `'catalog:'`, but the
    alias detection only fired on `specifier.starts_with("npm:")`. Now
    detects aliases purely from the `version:` shape (the canonical
    `<real>@<resolved>` form pnpm always uses), with a peer-suffix strip so
    `version: 18.2.0(react@18.2.0)` doesn't get misclassified.
    
    ### Refactor: unified workspace-config writer
    
    One rule applies to every command that mutates a setting which can live
    in either the workspace yaml or `package.json#{pnpm,aube}.<key>` (`aube
    patch-commit`, `aube patch-remove`, `aube approve-builds`, install-time
    auto-deny seeding, future settings):
    
    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 chosen namespace).
    3. Otherwise → write `aube.<key>` (aube's native namespace; the read
    side already gives `aube.*` precedence over `pnpm.*`).
    
    New helpers in `aube_manifest::workspace`:
    - `ConfigWriteTarget` + `config_write_target(dir)` — picks step 1 vs
    steps 2/3.
    - `edit_workspace_yaml(path, f)` — yaml writer; **skips the rewrite when
    the closure produces no structural change**, so user comments survive
    every no-op write. Used by allowBuilds, patchedDependencies, and catalog
    cleanup.
    - `edit_setting_map(cwd, key, f)` — `package.json` writer; picks
    namespace per steps 2/3, also skips no-op rewrites.
    - `remove_setting_entry(cwd, key, entry_key)` — strips an entry from
    both `pnpm.<key>` and `aube.<key>` so a one-namespace removal doesn't
    leave a stale duplicate behind on the read merge.
    
    Migrated callers: `aube approve-builds` (and the install-time auto-deny
    seed), `aube patch-commit`, `aube patch-remove`, catalog cleanup. The
    `PatchDestination` enum and `edit_patched_dependencies` helper that
    lived in `aube/src/patches.rs` are gone.
    
    ### Refactor: workspace-yaml file selection
    
    Centralized the `aube-workspace.yaml` → `pnpm-workspace.yaml` precedence
    walk into `aube_manifest::workspace::workspace_yaml_existing`.
    `workspace_yaml_target` is now a one-liner over it. Removed three
    duplicates of the same loop (`catalogs.rs`, `find_workspace_root`,
    `find_workspace_yaml_root`).
    
    ## Test plan
    
    - [x] `cargo test` (1185 passing — new coverage spans CRLF apply +
    embedded-`\r` restore in `aube-linker`; helper-level + per-writer
    no-op-skip tests for allowBuilds, patchedDependencies, and catalog
    cleanup; `ConfigWriteTarget` + namespace-picking cases; pnpm-lockfile
    catalog alias)
    - [x] `cargo clippy --all-targets -- -D warnings`
    - [x] `cargo fmt --check`
    - [x] End-to-end repros from the discussion: `aube install` against
    `patch-application-failure` succeeds with CRLF preserved; `aube install
    --frozen-lockfile` against `catalog-npm-alias` installs `beamcoder`
    (resolved to `beamcoder-prebuild`) into `packages/app/node_modules/`
    
    🤖 Generated with [Claude Code](https://claude.com/claude-code)
    
    <!-- CURSOR_SUMMARY -->
    ---
    
    > [!NOTE]
    > **Medium Risk**
    > Touches install/patch/config persistence paths and changes where
    settings are written (`workspace` YAML vs `package.json`), which can
    affect real projects’ config layout; mitigated by extensive new tests
    and largely additive helpers.
    > 
    > **Overview**
    > Fixes patch application on CRLF-backed files by normalizing input to
    LF for diff matching and restoring CRLF on write (with protection for
    embedded literal `\r`), plus adds regression tests.
    > 
    > Unifies how workspace-level settings are written: if a workspace yaml
    exists, write there; otherwise write to `package.json` under `aube.*`
    unless `pnpm` already exists. This refactor is applied to `allowBuilds`
    seeding/approval, `patch-commit`/`patch-remove` (including removing
    entries from all possible locations and reporting the actual files
    changed), and catalog cleanup (now skips no-op YAML rewrites to avoid
    stripping comments).
    > 
    > Fixes pnpm lockfile parsing to detect npm-aliased dependencies based
    on the `version:` field shape (including catalog-declared aliases and
    peer suffix handling), with new tests.
    > 
    > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
    74cbd4d. Bugbot is set up for automated
    code reviews on this repo. Configure
    [here](https://www.cursor.com/dashboard/bugbot).</sup>
    <!-- /CURSOR_SUMMARY -->
    
    ---------
    
    Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    jdx and claude authored Apr 29, 2026
    Configuration menu
    Copy the full SHA
    2f44140 View commit details
    Browse the repository at this point in the history
  10. chore: release v1.5.0 (#375)

    ## 🤖 New release: `v1.5.0`
    
    This PR bumps the workspace to `v1.5.0` and regenerates CHANGELOG
    entries, `aube.usage.kdl`, the CLI docs, and the benchmark results.
    
    See the diff for the full set of changes, or the per-crate
    `CHANGELOG.md` files for the release notes that will ship.
    
    ---
    Generated by the `release-plz-pr` workflow.
    
    Co-authored-by: release-plz[bot] <release-plz+bot@users.noreply.github.com>
    mise-en-dev and release-plz[bot] authored Apr 29, 2026
    Configuration menu
    Copy the full SHA
    c9a98ab View commit details
    Browse the repository at this point in the history
Loading