### What does this PR do?
Handles EXDEV correctly after first clonefile fails with ENOENT
Fixes#23579Fixes#23577
### How did you verify your code works?
Manually
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
### What does this PR do?
Add missing error handling for directory entries errors
The code was missing a check for .err
### How did you verify your code works?
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
### What does this PR do?
Fixes `bun -p "process.stderr.write('Hello' +
String.fromCharCode(0xd800))"`.
Also fixes potential index out of bounds if there are many invalid
sequences.
This also affects `TextEncoder`.
### How did you verify your code works?
Added tests for edgecases
---------
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
### What does this PR do?
Makes isolated installs the default install strategy for projects with
workspaces in Bun v1.3.
Also fixes creating patches with `bun patch` and `--linker isolated`
Fixes#22693
### How did you verify your code works?
Added tests for node_modules renaming `bun patch` with isolated install.
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
## Summary
This PR improves the correctness of bin linking by atomically
normalizing `\r\n` to `\n` in shebang lines when linking bins.
### Changes
- **Refactored shebang normalization in `src/install/bin.zig`**:
- Extracted logic into separate `tryNormalizeShebang` function
- Changed from in-place file modification to atomic file replacement
- Reads entire file, creates temporary file with corrected shebang, then
atomically renames
- Properly cleans up temporary files on errors
- **Added test coverage**:
- New test file `test/cli/install/shebang-normalize.test.ts` verifies
CRLF normalization works correctly
- Modified existing test in `bun-link.test.ts` to use Python script with
CRLF shebang
### Why
The previous implementation modified files in-place by seeking to the
`\r` position and overwriting with `\n`. This could potentially corrupt
files if interrupted mid-write. The new atomic approach ensures file
integrity by writing to a temporary file first, then renaming it to
replace the original.
## Test plan
- ✅ `bun bd test test/cli/install/shebang-normalize.test.ts` - passes
- ✅ Verified bins with CRLF shebangs are normalized to LF during linking
- ✅ Code compiles successfully
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
### What does this PR do?
fixes#22679
* includes a better error if a package cant be met because of the age
(but would normally)
* logs the resolved one in --verbose (which can be helpful in debugging
to show it does know latest but couldn't use)
* makes bun outdated show in the table when the package isn't true
latest
* includes a rudimentary "stability" check if a later version is in
blacked out time (but only up to 7 days as it goes back to latest with
min age)
For extended security we could also Last-Modified header of the tgz
download and then abort if too new (just like the hash)
| install error with no recent version | bun outdated respecting the
rule |
| --- | --- |
<img width="838" height="119" alt="image"
src="https://github.com/user-attachments/assets/b60916a8-27f6-4405-bfb6-57f9fa8bb0d6"
/> | <img width="609" height="314" alt="image"
src="https://github.com/user-attachments/assets/d8869ff4-8e16-492c-8e4c-9ac1dfa302ba"
/> |
For stable release we will make it use `3d` type syntax instead of magic
second numbers.
### How did you verify your code works?
tests & manual
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Dylan Conway <dylan.conway567@gmail.com>
## Summary
During `yarn.lock` migration, OS/CPU package metadata was not being
fetched from the npm registry when missing from `yarn.lock`. This caused
packages with platform-specific requirements to not be properly marked,
potentially leading to incorrect package installation behavior.
## Changes
Updated `fetchNecessaryPackageMetadataAfterYarnOrPnpmMigration` to
conditionally fetch OS/CPU metadata:
- **For yarn.lock migration**: Fetches OS/CPU metadata from npm registry
when not present in yarn.lock (`update_os_cpu = true`)
- **For pnpm-lock.yaml migration**: Skips OS/CPU fetching since
pnpm-lock.yaml already includes this data (`update_os_cpu = false`)
### Files Modified
- `src/install/lockfile.zig` - Added comptime `update_os_cpu` parameter
and conditional logic to fetch OS/CPU metadata
- `src/install/yarn.zig` - Pass `true` to enable OS/CPU fetching for
yarn migrations
- `src/install/pnpm.zig` - Pass `false` to skip OS/CPU fetching for pnpm
migrations (already parsed from lockfile)
## Why This Approach
- `yarn.lock` format often doesn't include OS/CPU constraints, requiring
us to fetch from npm registry
- `pnpm-lock.yaml` already parses OS/CPU during migration (lines 618-621
in pnpm.zig), making additional fetching redundant
- Using a comptime parameter allows the compiler to optimize away the
unused code path
## Testing
- ✅ Debug build compiles successfully
- Tested that the function correctly updates `pkg_meta.os` and
`pkg_meta.arch` only when:
- `update_os_cpu` is `true` (yarn migration)
- Current values are `.all` (not already set)
- Package metadata is available from npm registry
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Dylan Conway <dylan.conway567@gmail.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
### What does this PR do?
Packages with self dependencies at a different version were colliding
with the current version in the store node_modules. This pr nests them
in another node_modules
Example:
self-dep@1.0.2 has a dependency on self-dep@1.0.1.
self-dep@1.0.2 is placed here in:
`./node_modules/.bun/self-dep@1.0.2/node_modules/self-dep`
and it's self-dep dependency symlink is now placed in:
`./node_modules/.bun/self-dep@1.0.2/node_modules/self-dep/node_modules/self-dep`
fixes#22681
### How did you verify your code works?
Manually tested the linked issue is working, and added a test
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
### What does this PR do?
Parsing would fail because the lockfile version might be parsing as a
non-whole float instead of a string (`5.4` vs `'5.4'`) and the migration
would have the wrong error.
### How did you verify your code works?
Added a test
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
### What does this PR do?
It's common for monorepos to exclude portions of a large glob
```json
"workspaces": [
"packages/**",
"!packages/**/test/**",
"!packages/**/template/**"
],
```
closes#4621 (note: patterns like `"packages/!(*-standalone)"` will need
to be written `"!packages/*-standalone"`)
### How did you verify your code works?
Manually tested https://github.com/opentiny/tiny-engine, and added a new
workspace test.
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
### What does this PR do?
Fixes `file:.` in root package.json or `file:../..` in workspace
package.json (if '../..' points to the root of the project)
### How did you verify your code works?
Added a test
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
## Summary
This PR continues the work from #22107 to fix the `--tolerate-republish`
flag implementation in `bun publish`.
### Changes:
- **Pre-check version existence**: Before attempting to publish with
`--tolerate-republish`, check if the version already exists on the
registry
- **Improved version checking**: Use GET request to package endpoint
instead of HEAD, then parse JSON response to check if specific version
exists
- **Correct output stream**: Output warning to stderr instead of stdout
for consistency with test expectations
- **Better error handling**: Update test to accept both 403 and 409 HTTP
error codes for duplicate publish attempts
### Test fixes:
The tests were failing because:
1. The mock registry returns 409 Conflict (not 403) for duplicate
packages
2. The warning message wasn't appearing in stderr as expected
3. The version check was using HEAD request which doesn't reliably
return version info
## Test plan
- [x] Fixed failing tests for `--tolerate-republish` functionality
- [x] Tests now properly handle both 403 and 409 error responses
- [x] Warning messages appear correctly in stderr
🤖 Generated with [Claude Code](https://claude.ai/code)
---------
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Dylan Conway <dylan.conway567@gmail.com>
### What does this PR do?
Two things:
- we weren't adding the root package to the `pkg_map`.
- `link:` dependency paths in `"snapshots"` weren't being joined with
the top level dir.
### How did you verify your code works?
Manually and added a test.
### What does this PR do?
fixes#7157, fixes#14662
migrates pnpm-workspace.yaml data to package.json & converts
pnpm-lock.yml to bun.lock
---
### How did you verify your code works?
manually, tests and real world examples
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Dylan Conway <dylan.conway567@gmail.com>
### What does this PR do?
This change was missing after changing semver core numbers to use u64.
Also fixes potentially serializing uninitialized bytes from resolution
unions.
### How did you verify your code works?
Added a test for migrating a bun.lockb with most features used.
### What does this PR do?
Sometimes packages will use very large numbers exceeding max u32 for
major/minor/patch (usually patch). This pr changes each core number in
bun to u64.
Because we serialize package information to disk for the binary lockfile
and package manifests, this pr bumps the version of each. We don't need
to change anything other than the version for serialized package
manifests because they will invalidate and save the new version. For old
binary lockfiles, this pr adds logic for migrating to the new version.
Even if there are no changes, migrating will always save the new
lockfile. Unfortunately means there will be a one time invisible diff
for binary lockfile users, but this is better than installs failing to
work.
fixes#22881fixes#21793fixes#16041fixes#22891
resolves BUN-7MX, BUN-R4Q, BUN-WRB
### How did you verify your code works?
Manually, and added a test for migrating from an older binary lockfile.
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
## Summary
Implements `--cpu` and `--os` flags for `bun install` to filter optional
dependencies based on target architecture and operating system. This
allows developers to control which platform-specific optional
dependencies are installed.
## What Changed
### Core Implementation
- Added `--cpu` and `--os` flags to `bun install` command that accept
multiple values
- Multiple values combine with bitwise OR (e.g., `--cpu x64 --cpu arm64`
matches packages for either architecture)
- Updated `isDisabled` methods throughout the codebase to accept custom
CPU/OS targets
- Removed deprecated `isMatch` methods in favor of `isMatchWithTarget`
for consistency
### Files Modified
- `src/install/npm.zig` - Removed `isMatch` methods, standardized on
`isMatchWithTarget`
- `src/install/PackageManager/CommandLineArguments.zig` - Parse and
validate multiple flag values
- `src/install/PackageManager/PackageManagerOptions.zig` - Pass CPU/OS
options through
- `src/install/lockfile/Package.zig` & `Package/Meta.zig` - Updated
`isDisabled` signatures
- `src/install/lockfile/Tree.zig` & `lockfile.zig` - Updated call sites
## Usage Examples
```bash
# Install only x64 dependencies
bun install --cpu x64
# Install dependencies for both x64 and arm64
bun install --cpu x64 --cpu arm64
# Install Linux-specific dependencies
bun install --os linux
# Install for multiple platforms
bun install --cpu x64 --cpu arm64 --os linux --os darwin
```
## Test Plan
✅ All 10 tests pass in `test/cli/install/bun-install-cpu-os.test.ts`:
- CPU architecture filtering
- OS filtering
- Combined CPU and OS filtering
- Multiple CPU architectures support
- Multiple operating systems support
- Multiple CPU and OS combinations
- Error handling for invalid values
- Negated CPU/OS support (`!arm64`, `!linux`)
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
### What does this PR do?
`PackageManager.temp_dir_path` is used for manifest serialization on
windows. It is also accessed and potentially set on multiple threads. To
avoid the problem entirely this PR wraps `getTemporaryDirectory` in
`bun.once`.
fixes#22748fixes#22629fixes#19150fixes#13779
### How did you verify your code works?
Manually
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
## What does this PR do?
Fixes a bug where custom tarball URLs get corrupted during installation,
causing 404 errors when installing packages from private registries.
## How did you test this change?
- Added test case in `test/cli/install/bun-add.test.ts` that reproduces
the issue with nested tarball dependencies
- Verified the test fails without the fix and passes with it
- Tested with debug build to confirm the fix resolves the URL corruption
## The Problem
When installing packages from custom tarball URLs, the URLs were getting
mangled with cache folder patterns. The issue had two root causes:
1. **Temporary directory naming**: The extract_tarball.zig code was
including the full URL (including protocol) in temp directory names,
causing string truncation issues with StringOrTinyString's 31-byte limit
2. **Empty package names**: Tarball dependencies with empty package
names weren't being properly handled during deduplication, causing
incorrect package lookups
## The Fix
1. **In extract_tarball.zig**: Now properly extracts just the filename
from URLs using `std.fs.path.basename()` instead of including the full
URL in temp directory names
2. **In PackageManagerEnqueue.zig**: Added handling for empty package
names in tarball dependencies by falling back to the dependency name
🤖 Generated with [Claude Code](https://claude.ai/code)
---------
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
## Summary
Fixes#18413 - Empty chunked gzip responses were causing `Decompression
error: ShortRead`
## The Issue
When a server sends an empty response with `Content-Encoding: gzip` and
`Transfer-Encoding: chunked`, Bun was throwing a `ShortRead` error. This
occurred because the code was checking if `avail_in == 0` (no input
data) and immediately returning an error, without attempting to
decompress what could be a valid empty gzip stream.
## The Fix
Instead of checking `avail_in == 0` before calling `inflate()`, we now:
1. Always call `inflate()` even when `avail_in == 0`
2. Check the return code from `inflate()`
3. If it returns `BufError` with `avail_in == 0`, then we truly need
more data and return `ShortRead`
4. If it returns `StreamEnd`, it was a valid empty gzip stream and we
finish successfully
This approach correctly distinguishes between "no data yet" and "valid
empty gzip stream".
## Why This Works
- A valid empty gzip stream still has headers and trailers (~20 bytes)
- The zlib `inflate()` function can handle empty streams correctly
- `BufError` with `avail_in == 0` specifically means "need more input
data"
## Test Plan
✅ Added regression test in `test/regression/issue/18413.test.ts`
covering:
- Empty chunked gzip response
- Empty non-chunked gzip response
- Empty chunked response without gzip
✅ Verified all existing gzip-related tests still pass
✅ Tested with the original failing case from the issue
🤖 Generated with [Claude Code](https://claude.ai/code)
---------
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Ciro Spaciari <ciro.spaciari@gmail.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
## Summary
Fixes index out of bounds panic in `PackageJSONEditor` when removing
duplicate trusted dependencies.
The issue occurred when iterating over
`trusted_deps_to_add_to_package_json.items` with a `for` loop and
calling `swapRemove()` during iteration. The `for` loop captures the
array length at the start, but `swapRemove()` modifies the array length,
causing the loop to access indices that are now out of bounds.
## Root Cause
In `PackageJSONEditor.zig:408`, the code was:
```zig
for (manager.trusted_deps_to_add_to_package_json.items, 0..) |trusted_package_name, i| {
// ... find duplicate logic ...
allocator.free(manager.trusted_deps_to_add_to_package_json.swapRemove(i));
}
```
When `swapRemove(i)` is called, it removes the element and decreases the
array length, but the `for` loop continues with the original captured
length, leading to index out of bounds.
## Solution
Changed to iterate backwards using a `while` loop:
```zig
var i: usize = manager.trusted_deps_to_add_to_package_json.items.len;
while (i > 0) {
i -= 1;
// ... same logic ...
allocator.free(manager.trusted_deps_to_add_to_package_json.swapRemove(i));
}
```
Backwards iteration is safe because removing elements doesn't affect
indices we haven't processed yet.
## Test Plan
Manually tested the reproduction case:
```bash
# This command previously panicked, now works
bun install -g --trust @google/gemini-cli
```
Fixes#22261🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Replace `catch bun.outOfMemory()`, which can accidentally catch
non-OOM-related errors, with either `bun.handleOom` or a manual `catch
|err| switch (err)`.
(For internal tracking: fixes STAB-1070)
---------
Co-authored-by: Dylan Conway <dylan.conway567@gmail.com>
### What does this PR do?
Fixes#22014
todo:
- [x] not spawn sync
- [x] better comm to subprocess (not stderr)
- [x] tty
- [x] more tests (also include some tests for the actual implementation
of a provider)
- [x] disable autoinstall?
Scanner template: https://github.com/oven-sh/security-scanner-template
<!-- **Please explain what your changes do**, example: -->
<!--
This adds a new flag --bail to bun test. When set, it will stop running
tests after the first failure. This is useful for CI environments where
you want to fail fast.
-->
---
- [x] Documentation or TypeScript types (it's okay to leave the rest
blank in this case)
- [x] Code changes
### How did you verify your code works?
<!-- **For code changes, please include automated tests**. Feel free to
uncomment the line below -->
<!-- I wrote automated tests -->
<!-- If JavaScript/TypeScript modules or builtins changed:
- [ ] I included a test for the new code, or existing tests cover it
- [ ] I ran my tests locally and they pass (`bun-debug test
test-file-name.test`)
-->
<!-- If Zig files changed:
- [ ] I checked the lifetime of memory allocated to verify it's (1)
freed and (2) only freed when it should be
- [ ] I included a test for the new code, or an existing test covers it
- [ ] JSValue used outside of the stack is either wrapped in a
JSC.Strong or is JSValueProtect'ed
- [ ] I wrote TypeScript/JavaScript tests and they pass locally
(`bun-debug test test-file-name.test`)
-->
<!-- If new methods, getters, or setters were added to a publicly
exposed class:
- [ ] I added TypeScript types for the new methods, getters, or setters
-->
<!-- If dependencies in tests changed:
- [ ] I made sure that specific versions of dependencies are used
instead of ranged or tagged versions
-->
<!-- If a new builtin ESM/CJS module was added:
- [ ] I updated Aliases in `module_loader.zig` to include the new module
- [ ] I added a test that imports the module
- [ ] I added a test that require() the module
-->
tests (bad currently)
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Dylan Conway <dylan-conway@users.noreply.github.com>
Co-authored-by: Dylan Conway <dylan.conway567@gmail.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
## Summary
Fixes a panic that occurred when parsing malformed integrity data in
lockfiles. The issue was in `integrity.zig` where base64 decoding
attempted to write more bytes than the fixed-size digest buffer could
hold, causing `panic: index out of bounds: index 64, len 64`.
## Root Cause
The `Integrity.parse()` function tried to decode base64 data into a
fixed 64-byte buffer without validating that the decoded size wouldn't
exceed the buffer capacity. When malformed or oversized base64 integrity
strings were encountered in lockfiles, this caused an out-of-bounds
write.
## Fix
Added proper bounds checking in `src/install/integrity.zig`:
- Validates expected digest length before decoding
- Checks decoded size against buffer capacity using `calcSizeForSlice()`
- Only decodes into appropriately sized buffer slice based on hash
algorithm
- Returns `unknown` tag for malformed data instead of panicking
## Test Plan
- [x] Verified release binary crashes with malformed integrity data
- [x] Verified debug build with fix handles malformed data gracefully
- [x] Added comprehensive regression tests for all hash types (sha1,
sha256, sha384, sha512)
- [x] Confirmed normal lockfile parsing continues to work correctly
- [x] Tests pass: `bun bd test
test/regression/issue/integrity-base64-bounds-check.test.ts`
## Before/After
**Before**: `panic: index out of bounds: index 64, len 64`
**After**: Graceful handling with warning about malformed integrity data
🤖 Generated with [Claude Code](https://claude.ai/code)
---------
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
## Summary
Fixes a crash in Package.zig where top-level catalog strings weren't
being counted before appending to the string builder.
## Root Cause
The issue occurred in the `parseWithJSON` function where:
1. **Counting phase**: Only catalog strings in the "workspaces"
expression were counted via `lockfile.catalogs.parseCount()`
2. **Appending phase**: There was a conditional call to
`lockfile.catalogs.parseAppend()` for top-level JSON catalog strings
3. **Result**: String builder allocation was insufficient when top-level
catalog strings were processed
## Changes
- Added `lockfile.catalogs.parseCount(lockfile, json, &string_builder)`
in the counting phase to ensure top-level catalog strings are always
counted
- Added explanatory comment documenting why this counting is necessary
## Test Plan
- [x] Built debug version successfully
- [x] Verified bun-debug binary works correctly
- [ ] Should be tested with package.json files that have top-level
catalog configurations
🤖 Generated with [Claude Code](https://claude.ai/code)
---------
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
### What does this PR do?
followup #21833
### How did you verify your code works?
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
## Summary
Optimizes the `--lockfile-only` flag to skip downloading **npm package
tarballs** since they're not needed for lockfile generation. This saves
bandwidth and improves performance for lockfile-only operations while
preserving accuracy for non-npm dependencies.
## Changes
- **Add `prefetch_resolved_tarballs` flag** to
`PackageManagerOptions.Do` struct (defaults to `true`)
- **Set flag to `false`** when `--lockfile-only` is used
- **Skip tarball downloads for npm packages only** when flag is
disabled:
- `getOrPutResolvedPackageWithFindResult` - Main npm package resolution
(uses `Task.Id.forNPMPackage`)
- `enqueuePackageForDownload` - NPM package downloads (uses
`bun.Semver.Version`)
- **Preserve tarball downloads for non-npm dependencies** to maintain
lockfile accuracy:
- Remote tarball URLs (needed for lockfile generation)
- GitHub dependencies (needed for lockfile generation)
- Generic tarball downloads (may be remote)
- Patch-related downloads (needed for patch application)
- **Add comprehensive test** that verifies only package manifests are
fetched for npm packages with `--lockfile-only`
## Rationale
Only npm registry packages can safely skip tarball downloads during
lockfile generation because:
✅ **NPM packages**: Metadata is available from registry manifests,
tarball not needed for lockfile
❌ **Remote URLs**: Need tarball content to determine package metadata
and generate accurate lockfile
❌ **GitHub deps**: Need tarball content to extract package.json and
determine dependencies
❌ **Tarball URIs**: Need content to determine package structure and
dependencies
This selective approach maximizes bandwidth savings while ensuring
lockfile accuracy.
## Test Plan
- ✅ New test in `test/cli/install/lockfile-only.test.ts` verifies only
npm manifest URLs are requested
- ✅ Uses absolute package versions to ensure the npm resolution code
path is hit
- ✅ Test output normalized to work with both debug and non-debug builds
- ✅ All existing install/update tests still pass (including remote
dependency tests)
## Performance Impact
For `--lockfile-only` operations with npm packages, this eliminates
unnecessary tarball downloads, reducing:
- **Network bandwidth usage** (manifests only, not tarballs)
- **Installation time** (no tarball extraction/processing)
- **Cache storage requirements** (tarballs not cached)
The optimization only affects npm packages in `--lockfile-only` mode and
has zero impact on:
- Regular installs (npm packages still download tarballs)
- Remote dependencies (always download tarballs for accuracy)
- GitHub dependencies (always download tarballs for accuracy)
## Files Changed
- `src/install/PackageManager/PackageManagerOptions.zig` - Add flag and
configure for lockfile-only
- `src/install/PackageManager/PackageManagerEnqueue.zig` - Skip npm
tarball generation selectively
- `test/cli/install/lockfile-only.test.ts` - Test with dummy registry
🤖 Generated with [Claude Code](https://claude.ai/code)
---------
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
Co-authored-by: Alistair Smith <hi@alistair.sh>
### What does this PR do?
cases like `@prisma/engines-version` with version of
`6.14.0-17.fba13060ef3cfbe5e95af3aaba61eabf2b8a8a20` was having issues
with the version and using a "corrupted" string instead
### How did you verify your code works?
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* Move `DebugThreadLock` to `bun.safety`
* Enable in `ci_assert` builds, but store stack traces only in debug
builds
* Reduce size of struct by making optional field non-optional
* Add `initLockedIfNonComptime` as a workaround for not being able to
call `initLocked` in comptime contexts
* Add `lockOrAssert` method to acquire the lock if unlocked, or else
assert that the current thread acquired the lock
* Add stack traces to `CriticalSection` and `AllocPtr` in debug builds
* Make `MimallocArena.init` infallible
* Make `MimallocArena.heap` non-nullable
* Rename `RefCount.active_counts` to `raw_count` and provide read-only
`get` method
* Add `bun.safety.alloc.assertEq` to assert that two allocators are
equal (avoiding comparison of undefined `ptr`s)
(For internal tracking: fixes STAB-917, STAB-918, STAB-962, STAB-963,
STAB-964, STAB-965)
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
### What does this PR do?
fixes#6409
This PR implements `bun install` automatic migration from yarn.lock
files to bun.lock, preserving versions exactly. The migration happens
automatically when:
1. A project has a `yarn.lock` file
2. No `bun.lock` or `bun.lockb` file exists
3. User runs `bun install`
### Current Status: ✅ Complete and Working
The yarn.lock migration feature is **fully functional and
comprehensively tested**. All dependency types are supported:
- ✅ Regular npm dependencies (`package@^1.0.0`)
- ✅ Git dependencies (`git+https://github.com/user/repo.git`,
`github:user/repo`)
- ✅ NPM alias dependencies (`alias@npm:package@version`)
- ✅ File dependencies (`file:./path`)
- ✅ Remote tarball URLs (`https://registry.npmjs.org/package.tgz`)
- ✅ Local tarball files (`file:package.tgz`)
### Test Results
```bash
$ bun bd test test/cli/install/migration/yarn-lock-migration.test.ts
✅ 4 pass, 0 fail
- yarn-lock-mkdirp (basic npm dependency)
- yarn-lock-mkdirp-no-resolved (npm dependency without resolved field)
- yarn-lock-mkdirp-file-dep (file dependency)
- yarn-stuff (all complex dependency types: git, npm aliases, file, remote tarballs)
```
### How did you verify your code works?
1. **Comprehensive test suite**: Added 4 test cases covering all
dependency types
2. **Version preservation**: Verified that package versions are
preserved exactly during migration
3. **Real-world scenarios**: Tested with complex yarn.lock files
containing git deps, npm aliases, file deps, and remote tarballs
4. **Migration logging**: Confirms migration with log message `[X.XXms]
migrated lockfile from yarn.lock`
### Key Implementation Details
- **Core parser**: `src/install/yarn.zig` handles all yarn.lock parsing
and dependency type resolution
- **Integration**: Migration is built into existing lockfile loading
infrastructure
- **Performance**: Migration typically completes in ~1ms for most
projects
- **Compatibility**: Preserves exact dependency versions and resolution
behavior
The implementation correctly handles edge cases like npm aliases, git
dependencies with commits, file dependencies with transitive deps, and
remote tarballs.
---------
Co-authored-by: Jarred-Sumner <709451+Jarred-Sumner@users.noreply.github.com>
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: RiskyMH <git@riskymh.dev>
Co-authored-by: RiskyMH <56214343+RiskyMH@users.noreply.github.com>
### What does this PR do?
Fixes thread safety issues due to file poll code being not thread safe.
<!-- **Please explain what your changes do**, example: -->
<!--
This adds a new flag --bail to bun test. When set, it will stop running
tests after the first failure. This is useful for CI environments where
you want to fail fast.
-->
### How did you verify your code works?
Added tests for lifecycle scripts. The tests are unlikely to reproduce
the bug, but we'll know if it actually fixes the issue if
`test/package.json` doesn't show in flaky tests anymore.
<!-- **For code changes, please include automated tests**. Feel free to
uncomment the line below -->
<!-- I wrote automated tests -->
<!-- If JavaScript/TypeScript modules or builtins changed:
- [ ] I included a test for the new code, or existing tests cover it
- [ ] I ran my tests locally and they pass (`bun-debug test
test-file-name.test`)
-->
<!-- If Zig files changed:
- [ ] I checked the lifetime of memory allocated to verify it's (1)
freed and (2) only freed when it should be
- [ ] I included a test for the new code, or an existing test covers it
- [ ] JSValue used outside of the stack is either wrapped in a
JSC.Strong or is JSValueProtect'ed
- [ ] I wrote TypeScript/JavaScript tests and they pass locally
(`bun-debug test test-file-name.test`)
-->
<!-- If new methods, getters, or setters were added to a publicly
exposed class:
- [ ] I added TypeScript types for the new methods, getters, or setters
-->
<!-- If dependencies in tests changed:
- [ ] I made sure that specific versions of dependencies are used
instead of ranged or tagged versions
-->
<!-- If a new builtin ESM/CJS module was added:
- [ ] I updated Aliases in `module_loader.zig` to include the new module
- [ ] I added a test that imports the module
- [ ] I added a test that require() the module
-->
---------
Co-authored-by: taylor.fish <contact@taylor.fish>
## Summary
- Fixed buffer overflow in env_loader when parsing large environment
variables with escape sequences
- Replaced fixed 4096-byte buffer with a stack fallback allocator that
automatically switches to heap allocation for larger values
- Added comprehensive tests to prevent regression
## Background
The env_loader previously used a fixed threadlocal buffer that could
overflow when parsing environment variables containing escape sequences.
This caused crashes when the parsed value exceeded 4KB.
## Changes
- Replaced fixed buffer with `StackFallbackAllocator` that uses 4KB
stack buffer for common cases and falls back to heap for larger values
- Updated all env parsing functions to accept a reusable buffer
parameter
- Added proper memory cleanup with defer statements
## Test plan
- [x] Added test cases for large environment variables with escape
sequences
- [x] Added test for values larger than 4KB
- [x] Added edge case tests (empty quotes, escape at EOF)
- [x] All existing env tests continue to pass
fixes#11627
fixes BAPI-1274
🤖 Generated with [Claude Code](https://claude.ai/code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Also fix a race condition with hardlinking on Windows during hoisted
installs, and a bug in the process waiter thread implementation causing
items to be skipped.
(For internal tracking: fixes STAB-850, STAB-873, STAB-881)