Skip to content

fix(licenses): resolve packages from hoisted layout - #1183

Merged
jdx merged 3 commits into
mainfrom
agent/fix-hoisted-licenses
Jul 29, 2026
Merged

jdx merged 3 commits into
mainfrom
agent/fix-hoisted-licenses

Conversation

@jdx

@jdx jdx commented Jul 29, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • detect the linker layout recorded by the completed install
  • resolve package manifests through reconstructed hoisted placements
  • preserve the full graph while planning placements, then apply --prod / --dev filtering
  • add regression coverage for root and nested hoisted dependencies

Root cause

aube licenses always derived package paths from the isolated virtual store. A hoisted install does not create node_modules/.aube, so every manifest read failed and each dependency fell back to UNKNOWN.

This also respects installs made with the one-shot --node-linker=hoisted flag by preferring the stored install layout over current configuration.

Fixes the behavior reported in #1182.

Validation

  • cargo test -p aube commands::licenses
  • mise run test:bats test/licenses.bats
  • cargo clippy -p aube --all-targets -- -D warnings
  • cargo fmt --check

AI-assisted — Tool: Codex; model: unavailable/unavailable; version: unavailable.


Note

Medium Risk
Changes path resolution for a user-facing command and extends persisted install layout metadata; behavior is backward-compatible via serde defaults and legacy inference, but wrong placement reconstruction could still mis-report licenses on edge-case hoisted trees.

Overview
aube licenses no longer assumes an isolated virtual store. It prefers the install layout snapshot in state (linker mode, modulesDir, hoisting limits), reconstructs hoisted placements from the full lockfile graph, then reads each package’s package.json from the on-disk hoisted path instead of node_modules/.aube/...—fixing hoisted installs where every license showed as UNKNOWN.

Install finalize now persists modules_dir_name and hoisting_limits into InstallLayoutState, and adds read_default_state_layout so layout can still be found under default node_modules after modulesDir moves. Older state without those fields is handled by inferring the modules directory from recorded direct entries and picking the hoisted plan that best matches existing directories on disk.

Bats coverage was added for hoisted installs, post-install .npmrc changes, and legacy layout JSON missing the new fields.

Reviewed by Cursor Bugbot for commit 6e2068a. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

  • Bug Fixes
    • Improved aube licenses (including --long --json) to resolve packages using the recorded hoisted layout, keeping on-disk paths correct even if settings change later.
    • License extraction for hoisted installs is now more reliable, avoiding incorrect "UNKNOWN" results.
    • Hoisting limits and modules directory naming are persisted to ensure consistent reporting across runs.
  • Tests
    • Added coverage for recorded hoisted layouts (including legacy inference) and for accurate path/license resolution under varying settings.

@coderabbitai

coderabbitai Bot commented Jul 29, 2026 •

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 1864a47d-e855-4a45-bf71-e451ba4ce3c7

📥 Commits

Reviewing files that changed from the base of the PR and between 428d9a7 and 6e2068a.

📒 Files selected for processing (4)
  • crates/aube/src/commands/install/finalize.rs
  • crates/aube/src/commands/licenses.rs
  • crates/aube/src/state.rs
  • test/licenses.bats

📝 Walkthrough

Walkthrough

The install state now records modules-directory and hoisting-limit details. The licenses command uses recorded or inferred layouts to reconstruct hoisted package paths when reading license manifests, with coverage for current, changed, and legacy settings.

Changes

Hoisted license reporting

Layer / File(s) Summary
Persist installation layout inputs
crates/aube/src/state.rs, crates/aube/src/commands/install/finalize.rs
Install state persists the modules directory and hoisting limits, derives them from the install layout, and supports default-layout fallback.
Select installation placements
crates/aube/src/commands/licenses.rs
The command checks recorded layout and linker settings, reconstructs hoisted placements, and handles legacy layout inference.
Resolve manifests and validate output
crates/aube/src/commands/licenses.rs, test/licenses.bats
Manifest lookup prefers hoisted package directories with virtual-store fallback, while tests cover current, changed, and legacy layouts.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant licenses
  participant InstallState
  participant HoistedPlacements
  participant LicenseReport

  User->>licenses: run licenses --long --json
  licenses->>InstallState: read recorded or default layout
  licenses->>HoistedPlacements: reconstruct placements when hoisted
  licenses->>LicenseReport: collect_rows with placements
  LicenseReport-->>User: package paths and license fields
Loading

Suggested reviewers: imjustprism

Poem

A bunny hops through node_modules bright,
Finding each license in just the right site.
Hoisted paths bloom, UNKNOWNs take flight,
JSON carrots sparkle in moonlit light.
“Ship it!” squeaks the rabbit—what a delightful night!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: resolving license packages from hoisted dependency layouts.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Jul 29, 2026 •

Copy link
Copy Markdown

Instruction counts

benchmark trend instructions Δ wall (min) Δ
graph ▁▁▁▁▁█████▇▇▇███▇████ 16,714,886 → 16,715,312 +0.00% 3.52 → 3.17ms -10.19%
install ▃▃▁▄▃▇▄▅▇▆▅▅▇▅▅▅▅█▇▇█ 103,146,594 → 103,174,508 +0.03% 27.64 → 25.52ms -7.67%
startup ▁▁▂▁▁▇▇▇█▇▆▇▆▇▇▇▇▆█▇█ 7,675,354 → 7,678,661 +0.04% 2.57 → 2.56ms -0.63%
tree ▁▁▁▁▁▅▄▄▄▄▄▄▄▄▄▄█████ 17,799,484 → 17,801,834 +0.01% 3.91 → 3.42ms -12.53%

No instruction-count regression above 1%.

Only instruction counts gate. Wall clock is shown for context — on identical hardware it moves 4-20% run to run.

Measured by tak — instruction-counted CLI benchmarks, stored in this repository's git notes.

6e2068af36a2 vs 34d941629b05 · measured on this runner, not pushed to the history.

@jdx
jdx marked this pull request as ready for review July 29, 2026 22:06
Comment thread crates/aube/src/commands/licenses.rs Resolved
@greptile-apps

greptile-apps Bot commented Jul 29, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR makes license reporting resolve manifests using the materialized install layout.

  • Persists the modules directory and hoisting limits in successful install state.
  • Reconstructs hoisted placements from the full dependency graph before applying production/development filtering.
  • Supports legacy state by inferring the modules directory and matching reconstructed placements against directories on disk.
  • Adds regression coverage for hoisted installs and post-install configuration changes.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
crates/aube/src/commands/install/finalize.rs Captures the resolved hoisting limits when writing the completed install layout.
crates/aube/src/commands/licenses.rs Uses recorded layout metadata and on-disk-matched legacy placements to resolve manifests from hoisted installs.
crates/aube/src/state.rs Extends backward-compatible install state with modules-directory and hoisting-limit metadata.
test/licenses.bats Covers current and legacy hoisted layouts, including configuration changes after installation.

Reviews (3): Last reviewed commit: "fix(licenses): support legacy hoisted st..." | Re-trigger Greptile

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 341cd29. Configure here.

Comment thread crates/aube/src/commands/licenses.rs Resolved
@jdx
jdx enabled auto-merge (squash) July 29, 2026 22:32
@jdx
jdx merged commit fa074ba into main Jul 29, 2026
19 of 20 checks passed
@jdx
jdx deleted the agent/fix-hoisted-licenses branch July 29, 2026 22:43
@cursor cursor Bot mentioned this pull request Jul 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant