The Flutter code generator for your assets, fonts, colors, … — Get rid of all String-based APIs.
Inspired by SwiftGen .
Motivation
Using asset path string directly is not safe.
# pubspec.yaml
flutter:
assets:
- assets/images/profile.jpg
Bad What would happen if you made a typo?
Widget build(BuildContext context) {
return Image.asset('assets/images/profile.jpeg');
}
// The following assertion was thrown resolving an image codec:
// Unable to load asset: assets/images/profile.jpeg
Good We want to use it safely.
Widget build(BuildContext context) {
return Assets.images.profile.image();
}
Installation
Homebrew
Works with MacOS and Linux.
$ brew install FlutterGen/tap/fluttergen
Pub Global
Works with MacOS, Linux and Windows.
$ dart pub global activate flutter_gen
You might need to set up your path .
As a part of build_runner
Add build_runner and FlutterGen to your package’s pubspec.yaml file:
dev_dependencies:
build_runner:
flutter_gen_runner:
Install FlutterGen
$ flutter pub get
Use FlutterGen
$ flutter packages pub run build_runner build
Usage
Run fluttergen after the configuration pubspec.yaml .
$ fluttergen -h
$ fluttergen -c example/pubspec.yaml
Configuration file
FlutterGen generates dart files based on the key flutter and flutter_gen of pubspec.yaml . Default configuration can be found here .
# pubspec.yaml
# ...
flutter_gen:
output: lib/gen/ # Optional (default: lib/gen/)
line_length: 80 # Optional (default: 80)
# Optional
integrations:
flutter_svg: true
flare_flutter: true
colors:
inputs:
- assets/color/colors.xml
flutter:
uses-material-design: true
assets:
- assets/images/
fonts:
- family: Raleway
fonts:
- asset: assets/fonts/Raleway-Regular.ttf
- asset: assets/fonts/Raleway-Italic.ttf
style: italic
Available Parsers
Assets
Just follow the doc Adding assets and images#Specifying assets to specify assets, then FlutterGen will generate related dart files. No other specific configuration is required.Ignore duplicated.
# pubspec.yaml
flutter:
assets:
- assets/images/
- assets/images/chip3/chip.jpg
- assets/images/chip4/chip.jpg
- assets/images/icons/paint.svg
- assets/json/fruits.json
- assets/flare/Penguin.flr
- pictures/ocean_view.jpg
These configurations will generate assets.gen.dart under the lib/gen/ directory by default.
Usage Example
FlutterGen generates Image class if the asset is Flutter supported image format.
Example results of assets/images/chip.jpg:
Assets.images.chip is an implementation of AssetImage class .Assets.images.chip.image(...) returns Image class .Assets.images.chip.path just returns the path string.
Widget build(BuildContext context) {
return Image(image: Assets.images.chip);
}
Widget build(BuildContext context) {
return Assets.images.chip.image(
width: 120,
height: 120,
fit: BoxFit.scaleDown,
);
Widget build(BuildContext context) {
// Assets.images.chip.path = 'assets/images/chip3/chip3.jpg'
return Image.asset(Assets.images.chip.path);
}
If you are using SVG images with flutter_svg you can use the integration feature.
# pubspec.yaml
flutter_gen:
integrations:
flutter_svg: true
flutter:
assets:
- assets/images/icons/paint.svg
Widget build(BuildContext context) {
return Assets.images.icons.paint.svg(
width: 120,
height: 120
);
}
Available Integrations
Packages File extension Setting Usage flutter_svg .svg flutter_svg: trueAssets.images.icons.paint.svg() flare_flutter .flr flare_flutter: trueAssets.flare.penguin.flare()
In other cases, the asset is generated as String class.
// If don't use the Integrations.
final svg = SvgPicture.asset(Assets.images.icons.paint);
final json = await rootBundle.loadString(Assets.json.fruits);
FlutterGen also support generating other style of Assets class:
# pubspec.yaml
flutter_gen:
assets:
# Assets.imagesChip
# style: camel-case
# Assets.images_chip
# style: snake-case
# Assets.images.chip (default style)
# style: dot-delimiter
flutter:
assets:
- assets/images/chip.png
The root directory will be omitted if it is either assets or asset .
assets/images/chip3/chip.jpg => Assets.images.chip3.chip
assets/images/chip4/chip.jpg => Assets.images.chip4.chip
assets/images/icons/paint.svg => Assets.images.icons.paint
assets/json/fruits.json => Assets.json.fruits
pictures/ocean_view.jpg => Assets.pictures.oceanView
Example of code generated by FlutterGen
/// GENERATED CODE - DO NOT MODIFY BY HAND
/// *****************************************************
/// FlutterGen
/// *****************************************************
import 'package:flutter/widgets.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:flutter/services.dart';
import 'package:flare_flutter/flare_actor.dart';
import 'package:flare_flutter/flare_controller.dart';
class $PicturesGen {
const $PicturesGen();
AssetGenImage get chip5 => const AssetGenImage('pictures/chip5.jpg');
}
class $AssetsFlareGen {
const $AssetsFlareGen();
FlareGenImage get penguin => const FlareGenImage('assets/flare/Penguin.flr');
}
class $AssetsImagesGen {
const $AssetsImagesGen();
AssetGenImage get chip1 => const AssetGenImage('assets/images/chip1.jpg');
AssetGenImage get chip2 => const AssetGenImage('assets/images/chip2.jpg');
$AssetsImagesChip3Gen get chip3 => const $AssetsImagesChip3Gen();
$AssetsImagesChip4Gen get chip4 => const $AssetsImagesChip4Gen();
$AssetsImagesIconsGen get icons => const $AssetsImagesIconsGen();
AssetGenImage get logo => const AssetGenImage('assets/images/logo.png');
AssetGenImage get profile => const AssetGenImage('assets/images/profile.jpg');
}
class $AssetsJsonGen {
const $AssetsJsonGen();
String get fruits => 'assets/json/fruits.json';
}
class $AssetsMovieGen {
const $AssetsMovieGen();
String get theEarth => 'assets/movie/the_earth.mp4';
}
class $AssetsUnknownGen {
const $AssetsUnknownGen();
String get unknownMimeType => 'assets/unknown/unknown_mime_type.bk';
}
class $AssetsImagesChip3Gen {
const $AssetsImagesChip3Gen();
AssetGenImage get chip3 =>
const AssetGenImage('assets/images/chip3/chip3.jpg');
}
class $AssetsImagesChip4Gen {
const $AssetsImagesChip4Gen();
AssetGenImage get chip4 =>
const AssetGenImage('assets/images/chip4/chip4.jpg');
}
class $AssetsImagesIconsGen {
const $AssetsImagesIconsGen();
SvgGenImage get fuchsia =>
const SvgGenImage('assets/images/icons/fuchsia.svg');
SvgGenImage get kmm => const SvgGenImage('assets/images/icons/kmm.svg');
SvgGenImage get paint => const SvgGenImage('assets/images/icons/paint.svg');
}
class Assets {
Assets._();
static const $AssetsFlareGen flare = $AssetsFlareGen();
static const $AssetsImagesGen images = $AssetsImagesGen();
static const $AssetsJsonGen json = $AssetsJsonGen();
static const $AssetsMovieGen movie = $AssetsMovieGen();
static const $AssetsUnknownGen unknown = $AssetsUnknownGen();
static const $PicturesGen pictures = $PicturesGen();
}
class AssetGenImage extends AssetImage {
const AssetGenImage(String assetName)
: _assetName = assetName,
super(assetName);
final String _assetName;
Image image({
Key key,
ImageFrameBuilder frameBuilder,
ImageLoadingBuilder loadingBuilder,
ImageErrorWidgetBuilder errorBuilder,
String semanticLabel,
bool excludeFromSemantics = false,
double width,
double height,
Color color,
BlendMode colorBlendMode,
BoxFit fit,
AlignmentGeometry alignment = Alignment.center,
ImageRepeat repeat = ImageRepeat.noRepeat,
Rect centerSlice,
bool matchTextDirection = false,
bool gaplessPlayback = false,
bool isAntiAlias = false,
FilterQuality filterQuality = FilterQuality.low,
}) {
return Image(
key: key,
image: this,
frameBuilder: frameBuilder,
loadingBuilder: loadingBuilder,
errorBuilder: errorBuilder,
semanticLabel: semanticLabel,
excludeFromSemantics: excludeFromSemantics,
width: width,
height: height,
color: color,
colorBlendMode: colorBlendMode,
fit: fit,
alignment: alignment,
repeat: repeat,
centerSlice: centerSlice,
matchTextDirection: matchTextDirection,
gaplessPlayback: gaplessPlayback,
isAntiAlias: isAntiAlias,
filterQuality: filterQuality,
);
}
String get path => _assetName;
}
class SvgGenImage {
const SvgGenImage(this._assetName);
final String _assetName;
SvgPicture svg({
Key key,
bool matchTextDirection = false,
AssetBundle bundle,
String package,
double width,
double height,
BoxFit fit = BoxFit.contain,
AlignmentGeometry alignment = Alignment.center,
bool allowDrawingOutsideViewBox = false,
WidgetBuilder placeholderBuilder,
Color color,
BlendMode colorBlendMode = BlendMode.srcIn,
String semanticsLabel,
bool excludeFromSemantics = false,
Clip clipBehavior = Clip.hardEdge,
}) {
return SvgPicture.asset(
_assetName,
key: key,
matchTextDirection: matchTextDirection,
bundle: bundle,
package: package,
width: width,
height: height,
fit: fit,
alignment: alignment,
allowDrawingOutsideViewBox: allowDrawingOutsideViewBox,
placeholderBuilder: placeholderBuilder,
color: color,
colorBlendMode: colorBlendMode,
semanticsLabel: semanticsLabel,
excludeFromSemantics: excludeFromSemantics,
clipBehavior: clipBehavior,
);
}
String get path => _assetName;
}
class FlareGenImage {
const FlareGenImage(this._assetName);
final String _assetName;
FlareActor flare({
String boundsNode,
String animation,
BoxFit fit = BoxFit.contain,
Alignment alignment = Alignment.center,
bool isPaused = false,
bool snapToEnd = false,
FlareController controller,
FlareCompletedCallback callback,
Color color,
bool shouldClip = true,
bool sizeFromArtboard = false,
String artboard,
bool antialias = true,
}) {
return FlareActor(
_assetName,
boundsNode: boundsNode,
animation: animation,
fit: fit,
alignment: alignment,
isPaused: isPaused,
snapToEnd: snapToEnd,
controller: controller,
callback: callback,
color: color,
shouldClip: shouldClip,
sizeFromArtboard: sizeFromArtboard,
artboard: artboard,
antialias: antialias,
);
}
String get path => _assetName;
}
Fonts
Just follow the doc Use a custom font to specify fonts, then FlutterGen will generate related dart files. No other specific configuration is required.Ignore duplicated.
# pubspec.yaml
flutter:
fonts:
- family: Raleway
fonts:
- asset: assets/fonts/Raleway-Regular.ttf
- asset: assets/fonts/Raleway-Italic.ttf
style: italic
- family: RobotoMono
fonts:
- asset: assets/fonts/RobotoMono-Regular.ttf
- asset: assets/fonts/RobotoMono-Bold.ttf
weight: 700
These configurations will generate fonts.gen.dart under the lib/gen/ directory by default.
Usage Example
Text(
'Hi there, I\'m FlutterGen',
style: TextStyle(
fontFamily: FontFamily.robotoMono,
fontFamilyFallback: const [FontFamily.raleway],
),
Example of code generated by FlutterGen
/// GENERATED CODE - DO NOT MODIFY BY HAND
/// *****************************************************
/// FlutterGen
/// *****************************************************
class FontFamily {
FontFamily._();
static const String raleway = 'Raleway';
static const String robotoMono = 'RobotoMono';
}
Colors
FlutterGen supports generating colors from XML format files.Ignore duplicated.
# pubspec.yaml
flutter_gen:
colors:
inputs:
- assets/color/colors.xml
- assets/color/colors2.xml
FlutterGen can generate a Color class based on the name attribute and the color hex value. If the element has the attribute type, then a specially color will be generated.
Currently supported special color types:
Noticed that there is no official material color generation algorithm. The implementation is based on the mcg project.
<color name="milk_tea">#F5CB84</color>
<color name="cinnamon" type="material">#955E1C</color>
<color name="yellow_ocher" type="material material-accent">#DF9527</color>
These configurations will generate colors.gen.dart under the lib/gen/ directory by default.
Usage Example
Text(
'Hi there, I\'m FlutterGen',
style: TextStyle(
color: ColorName.denim,
),
Example of code generated by FlutterGen
/// GENERATED CODE - DO NOT MODIFY BY HAND
/// *****************************************************
/// FlutterGen
/// *****************************************************
import 'package:flutter/painting.dart';
import 'package:flutter/material.dart';
class ColorName {
ColorName._();
static const Color black = Color(0xFF000000);
static const Color black30 = Color(0x4D000000);
static const Color black40 = Color(0x66000000);
static const Color black50 = Color(0x80000000);
static const Color black60 = Color(0x99000000);
static const MaterialColor crimsonRed = MaterialColor(
0xFFCF2A2A,
<int, Color>{
50: Color(0xFFF9E5E5),
100: Color(0xFFF1BFBF),
200: Color(0xFFE79595),
300: Color(0xFFDD6A6A),
400: Color(0xFFD64A4A),
500: Color(0xFFCF2A2A),
600: Color(0xFFCA2525),
700: Color(0xFFC31F1F),
800: Color(0xFFBD1919),
900: Color(0xFFB20F0F),
},
);
static const Color gray410 = Color(0xFF979797);
static const Color gray70 = Color(0xFFEEEEEE);
static const Color white = Color(0xFFFFFFFF);
static const MaterialColor yellowOcher = MaterialColor(
0xFFDF9527,
<int, Color>{
50: Color(0xFFFBF2E5),
100: Color(0xFFF5DFBE),
200: Color(0xFFEFCA93),
300: Color(0xFFE9B568),
400: Color(0xFFE4A547),
500: Color(0xFFDF9527),
600: Color(0xFFDB8D23),
700: Color(0xFFD7821D),
800: Color(0xFFD27817),
900: Color(0xFFCA670E),
},
);
static const MaterialAccentColor yellowOcherAccent = MaterialAccentColor(
0xFFFFBCA3,
<int, Color>{
100: Color(0xFFFFE8E0),
200: Color(0xFFFFBCA3),
400: Color(0xFFFFA989),
700: Color(0xFFFF9E7A),
},
);
}
Default Configuration
The following are the default settings. The options you set in pubspec.yaml will override the corresponding default options.
flutter_gen:
output: lib/gen/
line_length: 80
null_safety: true
integrations:
flutter_svg: false
flare_flutter: false
assets:
enabled: true
package_parameter_enabled: false
style: dot-delimiter
fonts:
enabled: true
colors:
enabled: true
inputs: []
flutter:
assets: []
fonts: []
Credits
The material color generation implementation is based on mcg and TinyColor .
Issues
Please file FlutterGen specific issues, bugs, or feature requests in our issue tracker .
Plugin issues that are not specific to FlutterGen can be filed in the Flutter issue tracker .
Contributing
We are looking for co-developers.
If you wish to contribute a change to any of the existing plugins in this repo, please review our contribution guide and open a pull request .
Download Flutter code generator source code on GitHub
The Flutter code generator for your assets, fonts, colors, … — Get rid of all String-based APIs. https://github.com/FlutterGen/flutter_gen 186 forks. 1,578 stars. 37 open issues. Recent commits: upgrade: update dependency prettier to v3.9.6 (#774)This PR contains the following updates:| Package | Change |[Age](https://docs.renovatebot.com/merge-confidence/) |[Confidence](https://docs.renovatebot.com/merge-confidence/) ||—|—|—|—|| [prettier](https://prettier.io)([source](https://redirect.github.com/prettier/prettier)) | [`3.8.1` →`3.9.6`](https://renovatebot.com/diffs/npm/prettier/3.8.1/3.9.6) |||—### Release Notes<details><summary>prettier/prettier (prettier)</summary>###[`v3.9.6`](https://redirect.github.com/prettier/prettier/compare/3.9.5…bd676aae6a3805672a21d02198e5d17c9cb1a97b)[CompareSource](https://redirect.github.com/prettier/prettier/compare/3.9.5…3.9.6)###[`v3.9.5`](https://redirect.github.com/prettier/prettier/blob/HEAD/CHANGELOG.md#395)[CompareSource](https://redirect.github.com/prettier/prettier/compare/3.9.4…3.9.5)[diff](https://redirect.github.com/prettier/prettier/compare/3.9.4…3.9.5)##### Markdown: Cap ordered list mark at 999,999,999([#19351](https://redirect.github.com/prettier/prettier/pull/19351)by [@tats-u](https://redirect.github.com/tats-u))CommonMark parsers only support ordered list item numbers up to999,999,999.With this change, Prettier now caps the ordered list item number at999,999,999 to ensure that the output is correctly parsed as an orderedlist by CommonMark parsers. Numbers larger than 999,999,999 are notparsed as list item numbers and are left unchanged in the output:<!– prettier-ignore –>“`markdown<!– Input –>999999998. text999999998. text999999998. text999999998. text1234567890123456789012) text<!– Prettier 3.9.4 –>999999998. text999999999. text1000000000. text1000000001. text1234567890123456789012) text<!– Prettier 3.9.5 –>999999998. text999999999. text999999999. text999999999. text1234567890123456789012) text“`##### Markdown: Avoid corrupting empty link with title([#19487](https://redirect.github.com/prettier/prettier/pull/19487)by [@andersk](https://redirect.github.com/andersk))Do not remove `<>` from an inline link or image with an empty URL and atitle, as this removal would change its interpretation.<!– prettier-ignore –>“`md<!– Input –>[link](<> "title")<!– Prettier 3.9.4 –>[link]( "title")<!– Prettier 3.9.5 –>[link](<> "title")“`##### Less: Remove extra spaces after `[` in map lookups([#19503](https://redirect.github.com/prettier/prettier/pull/19503)by [@kovsu](https://redirect.github.com/kovsu))<!– prettier-ignore –>“`less// Input.foo { color: #theme[ primary]; color: #theme[@name]; color: #theme[@@name];}// Prettier 3.9.4.foo { color: #theme[ primary]; color: #theme[ @name]; color: #theme[ @@name];}// Prettier 3.9.5.foo { color: #theme[primary]; color: #theme[@name]; color: #theme[@@name];}“`##### CSS: Prevent addition space in `type()` with `+`([#19516](https://redirect.github.com/prettier/prettier/pull/19516)by [@bigandy](https://redirect.github.com/bigandy))This fixes the addition space before `+` in CSS `type()` declaration.For example `type(<number>+)` was being converted into `type(<number>+)` which is invalid CSS and does not work.<!– prettier-ignore –>“`css/* Input */div { border-radius: attr(br type(<length>+));}/* Prettier 3.9.4 */div { border-radius: attr(br type(<length> +));}/* Prettier 3.9.5 */div { border-radius: attr(br type(<length>+));}“`##### Less: Remove spaces between merge markers and colons([#19517](https://redirect.github.com/prettier/prettier/pull/19517)by [@kovsu](https://redirect.github.com/kovsu))<!– prettier-ignore –>“`less// Inputa { box-shadow + : 0 0 1px #000;}// Prettier 3.9.4a { box-shadow+ : 0 0 1px #000;}// Prettier 3.9.5a { box-shadow+: 0 0 1px #000;}“`##### Markdown: Preserve wiki links with aliases([#19527](https://redirect.github.com/prettier/prettier/pull/19527)by [@kovsu](https://redirect.github.com/kovsu))<!– prettier-ignore –>“`markdown<!– Input –>[[Foo:Bar]]<!– Prettier 3.9.4 –>[[Foo]]<!– Prettier 3.9.5 –>[[Foo:Bar]]“`##### TypeScript: Fix comments being dropped on shorthand `type`import/export specifiers([#19565](https://redirect.github.com/prettier/prettier/pull/19565)by [@kirkwaiblinger](https://redirect.github.com/kirkwaiblinger))<!– prettier-ignore –>“`tsx// Inputexport { type /* comment */ T } from "foo";import { type /* comment */ T } from "foo";// Prettier 3.9.4Error: Comment "comment" was not printed. Please report this error!// Prettier 3.9.5export { type /* comment */ T } from "foo";import { type /* comment */ T } from "foo";“`##### Miscellaneous: Preserving comments' `placement` property([#19567](https://redirect.github.com/prettier/prettier/pull/19567)by [@Janther](https://redirect.github.com/Janther))Prettier\@3.9.0 deleted an undocumented property on comments,which was already used by plugins, `comment.placement` is now availableagain after comment attach.##### Flow: Stop enforcing empty module declaration to break([#19568](https://redirect.github.com/prettier/prettier/pull/19568)by [@fisker](https://redirect.github.com/fisker))<!– prettier-ignore –>“`flow// Inputdeclare module "foo" {}// Prettier 3.9.4declare module "foo" {}// Prettier 3.9.5declare module "foo" {}“`##### Angular: Support expression for exhaustive typechecking([#19571](https://redirect.github.com/prettier/prettier/pull/19571)by [@fisker](https://redirect.github.com/fisker))<!– prettier-ignore –>“`html<!– Input –>@switch (state.mode) { @default never(state);}<!– Prettier 3.9.4 –>@switch (state.mode) { @default never;}<!– Prettier 3.9.5 –>@switch (state.mode) { @default never(state);}“`##### TypeScript: Ignore comments inside mapped type when checking typeparameter comments([#19572](https://redirect.github.com/prettier/prettier/pull/19572)by [@fisker](https://redirect.github.com/fisker))<!– prettier-ignore –>“`tsx// Inputfoo<{ // comment [key in keyof Foo]: number}>();// Prettier 3.9.4foo< { // comment [key in keyof Foo]: number; }>();// Prettier 3.9.5foo<{ // comment [key in keyof Foo]: number;}>();“`##### Less: Fix adjacent block comments being corrupted([#19574](https://redirect.github.com/prettier/prettier/pull/19574)by [@kovsu](https://redirect.github.com/kovsu))<!– prettier-ignore –>“`less// Input/* a *//* b *//* a */* { color: red;}// Prettier 3.9.4/* a *//* b *//* a * { color: red;}// Prettier 3.9.5/* a */ /* b *//* a */* { color: red;}“`##### JavaScript: Handle dangling comments in `SwitchStatement`([#19581](https://redirect.github.com/prettier/prettier/pull/19581)by [@fisker](https://redirect.github.com/fisker))<!– prettier-ignore –>“`jsx// Inputswitch (foo) { // comment}// Prettier 3.9.4switch ( foo // comment) {}// Prettier 3.9.5switch (foo) { // comment}“`##### TypeScript: Remove space in comment-only object type([#19583](https://redirect.github.com/prettier/prettier/pull/19583)by [@fisker](https://redirect.github.com/fisker))<!– prettier-ignore –>“`tsx// Inputvar foo = { /* comment */};type Foo = { /* comment */};// Prettier 3.9.4var foo = {/* comment */};type Foo = { /* comment */ };// Prettier 3.9.5var foo = {/* comment */};type Foo = {/* comment */};“`###[`v3.9.4`](https://redirect.github.com/prettier/prettier/compare/3.9.3…3.9.4)[CompareSource](https://redirect.github.com/prettier/prettier/compare/3.9.3…3.9.4)###[`v3.9.3`](https://redirect.github.com/prettier/prettier/compare/b875c902b0509ca1ded6d4a12667d7834c8f8d00…b875c902b0509ca1ded6d4a12667d7834c8f8d00)[CompareSource](https://redirect.github.com/prettier/prettier/compare/3.9.2…3.9.3)###[`v3.9.2`](https://redirect.github.com/prettier/prettier/compare/3.9.1…b875c902b0509ca1ded6d4a12667d7834c8f8d00)[CompareSource](https://redirect.github.com/prettier/prettier/compare/3.9.1…3.9.2)###[`v3.9.1`](https://redirect.github.com/prettier/prettier/compare/3.9.0…3.9.1)[CompareSource](https://redirect.github.com/prettier/prettier/compare/3.9.0…3.9.1)###[`v3.9.0`](https://redirect.github.com/prettier/prettier/blob/HEAD/CHANGELOG.md#390)[CompareSource](https://redirect.github.com/prettier/prettier/compare/3.8.5…3.9.0)[diff](https://redirect.github.com/prettier/prettier/compare/3.8.5…3.9.0)🔗 [Release Notes](https://prettier.io/blog/2026/06/27/3.9.0)###[`v3.8.5`](https://redirect.github.com/prettier/prettier/compare/3.8.4…96395cbff58df7159fedd22a18446060873b2312)[CompareSource](https://redirect.github.com/prettier/prettier/compare/3.8.4…3.8.5)###[`v3.8.4`](https://redirect.github.com/prettier/prettier/blob/HEAD/CHANGELOG.md#384)[CompareSource](https://redirect.github.com/prettier/prettier/compare/3.8.3…3.8.4)[diff](https://redirect.github.com/prettier/prettier/compare/3.8.3…3.8.4)##### Markdown: Fix blank lines between list items and nested sub-listsbeing removed in Markdown/MDX([#17746](https://redirect.github.com/prettier/prettier/pull/17746)by [@byplayer](https://redirect.github.com/byplayer))Prettier was removing blank lines between list items and their nestedsub-lists, converting loose lists into tight lists and changing theirsemantic meaning.<!– prettier-ignore –>“`markdown<!– Input –>- a – b- c – d<!– Prettier 3.8.3 –>- a – b- c – d<!– Prettier 3.8.4 –>- a – b- c – d“`###[`v3.8.3`](https://redirect.github.com/prettier/prettier/blob/HEAD/CHANGELOG.md#383)[CompareSource](https://redirect.github.com/prettier/prettier/compare/3.8.2…3.8.3)[diff](https://redirect.github.com/prettier/prettier/compare/3.8.2…3.8.3)##### SCSS: Prevent trailing comma in `if()` function([#18471](https://redirect.github.com/prettier/prettier/pull/18471)by [@kovsu](https://redirect.github.com/kovsu))<!– prettier-ignore –>“`scss// Input$value: if(sass(false): 1; else: -1);// Prettier 3.8.2$value: if( sass(false): 1; else: -1,);// Prettier 3.8.3$value: if(sass(false): 1; else: -1);“`###[`v3.8.2`](https://redirect.github.com/prettier/prettier/blob/HEAD/CHANGELOG.md#382)[CompareSource](https://redirect.github.com/prettier/prettier/compare/3.8.1…3.8.2)[diff](https://redirect.github.com/prettier/prettier/compare/3.8.1…3.8.2)##### Angular: Support Angular v21.2([#18722](https://redirect.github.com/prettier/prettier/pull/18722),[#19034](https://redirect.github.com/prettier/prettier/pull/19034)by [@fisker](https://redirect.github.com/fisker))Exhaustive typechecking with `@default never;`<!– prettier-ignore –>“`html<!– Input –>@switch (foo) { @case (1) {} @default never;}<!– Prettier 3.8.1 –>SyntaxError: Incomplete block "default never". If you meant to write the @ character, you should use the "@" HTML entity instead. (3:3)<!– Prettier 3.8.2 –>@switch (foo) { @case (1) {} @default never;}““arrow function` and `instanceof` expressions.<!– prettier-ignore –>“`html<!– Input –>@let fn = (a) => a? 1:2;{{ fn ( a instanceof b)}}<!– Prettier 3.8.1 –>@let fn = (a) => a? 1:2;{{ fn ( a instanceof b)}}<!– Prettier 3.8.2 –>@let fn = (a) => (a ? 1 : 2);{{ fn(a instanceof b) }}“`</details>—### Configuration📅 **Schedule**: (in timezone Asia/Tokyo)- Branch creation – Only on Wednesday (`* * * * 3`)- Automerge – At any time (no schedule defined)🚦 **Automerge**: Disabled by config. Please merge this manually once youare satisfied.♻ **Rebasing**: Whenever PR is behind base branch, or you tick therebase/retry checkbox.🔕 **Ignore**: Close this PR and you won't be reminded about this updateagain.—- [ ] <!– rebase-check –>If you want to rebase/retry this PR, checkthis box—This PR was generated by [Mend Renovate](https://mend.io/renovate/).View the [repository joblog](https://developer.mend.io/github/FlutterGen/flutter_gen).<!–renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yNTkuMiIsInVwZGF0ZWRJblZlciI6IjQ0LjExLjQiLCJ0YXJnZXRCcmFuY2giOiJtYWluIiwibGFiZWxzIjpbXX0=–>Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> , GitHub upgrade: update pnpm to v11.17.0 (#776)> ℹ️ **Note**> > This PR body was truncated due to platform limits.This PR contains the following updates:| Package | Change |[Age](https://docs.renovatebot.com/merge-confidence/) |[Confidence](https://docs.renovatebot.com/merge-confidence/) ||—|—|—|—|| [pnpm](https://pnpm.io)([source](https://redirect.github.com/pnpm/pnpm/tree/HEAD/pnpm11/pnpm))| [`11.9.0` →`11.17.0`](https://renovatebot.com/diffs/npm/pnpm/11.9.0/11.17.0) |||—### Release Notes<details><summary>pnpm/pnpm (pnpm)</summary>###[`v11.17.0`](https://redirect.github.com/pnpm/pnpm/releases/tag/v11.17.0):pnpm 11.17[CompareSource](https://redirect.github.com/pnpm/pnpm/compare/v11.16.0…v11.17.0)##### Minor Changes- Added a new setting, `update.githubActionsServer`, for specifying thebase URL of the GitHub server that hosts the repositories of the GitHubActions referenced by the workflow files (for example, a GitHubEnterprise Server). When the setting is not defined, the URL is readfrom the `GITHUB_SERVER_URL` environment variable, falling back to`https://github.com`. The URL must use the `https://` or `http://`protocol[#13220](https://redirect.github.com/pnpm/pnpm/issues/13220).`pnpm outdated` and `pnpm update` no longer fail when the refs of aGitHub Action's repository cannot be read (for example, when theaction's repository is private or hosted on a different GitHub server).Such actions are now skipped with a warning.Setting `update.githubActions` to `false` now makes `pnpm outdated` andthe interactive `pnpm update` skip GitHub Actions dependencies.##### Patch Changes- The token poll for web-based authentication no longer reads the bodyof non-OK or still-pending (HTTP 202) responses, and caps the tokenresponse body it does read at 64 KiB, so a malicious or compromisedregistry cannot exhaust memory through the poll[pnpm/pnpm#12721](https://redirect.github.com/pnpm/pnpm/issues/12721).- Fixed `catalog:` references in dependencies and overrides failing toresolve when installing through a pnpr server, which errored with "Nocatalog entry '<name>' was found for catalog 'default'." even though thecatalog entry existed. Also fixed a crash on Windows when installing anested workspace member (e.g. `packages/foo`) through a pnpr server[#13232](https://redirect.github.com/pnpm/pnpm/issues/13232).- Republished every package: the tarballs published by the v11.13.1through v11.16.0 releases were missing most of their compiled files dueto a packing bug[#13164](https://redirect.github.com/pnpm/pnpm/issues/13164).- Revert script ordering change for `pnpm run –sequential /regex/`- Support the `from-git` argument in the `pnpm version` command.- When the authentication URL cannot be rendered as a QR code (forexample when it exceeds the maximum QR data capacity), web-based loginnow displays the URL alone with a warning instead of abortingauthentication[pnpm/pnpm#12721](https://redirect.github.com/pnpm/pnpm/issues/12721).<!– sponsors –>##### Platinum Sponsors<table> <tbody> <tr> <td align="center" valign="middle"><a href="https://bit.cloud/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"><imgsrc="https://pnpm.io/img/users/bit.svg" width="80" alt="Bit"></a> </td> </tr> <tr> <td align="center" valign="middle"><a href="https://openai.com/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/openai_dark.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/openai_light.svg" /><img src="https://pnpm.io/img/users/openai_dark.svg" width="160"alt="OpenAI" /> </picture> </a> </td> </tr> </tbody></table>##### Gold Sponsors<table> <tbody> <tr> <td align="center" valign="middle"><a href="https://sanity.io/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/sanity.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/sanity_light.svg" /><img src="https://pnpm.io/img/users/sanity.svg" width="120" alt="Sanity"/> </picture> </a> </td> <td align="center" valign="middle"><a href="https://discord.com/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/discord.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/discord_light.svg" /><img src="https://pnpm.io/img/users/discord.svg" width="220"alt="Discord" /> </picture> </a> </td> <td align="center" valign="middle"><a href="https://vite.dev/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"><imgsrc="https://pnpm.io/img/users/vitejs.svg" width="42" alt="Vite"></a> </td> </tr> <tr> <td align="center" valign="middle"><a href="https://serpapi.com/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/serpapi_dark.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/serpapi_light.svg" /><img src="https://pnpm.io/img/users/serpapi_dark.svg" width="160"alt="SerpApi" /> </picture> </a> </td> <td align="center" valign="middle"><ahref="https://coderabbit.ai/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/coderabbit.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/coderabbit_light.svg" /><img src="https://pnpm.io/img/users/coderabbit.svg" width="220"alt="CodeRabbit" /> </picture> </a> </td> <td align="center" valign="middle"><ahref="https://stackblitz.com/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/stackblitz.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/stackblitz_light.svg" /><img src="https://pnpm.io/img/users/stackblitz.svg" width="190"alt="Stackblitz" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"><a href="https://workleap.com/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/workleap.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/workleap_light.svg" /><img src="https://pnpm.io/img/users/workleap.svg" width="190"alt="Workleap" /> </picture> </a> </td> <td align="center" valign="middle"><a href="https://nx.dev/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/nx.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/nx_light.svg" /><img src="https://pnpm.io/img/users/nx.svg" width="50" alt="Nx" /> </picture> </a> </td> </tr> </tbody></table><!– sponsors end –>###[`v11.16.0`](https://redirect.github.com/pnpm/pnpm/releases/tag/v11.16.0):pnpm 11.16[CompareSource](https://redirect.github.com/pnpm/pnpm/compare/v11.15.1…v11.16.0)#### Minor Changes- The first release of a package now publishes the version written inits manifest verbatim, instead of bumping off it. `pnpm version -r` and`pnpm change status` check the registry for each release's currentversion; when that version is not yet published, the package debuts atit and its pending changesets apply only from the next release. A newlyadded package seeded at `1100.0.0` with a `minor` changeset is thereforepublished as `1100.0.0` rather than skipping straight to `1100.1.0`.- Added a `–changeset` flag to `pnpm update`. Set `update.changeset` to`true` in `pnpm-workspace.yaml` to enable this behavior by default, anduse `–no-changeset` to override the setting for one update. After theupdate completes, pnpm writes a `.changeset/pnpm-update-<suffix>.md`file declaring a patch bump for every workspace package whose`dependencies` or `optionalDependencies` were changed by the update anda major bump when `peerDependencies` changed, including packages thatconsume an updated catalog entry via the `catalog:` protocol. Privatepackages, packages without a name, and packages listed in the `ignore`array of `.changeset/config.json` are skipped. If`.changeset/config.json` does not exist, a warning is printed and nochangeset is generated.- Added GitHub Actions dependencies to `pnpm outdated` and interactive`pnpm update`. Non-interactive updates can include them with`–include-github-actions` or by setting `update.githubActions` to`true` in `pnpm-workspace.yaml`. Updated actions are pinned to exactcommit hashes with their release tags preserved in comments.- Added `update` and `audit` settings sections to `pnpm-workspace.yaml`,superseding the awkwardly named `updateConfig`, `auditConfig`, andtop-level `auditLevel` settings: “`yaml update: ignoreDeps: # was updateConfig.ignoreDependencies – webpack – "@babel/*" audit: level: high # was auditLevel ignore: # was auditConfig.ignoreGhsas – GHSA-xxxx-yyyy-zzzz ““update.ignoreDeps` lists dependency name patterns that `pnpm update`and `pnpm outdated` should skip. `audit.level` and `audit.ignore` tune`pnpm audit`.The deprecated `updateConfig`, `auditConfig`, and `auditLevel` settingskeep working until the next major version. When both a new section valueand its deprecated counterpart are set, the new section takes precedenceand a warning is printed. Both the TypeScript CLI and the Rust configsurface (pacquet) recognize the new sections.#### Patch Changes- Fixed `pnpm add –save-exact`/`–save-prefix` and `pnpm update`writing a package's version with the `peerDependencies` range's prefix(e.g. `^19.2.7` instead of the requested `19.2.7`) whenever the samepackage also appeared in `peerDependencies`. A real`dependencies`/`devDependencies`/`optionalDependencies` entry now takesprecedence over a same-named `peerDependencies` entry when computing thecurrent specifiers[#13108](https://redirect.github.com/pnpm/pnpm/issues/13108).<!– sponsors –>#### Platinum Sponsors<table> <tbody> <tr> <td align="center" valign="middle"><a href="https://bit.cloud/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"><imgsrc="https://pnpm.io/img/users/bit.svg" width="80" alt="Bit"></a> </td> </tr> <tr> <td align="center" valign="middle"><a href="https://openai.com/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/openai_dark.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/openai_light.svg" /><img src="https://pnpm.io/img/users/openai_dark.svg" width="160"alt="OpenAI" /> </picture> </a> </td> </tr> </tbody></table>#### Gold Sponsors<table> <tbody> <tr> <td align="center" valign="middle"><a href="https://sanity.io/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/sanity.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/sanity_light.svg" /><img src="https://pnpm.io/img/users/sanity.svg" width="120" alt="Sanity"/> </picture> </a> </td> <td align="center" valign="middle"><a href="https://discord.com/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/discord.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/discord_light.svg" /><img src="https://pnpm.io/img/users/discord.svg" width="220"alt="Discord" /> </picture> </a> </td> <td align="center" valign="middle"><a href="https://vite.dev/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"><imgsrc="https://pnpm.io/img/users/vitejs.svg" width="42" alt="Vite"></a> </td> </tr> <tr> <td align="center" valign="middle"><a href="https://serpapi.com/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/serpapi_dark.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/serpapi_light.svg" /><img src="https://pnpm.io/img/users/serpapi_dark.svg" width="160"alt="SerpApi" /> </picture> </a> </td> <td align="center" valign="middle"><ahref="https://coderabbit.ai/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/coderabbit.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/coderabbit_light.svg" /><img src="https://pnpm.io/img/users/coderabbit.svg" width="220"alt="CodeRabbit" /> </picture> </a> </td> <td align="center" valign="middle"><ahref="https://stackblitz.com/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/stackblitz.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/stackblitz_light.svg" /><img src="https://pnpm.io/img/users/stackblitz.svg" width="190"alt="Stackblitz" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"><a href="https://workleap.com/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/workleap.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/workleap_light.svg" /><img src="https://pnpm.io/img/users/workleap.svg" width="190"alt="Workleap" /> </picture> </a> </td> <td align="center" valign="middle"><a href="https://nx.dev/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/nx.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/nx_light.svg" /><img src="https://pnpm.io/img/users/nx.svg" width="50" alt="Nx" /> </picture> </a> </td> </tr> </tbody></table><!– sponsors end –>###[`v11.15.1`](https://redirect.github.com/pnpm/pnpm/compare/v11.15.0…v11.15.1)[CompareSource](https://redirect.github.com/pnpm/pnpm/compare/v11.15.0…v11.15.1)###[`v11.15.0`](https://redirect.github.com/pnpm/pnpm/releases/tag/v11.15.0):pnpm 11.15[CompareSource](https://redirect.github.com/pnpm/pnpm/compare/v11.14.0…v11.15.0)##### Minor Changes- Optional peer dependencies declared only via `peerDependenciesMeta`(for example `debug`'s `supports-color` peer) are now resolved from asatisfying version already present in the dependency graph, the same wayexplicitly declared optional peer dependencies are. Previously suchpeers were only resolved this way when the package's metadata was readback from the lockfile, so an unrelated dependency change could rewritepeer resolutions across the whole lockfile.##### Patch Changes- Updated `adm-zip` to prevent crafted ZIP archives from causingexcessive memory allocation.- `pnpm version -r` no longer writes a versioning-ledger entry with noconsumed intents as a bare `intents:` key, which the next run failed toread with `ERR_PNPM_INVALID_VERSIONING_LEDGER`. Empty intent lists arenow written as `intents: []`, and the ledger reader accepts the bareform left by earlier releases.- Fixed pnpr workspace resolution to preserve project names and versionsfor `workspace:` dependencies.<!– sponsors –>#### Platinum Sponsors<table> <tbody> <tr> <td align="center" valign="middle"><a href="https://bit.cloud/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"><imgsrc="https://pnpm.io/img/users/bit.svg" width="80" alt="Bit"></a> </td> </tr> <tr> <td align="center" valign="middle"><a href="https://openai.com/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/openai_dark.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/openai_light.svg" /><img src="https://pnpm.io/img/users/openai_dark.svg" width="160"alt="OpenAI" /> </picture> </a> </td> </tr> </tbody></table>#### Gold Sponsors<table> <tbody> <tr> <td align="center" valign="middle"><a href="https://sanity.io/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/sanity.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/sanity_light.svg" /><img src="https://pnpm.io/img/users/sanity.svg" width="120" alt="Sanity"/> </picture> </a> </td> <td align="center" valign="middle"><a href="https://discord.com/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/discord.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/discord_light.svg" /><img src="https://pnpm.io/img/users/discord.svg" width="220"alt="Discord" /> </picture> </a> </td> <td align="center" valign="middle"><a href="https://vite.dev/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"><imgsrc="https://pnpm.io/img/users/vitejs.svg" width="42" alt="Vite"></a> </td> </tr> <tr> <td align="center" valign="middle"><a href="https://serpapi.com/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/serpapi_dark.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/serpapi_light.svg" /><img src="https://pnpm.io/img/users/serpapi_dark.svg" width="160"alt="SerpApi" /> </picture> </a> </td> <td align="center" valign="middle"><ahref="https://coderabbit.ai/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/coderabbit.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/coderabbit_light.svg" /><img src="https://pnpm.io/img/users/coderabbit.svg" width="220"alt="CodeRabbit" /> </picture> </a> </td> <td align="center" valign="middle"><ahref="https://stackblitz.com/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/stackblitz.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/stackblitz_light.svg" /><img src="https://pnpm.io/img/users/stackblitz.svg" width="190"alt="Stackblitz" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"><a href="https://workleap.com/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/workleap.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/workleap_light.svg" /><img src="https://pnpm.io/img/users/workleap.svg" width="190"alt="Workleap" /> </picture> </a> </td> <td align="center" valign="middle"><a href="https://nx.dev/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/nx.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/nx_light.svg" /><img src="https://pnpm.io/img/users/nx.svg" width="50" alt="Nx" /> </picture> </a> </td> </tr> </tbody></table><!– sponsors end –>###[`v11.14.0`](https://redirect.github.com/pnpm/pnpm/releases/tag/v11.14.0):pnpm 11.14[CompareSource](https://redirect.github.com/pnpm/pnpm/compare/v11.13.1…v11.14.0)#### Minor Changes- `peerDependencies` now accept dependency specifiers that carry ascheme — a named-registry spec (`<registry>:<version>`), an `npm:`alias, or a `file:`/git/URL spec — instead of rejecting them with`ERR_PNPM_INVALID_PEER_DEPENDENCY_SPECIFICATION`[#13095](https://redirect.github.com/pnpm/pnpm/issues/13095).Such a peer is matched against the semver range carried by the specifier(`work:5.x.x` is checked as `5.x.x`, `npm:bar@^5` as `^5`), or against`*` when it carries no version, while the original specifier stillselects the package to auto-install. Bare `name@version` values, whichare almost always a mistake, are still rejected.- Added `pnpm doctor`, which diagnoses the pnpm installation and theenvironment it runs in: the versions and install method, whether theglobal bin directory is on `PATH`, whether the store and cache arewritable, which link strategies (reflink, hardlink, symlink) the store'sfilesystem supports, registry connectivity, and an offline `file:`install that exercises the resolve/store/link path end to end. Eachcheck reports how to fix what it finds, and the command exits non-zerowhen any check fails.Use `–offline` to skip the checks that need network access, `–json`for machine-readable output, and `–benchmark` to time the filesystemand install checks.- Added support for executing multiple scripts matching a RegExp passedto `pnpm run` (e.g., `pnpm run "/^build:.*/"`), running matched scriptsin deterministic lexicographical order. Restored the `–sequential`(`-s`) CLI option for `pnpm run`, which forces `workspaceConcurrency` to1 so that matched scripts run sequentially one by one across and withinpackages.#### Patch Changes- Fixed `pnpm install` failing with `ERR_PNPM_LOCKFILE_IS_SYMLINK` when`pnpm-lock.yaml` is a symlink, as build sandboxes such as Bazel and Nixstage it[#13073](https://redirect.github.com/pnpm/pnpm/issues/13073).Reading a lockfile through a symlink is allowed again, and an installthat leaves the lockfile unchanged no longer rewrites it, so`–frozen-lockfile` no longer needs to write at all. Writing a *changed*lockfile through a symlink is still refused, as that would redirect thewrite onto the symlink's target.- Fixed frozen installs incorrectly treating equivalent Git dependencyspecifiers as a stale lockfile. See[#13039](https://redirect.github.com/pnpm/pnpm/issues/13039).- `pnpm owner ls` now reports authentication and authorization failures(401/403) as dedicated errors that include the registry's response body,matching `pnpm owner add`/`rm`, instead of a generic `Failed to fetchowners` message.- Recover from a metadata cache entry that disappears (concurrent cachecleanup, antivirus) after the registry has already answered theconditional request with `304 Not Modified`. The metadata isre-requested once without cache validators instead of failing theinstall with `ERR_PNPM_CACHE_MISSING_AFTER_304`.- A project pinned to a broken pnpm release via `packageManager` or`devEngines.packageManager` now reports which release is broken and whatto do about it, instead of failing inside the installer. `pnpmself-update` already refused these releases; the version switch doestoo.- Prevent broken-lockfile errors from including snippets of thelockfile's contents.- `pnpm self-update` now checks that the version it installed can runbefore making it the active pnpm. A release that installs but cannotexecute is discarded with an error instead of replacing a workinginstallation.- Fixed an out-of-memory regression when workspace projects concurrentlyresolve a package with large registry metadata[pnpm/pnpm#13077](https://redirect.github.com/pnpm/pnpm/issues/13077).- Fixed `pnpm update` rewriting exact version pins that use the `=`operator (for example `=3.5.1`) to a caret range (`^3.5.1`). Exact pinsare now preserved and written back as the bare version. See[#12745](https://redirect.github.com/pnpm/pnpm/issues/12745).<!– sponsors –>#### Platinum Sponsors<table> <tbody> <tr> <td align="center" valign="middle"><a href="https://bit.cloud/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"><imgsrc="https://pnpm.io/img/users/bit.svg" width="80" alt="Bit"></a> </td> </tr> <tr> <td align="center" valign="middle"><a href="https://openai.com/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/openai_dark.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/openai_light.svg" /><img src="https://pnpm.io/img/users/openai_dark.svg" width="160"alt="OpenAI" /> </picture> </a> </td> </tr> </tbody></table>#### Gold Sponsors<table> <tbody> <tr> <td align="center" valign="middle"><a href="https://sanity.io/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/sanity.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/sanity_light.svg" /><img src="https://pnpm.io/img/users/sanity.svg" width="120" alt="Sanity"/> </picture> </a> </td> <td align="center" valign="middle"><a href="https://discord.com/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/discord.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/discord_light.svg" /><img src="https://pnpm.io/img/users/discord.svg" width="220"alt="Discord" /> </picture> </a> </td> <td align="center" valign="middle"><a href="https://vite.dev/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"><imgsrc="https://pnpm.io/img/users/vitejs.svg" width="42" alt="Vite"></a> </td> </tr> <tr> <td align="center" valign="middle"><a href="https://serpapi.com/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/serpapi_dark.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/serpapi_light.svg" /><img src="https://pnpm.io/img/users/serpapi_dark.svg" width="160"alt="SerpApi" /> </picture> </a> </td> <td align="center" valign="middle"><ahref="https://coderabbit.ai/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/coderabbit.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/coderabbit_light.svg" /><img src="https://pnpm.io/img/users/coderabbit.svg" width="220"alt="CodeRabbit" /> </picture> </a> </td> <td align="center" valign="middle"><ahref="https://stackblitz.com/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/stackblitz.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/stackblitz_light.svg" /><img src="https://pnpm.io/img/users/stackblitz.svg" width="190"alt="Stackblitz" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"><a href="https://workleap.com/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/workleap.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/workleap_light.svg" /><img src="https://pnpm.io/img/users/workleap.svg" width="190"alt="Workleap" /> </picture> </a> </td> <td align="center" valign="middle"><a href="https://nx.dev/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/nx.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/nx_light.svg" /><img src="https://pnpm.io/img/users/nx.svg" width="50" alt="Nx" /> </picture> </a> </td> </tr> </tbody></table><!– sponsors end –>###[`v11.13.1`](https://redirect.github.com/pnpm/pnpm/releases/tag/v11.13.1):pnpm 11.13.1[CompareSource](https://redirect.github.com/pnpm/pnpm/compare/v11.13.0…v11.13.1)#### Patch Changes- Fixed `pnpm pack` applying workspace-root ignore rules when aworkspace package has its own `.npmignore` file.- Keep the interactive `minimumReleaseAge` approval prompt visibleduring `pnpm install`. The progress reporter now pauses its redrawswhile a prompt is waiting for input instead of overwriting it, so theinstall no longer hangs on a question the user cannot see[#13019](https://redirect.github.com/pnpm/pnpm/issues/13019).- Fixed `pnpm self-update` failing to link native platform binariesstored in sibling global virtual store slots.###[`v11.13.0`](https://redirect.github.com/pnpm/pnpm/releases/tag/v11.13.0):pnpm 11.13[CompareSource](https://redirect.github.com/pnpm/pnpm/compare/v11.12.0…v11.13.0)#### Minor Changes- Added `versioning.epics` to `pnpm-workspace.yaml`. An epic ties agroup of member packages to a lead package, constraining every member'smajor version to a band derived from the lead's major: while the lead ison major `M`, members live in `M*100 … M*100+99`. Members moveindependently inside the band (patch, minor, and a `major` intent thatstays in-band); a bump that would carry a member past the band ceilingis rejected until the lead advances its own major. When a release plantakes the lead to a new stable major, every member re-bases to the bandfloor in the same plan. Membership is matched with pnpm's packageselectors — name globs, `./`-prefixed directory globs, and `!`-prefixednegations.- Added the `team` command for managing organization teams and teammemberships on the registry, with create, destroy, add, rm, and lssubcommands and support for –otp, –parseable, and –json flags.- Added native workspace release management[#12952](https://redirect.github.com/pnpm/pnpm/issues/12952): thenew `pnpm change` command records change intents aschangesets-compatible `.changeset/*.md` files (`pnpm change status`shows the pending release plan), and the bare `pnpm version -r` consumesthem — bumping versions across the workspace with dependent propagationthrough `workspace:` ranges, fixed groups, a `maxBump` cap, `–filter`narrowing, and `–dry-run` — writing changelogs, and recording consumedintents in a committed ledger that keeps cherry-picks and merge-backsbetween release branches safe. Packages can be moved onto per-packagerelease lanes with the new `pnpm lane <name> –filter <pkg>` command andback with `pnpm lane main –filter <pkg>` (`pnpm lane` shows themembership), releasing `X.Y.Z-lane.N` prereleases from the same runsthat release stable versions of the packages on the main lane.Configuration lives under the new `versioning` key of`pnpm-workspace.yaml` (`fixed`, `ignore`, `maxBump`, `lanes`,`changelog`). When two workspace projects publish the same name, intentfiles, `versioning.lanes`, and `versioning.fixed`/`ignore` may referencea project by its workspace-relative directory path (e.g.`"./pnpm/npm/pnpm"`) — the one additive extension to the changesetsformat, applied automatically by `pnpm change`.Release changelogs default to `registry` storage(`versioning.changelog.storage`): no `CHANGELOG.md` is committed. Eachrelease's section is composed at publish time and packed into thepublished tarball on top of the previously published version'schangelog, and the consumed change intents are garbage-collected by alater `pnpm version -r` only once the registry confirms the version ispublished with its section. Set `versioning.changelog.storage:repository` to keep committed `CHANGELOG.md` files instead.- Added a new override selector form with an empty range — `"pkg@":"<version>"` — called a convergence override. It rewrites a dependencyedge only when its exact version satisfies the edge's declared range, socompatible consumers converge on one version while incompatibleconsumers keep their own resolution — now and for any dependent added inthe future[#12794](https://redirect.github.com/pnpm/pnpm/issues/12794). “`yaml overrides: "form-data@": 4.0.6 “`The value must be an exact version. When a full resolution detects thatevery declared range also admits a newer version, pnpm warns that theoverride is stale and names the version to converge on. Previously anempty range in an override selector was undocumented and behaved like abare (unscoped) override.#### Patch Changes- A `tokenHelper` set in the global pnpm `auth.ini` is no longerrejected as project-level configuration. The guard that blocks`tokenHelper` from a project `.npmrc` only treated `~/.npmrc` as atrusted source, so a helper written to `auth.ini` (for example by `pnpmconfig set`) failed on every command and could not even be removed with`pnpm config delete`. A `tokenHelper` in a workspace or project `.npmrc`is still rejected.- `pnpm cache delete` now removes a package's metadata from everymetadata cache directory (`metadata`, `metadata-full`, and`metadata-full-filtered`), instead of only the one the currentresolution mode reads. Previously a package cached under a differentmode (e.g. `metadata-full-filtered`) was left behind. Closes[#12753](https://redirect.github.com/pnpm/pnpm/issues/12753).- Fixed an injected workspace dependency (`injectWorkspacePackages:true`) incorrectly staying as `file:` instead of deduping back to`link:` when an unrelated, ordinary shared dependency resolved to apeer-suffixed variant for the target project's own copy but not for theinjected occurrence. See[#10433](https://redirect.github.com/pnpm/pnpm/issues/10433).- `pnpm deploy` now supports workspaces that use catalogs.- Fixed `pnpm deploy` with a shared lockfile so local `file:` tarballdependencies keep their package name in the generated deploy lockfile.This prevents warm-store deploys from failing with`ERR_PNPM_UNEXPECTED_PKG_CONTENT_IN_STORE` when the tarball filenameincludes the version.- Options that follow `create`, `exec`, or `test` appearing as asubcommand of another command are now parsed instead of being silentlytreated as positional parameters. For example, `pnpm team create@org:team –registry <url>` previously ignored the `–registry` optionand sent the request to the default registry.- `pnpm add -g`, `pnpm update -g`, `pnpm setup`, and the self-updater nolonger fail with `ERR_PNPM_MISSING_TIME` when `trustPolicy:no-downgrade` or `resolutionMode: time-based` is set in the globalconfig[#12883](https://redirect.github.com/pnpm/pnpm/issues/12883). Thedecision to fetch full registry metadata now lives in one place, and the`no-downgrade` trust policy always requests full metadata (matching theself-updater), since the trust evidence it checks is missing fromabbreviated metadata even on registries that include the `time` field.- `pnpm list` and `pnpm why` no longer crash with `EMFILE: too many openfiles` when a project has a large number of unsaved dependencies(packages present in `node_modules` but not in the lockfile). The readsof those packages are now concurrency-limited.- The published `pnpm` package no longer declares `dependencies` or`devDependencies`. Because the CLI bundles its runtime dependencies into`dist/node_modules`, those fields are dropped when packing, so `npminstall` of the tarball no longer tries to resolve internal-onlypackages such as `@pnpm/test-ipc-server`. Closes[#12955](https://redirect.github.com/pnpm/pnpm/issues/12955).- Fixed `pnpm publish –otp` and `pnpm publish –batch –otp` to sendthe configured OTP to the registry.- `pnpm publish` again sends the package's README to the registry asmetadata, so registries can render it on the package page. The readme isalways included in the published metadata (matching the npm CLI), whilethe `embed-readme` setting continues to control only whether the readmeis written into the `package.json` inside the tarball. This restores thebehavior that was lost when publishing became fully native. Closes[#12966](https://redirect.github.com/pnpm/pnpm/issues/12966).- Fixed the dependency status check wrongly reporting "up to date" whena `package.json`, `.pnpmfile.cjs`, or patch file was edited in the samesecond as the previous install, on filesystems that record mtimes atwhole-second resolution (for example ext4 with 128-byte inodes). Theoptimistic repeat-install fast path and `verify-deps-before-run`compared mtimes strictly, so a same-second edit whose mtime rounded downlooked unchanged and re-resolution was skipped. Such a file's wholesecond is now treated as possibly-modified, falling through to thecontent check; behavior on sub-second filesystems is unchanged.- Retry package metadata requests when a registry or proxy returns `304Not Modified` to an unconditional request, preventing false`ERR_PNPM_CACHE_MISSING_AFTER_304` failures[pnpm/pnpm#12882](https://redirect.github.com/pnpm/pnpm/issues/12882).If the retry also returns `304`, report`ERR_PNPM_META_NOT_MODIFIED_WITHOUT_CACHE` instead.- Fixed `pnpm update` removing transitive lockfile entries when`dedupePeerDependents` is disabled and the selected package is absent[pnpm/pnpm#12456](https://redirect.github.com/pnpm/pnpm/issues/12456).- Limit modern deploy lockfiles and localized virtual stores todependencies reachable from the selected dependency groups.- A `tokenHelper` command is now given a 60-second time limit. A helperthat hangs (deadlock, stuck I/O) is killed and reported as an errorinstead of leaving the command waiting forever.- Fixed orphaned child processes on Windows when pnpm exits on an errorwhile commands spawned by `pnpm exec` or `pnpm dlx` are still running(for example, when one project's command fails during `pnpm –recursiveexec`). The PIDs of these commands are now recorded when they arespawned and their whole process trees are terminated with `taskkill` onan error exit. Previously the cleanup relied on enumerating the systemprocess list, which is so slow on Windows that the enumeration hit itstimeout and the cleanup was silently skipped[#12406](https://redirect.github.com/pnpm/pnpm/issues/12406).- `pnpm pack` now respects workspace-root `.npmignore` and `.gitignore`files when packing workspace packages.<!– sponsors –>#### Platinum Sponsors<table> <tbody> <tr> <td align="center" valign="middle"><a href="https://bit.cloud/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"><imgsrc="https://pnpm.io/img/users/bit.svg" width="80" alt="Bit"></a> </td> </tr> <tr> <td align="center" valign="middle"><a href="https://openai.com/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/openai_dark.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/openai_light.svg" /><img src="https://pnpm.io/img/users/openai_dark.svg" width="160"alt="OpenAI" /> </picture> </a> </td> </tr> </tbody></table>#### Gold Sponsors<table> <tbody> <tr> <td align="center" valign="middle"><a href="https://sanity.io/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/sanity.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/sanity_light.svg" /><img src="https://pnpm.io/img/users/sanity.svg" width="120" alt="Sanity"/> </picture> </a> </td> <td align="center" valign="middle"><a href="https://discord.com/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/discord.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/discord_light.svg" /><img src="https://pnpm.io/img/users/discord.svg" width="220"alt="Discord" /> </picture> </a> </td> <td align="center" valign="middle"><a href="https://vite.dev/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"><imgsrc="https://pnpm.io/img/users/vitejs.svg" width="42" alt="Vite"></a> </td> </tr> <tr> <td align="center" valign="middle"><a href="https://serpapi.com/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/serpapi_dark.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/serpapi_light.svg" /><img src="https://pnpm.io/img/users/serpapi_dark.svg" width="160"alt="SerpApi" /> </picture> </a> </td> <td align="center" valign="middle"><ahref="https://coderabbit.ai/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/coderabbit.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/coderabbit_light.svg" /><img src="https://pnpm.io/img/users/coderabbit.svg" width="220"alt="CodeRabbit" /> </picture> </a> </td> <td align="center" valign="middle"><ahref="https://stackblitz.com/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/stackblitz.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/stackblitz_light.svg" /><img src="https://pnpm.io/img/users/stackblitz.svg" width="190"alt="Stackblitz" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"><a href="https://workleap.com/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/workleap.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/workleap_light.svg" /><img src="https://pnpm.io/img/users/workleap.svg" width="190"alt="Workleap" /> </picture> </a> </td> <td align="center" valign="middle"><a href="https://nx.dev/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/nx.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/nx_light.svg" /><img src="https://pnpm.io/img/users/nx.svg" width="50" alt="Nx" /> </picture> </a> </td> </tr> </tbody></table><!– sponsors end –>###[`v11.12.0`](https://redirect.github.com/pnpm/pnpm/releases/tag/v11.12.0):pnpm 11.12[CompareSource](https://redirect.github.com/pnpm/pnpm/compare/v11.11.0…v11.12.0)#### Minor Changes- [`a897ef7`](https://redirect.github.com/pnpm/pnpm/commit/a897ef7):Custom fetchers exported from a pnpmfile can now delegate by returning a`{ delegate: <resolution> }` envelope: pnpm rewrites the package'sresolution to the delegated shape and runs the built-in fetcher on it.This is the portable delegation form that also works in pacquet, where`cafs` and `fetchers` cannot be passed to the hook. Related to[pnpm/pnpm#11685](https://redirect.github.com/pnpm/pnpm/issues/11685).#### Patch Changes- [`2b02764`](https://redirect.github.com/pnpm/pnpm/commit/2b02764): Thechanged-packages filter (`–filter "…[<since>]"`) no longer allows anoption-like `<since>` value (such as `–output=<path>`) to beinterpreted as a git option — git now rejects it as a bad revision. Therepository root is also resolved to the nearest `.git` entry, so thefilter works in a git worktree checked out inside another repository'stree.- [`43711ce`](https://redirect.github.com/pnpm/pnpm/commit/43711ce):`pnpm outdated` no longer checks the registry for dependencies that areresolved from local `link:`, `file:`, or `workspace:` references in thelockfile[#12827](https://redirect.github.com/pnpm/pnpm/issues/12827).- [`3c6718b`](https://redirect.github.com/pnpm/pnpm/commit/3c6718b):Fixed a deadlock in peer dependency resolution: `pnpm install` hungforever when a peer dependency cycle spanned a project's owndependencies and auto-installed peer providers, for example wheninstalling `electron-builder@26.15.3`[#12921](https://redirect.github.com/pnpm/pnpm/issues/12921).- [`252f15e`](https://redirect.github.com/pnpm/pnpm/commit/252f15e):Fixed peer dependency auto-install picking a version the peer rangerejects. In a workspace with several projects, a package declaring apeer dependency with a semver range (for example `^1.0.0`) could get thehighest version found anywhere in the workspace (for example a `2.0.0`resolved for another project) instead of a version that satisfies therange. Peers are now deduplicated onto the highest preferred versionthat satisfies the declared range, and when none does, the range isresolved from the registry.Also fixed re-resolving with an existing lockfile hoisting a differentpeer version than a fresh install of the same manifest: rootdependencies reused from the lockfile were invisible to peer hoisting,so a peer that a root dependency provides could be bound to anotherversion.- [`a38adda`](https://redirect.github.com/pnpm/pnpm/commit/a38adda):`pnpm self-update <version>` now installs the requested pnpm versionwhen it matches the currently running version but is missing from theglobal self-update directory.- [`6a85968`](https://redirect.github.com/pnpm/pnpm/commit/6a85968):`pnpm stage list` now stops paginating after a fail-safe cap of 1000pages, so a misbehaving registry cannot keep the command loopingforever.- [`eee7c9a`](https://redirect.github.com/pnpm/pnpm/commit/eee7c9a):`verify-deps-before-run` no longer spawns a `pnpm install` when pnpm isexecuted in a directory that has no `package.json`. A mistyped commandrun outside a project (for example `pnpm witch 10 login`) used to crashwith a confusing error from the spawned install; now it fails with theregular "no package.json found" error.<!– sponsors –>#### Platinum Sponsors<table> <tbody> <tr> <td align="center" valign="middle"><a href="https://bit.cloud/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"><imgsrc="https://pnpm.io/img/users/bit.svg" width="80" alt="Bit"></a> </td> </tr> <tr> <td align="center" valign="middle"><a href="https://openai.com/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/openai_dark.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/openai_light.svg" /><img src="https://pnpm.io/img/users/openai_dark.svg" width="160"alt="OpenAI" /> </picture> </a> </td> </tr> </tbody></table>#### Gold Sponsors<table> <tbody> <tr> <td align="center" valign="middle"><a href="https://sanity.io/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/sanity.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/sanity_light.svg" /><img src="https://pnpm.io/img/users/sanity.svg" width="120" alt="Sanity"/> </picture> </a> </td> <td align="center" valign="middle"><a href="https://discord.com/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/discord.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/discord_light.svg" /><img src="https://pnpm.io/img/users/discord.svg" width="220"alt="Discord" /> </picture> </a> </td> <td align="center" valign="middle"><a href="https://vite.dev/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"><imgsrc="https://pnpm.io/img/users/vitejs.svg" width="42" alt="Vite"></a> </td> </tr> <tr> <td align="center" valign="middle"><a href="https://serpapi.com/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/serpapi_dark.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/serpapi_light.svg" /><img src="https://pnpm.io/img/users/serpapi_dark.svg" width="160"alt="SerpApi" /> </picture> </a> </td> <td align="center" valign="middle"><ahref="https://coderabbit.ai/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/coderabbit.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/coderabbit_light.svg" /><img src="https://pnpm.io/img/users/coderabbit.svg" width="220"alt="CodeRabbit" /> </picture> </a> </td> <td align="center" valign="middle"><ahref="https://stackblitz.com/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/stackblitz.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/stackblitz_light.svg" /><img src="https://pnpm.io/img/users/stackblitz.svg" width="190"alt="Stackblitz" /> </picture> </a> </td> </tr> <tr> <td align="center" valign="middle"><a href="https://workleap.com/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/workleap.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/workleap_light.svg" /><img src="https://pnpm.io/img/users/workleap.svg" width="190"alt="Workleap" /> </picture> </a> </td> <td align="center" valign="middle"><a href="https://nx.dev/?utm_source=pnpm&utm_medium=release_notes"target="_blank" rel="noopener noreferrer"> <picture><source media="(prefers-color-scheme: light)"srcset="https://pnpm.io/img/users/nx.svg" /><source media="(prefers-color-scheme: dark)"srcset="https://pnpm.io/img/users/nx_light.svg" /><img src="https://pnpm.io/img/users/nx.svg" width="50" alt="Nx" /> </picture> </a> </td> </tr> </tbody></table><!– sponsors end –>###[`v11.11.0`](https://redirect.github.com/pnpm/pnpm/blob/HEAD/pnpm11/pnpm/CHANGELOG.md#11110)[CompareSource](https://redirect.github.com/pnpm/pnpm/compare/v11.10.0…v11.11.0)##### Minor Changes- [`508b8c2`](https://redirect.github.com/pnpm/pnpm/commit/508b8c2):Added the `pnpm access` command for managing package access andvisibility on the registry, supporting listing packages andcollaborators, getting and setting package status and MFA requirements,and granting or revoking team access.##### Patch Changes- [`c70e33e`](ht> ✂ **Note**> > PR body was truncated to here.</details>—### Configuration📅 **Schedule**: (in timezone Asia/Tokyo)- Branch creation – Only on Wednesday (`* * * * 3`)- Automerge – At any time (no schedule defined)🚦 **Automerge**: Disabled by config. Please merge this manually once youare satisfied.♻ **Rebasing**: Whenever PR is behind base branch, or you tick therebase/retry checkbox.🔕 **Ignore**: Close this PR and you won't be reminded about this updateagain.—- [ ] <!– rebase-check –>If you want to rebase/retry this PR, checkthis box—This PR was generated by [Mend Renovate](https://mend.io/renovate/).View the [repository joblog](https://developer.mend.io/github/FlutterGen/flutter_gen).<!–renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yNzIuNCIsInVwZGF0ZWRJblZlciI6IjQ0LjEyLjAiLCJ0YXJnZXRCcmFuY2giOiJtYWluIiwibGFiZWxzIjpbXX0=–>Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> , GitHub upgrade: update dependency lint-staged to v17.2.0 (#778)This PR contains the following updates:| Package | Change |[Age](https://docs.renovatebot.com/merge-confidence/) |[Confidence](https://docs.renovatebot.com/merge-confidence/) ||—|—|—|—|| [lint-staged](https://redirect.github.com/lint-staged/lint-staged) |[`17.0.7` →`17.2.0`](https://renovatebot.com/diffs/npm/lint-staged/17.0.7/17.2.0) |||—### Release Notes<details><summary>lint-staged/lint-staged (lint-staged)</summary>###[`v17.2.0`](https://redirect.github.com/lint-staged/lint-staged/blob/HEAD/CHANGELOG.md#1720)[CompareSource](https://redirect.github.com/lint-staged/lint-staged/compare/v17.1.1…v17.2.0)##### Minor Changes-[#1823](https://redirect.github.com/lint-staged/lint-staged/pull/1823)[`ee156cc`](https://redirect.github.com/lint-staged/lint-staged/commit/ee156cc7039494f1db11f389b1233c78f588238c)- The chunking of tasks based on maximum command line argument lengthhas been re-implemented to be more precise. Now the chunking happensbased on the final generated command string, instead of just the list ofstaged files like previously. This benefits mainly Windows platforms andfunction commands like: “`js /** @type {import('lint-staged').Configuration} */ export default {"*.ts": () => "tsc", // Run "tsc" when any TS file is changed (forentire project) }; “`Where the spawned command is literally `"tsc"` without any extraarguments. Previously, this was still chunked when a lot of files werestaged. Now, it probably won't be chunked because the length of thecommand is just three letters.Also, native JavaScript/Node.js function tasks won't be chunked at all,when previously they were run multiple times when chunked: “`js /** @type {import('lint-staged').Configuration} */ export default { "*.js": { title: "Log staged JS files to console", task: async (files) => { console.log("Staged JS files:", files); }, }, }; “`###[`v17.1.1`](https://redirect.github.com/lint-staged/lint-staged/blob/HEAD/CHANGELOG.md#1711)[CompareSource](https://redirect.github.com/lint-staged/lint-staged/compare/v17.1.0…v17.1.1)##### Patch Changes-[#1820](https://redirect.github.com/lint-staged/lint-staged/pull/1820)[`a626a9f`](https://redirect.github.com/lint-staged/lint-staged/commit/a626a9f269d9ff6498a9b8245490e096f90c4bb7)- It's now possible to set `–max-arg-length=Infinity` to effectivelydisable chunking of tasks based on the number of staged files. Theparsing and validation of the numeric CLI options `–max-arg-length` and`–concurrency` has been improved.###[`v17.1.0`](https://redirect.github.com/lint-staged/lint-staged/blob/HEAD/CHANGELOG.md#1710)[CompareSource](https://redirect.github.com/lint-staged/lint-staged/compare/v17.0.8…v17.1.0)##### Minor Changes-[#1816](https://redirect.github.com/lint-staged/lint-staged/pull/1816)[`7568d4f`](https://redirect.github.com/lint-staged/lint-staged/commit/7568d4fb15ba3c3317a7aec36195461cb2f272d7)- The console output of *lint-staged* has been simplified so thatthere's less interactive spinners and more explicit messages like*"Started…*" -> "*Done!*". The primary purpose of this was to remove[`Listr2`](https://redirect.github.com/listr2/listr2), a very largedependency. **Before:**Size of `node_modules/` after installing: `1561.7 kB` with 29 packages. Fancy interactive spinners, but output dynamically changes: “`shell ✔ Backed up original state in git stash (0b191303) ✔ Running tasks for staged files… ✔ Staging changes from tasks… ✔ Cleaning up temporary files… “` **After:**Size of `node_modules/` after installing: `974.0 kB` with 5 packages(37.6 % smaller, 82.7 % less transitive dependencies). Simpler but more explicit output: “`shell ⋯ Backing up original state… ✔ Done backing up original state (35b38ed1)! ⋯ Running tasks for staged files… *.js — 1 file ⋯ oxlint –fix *.{json,md} — 1 file ⋯ oxfmt –write ✔ oxfmt –write ✔ oxlint –fix ✔ Done running tasks for staged files! ⋯ Staging changes from tasks… ✔ Done staging changes from tasks! ⋯ Cleaning up temporary files… ✔ Done cleaning up temporary files! “`##### Patch Changes-[#1816](https://redirect.github.com/lint-staged/lint-staged/pull/1816)[`c19079d`](https://redirect.github.com/lint-staged/lint-staged/commit/c19079d808d557b538c34fe69381d2ef970c7acc)- Try to restore hidden unstaged changes when using `–no-revert`.-[#1818](https://redirect.github.com/lint-staged/lint-staged/pull/1818)[`efb23a2`](https://redirect.github.com/lint-staged/lint-staged/commit/efb23a25075d980db9edabd2f71e769fc97d48c8)- Console output colors are enabled/disabled more consistently.-[#1818](https://redirect.github.com/lint-staged/lint-staged/pull/1818)[`26112a1`](https://redirect.github.com/lint-staged/lint-staged/commit/26112a19151f9678861d51ea7416e9f9bef24bbb)- Failed JS function tasks now properly kill other tasks, unless`–continue-on-error` is used. Previously their failure didn't affectother tasks.###[`v17.0.8`](https://redirect.github.com/lint-staged/lint-staged/blob/HEAD/CHANGELOG.md#1708)[CompareSource](https://redirect.github.com/lint-staged/lint-staged/compare/v17.0.7…v17.0.8)##### Patch Changes-[#1809](https://redirect.github.com/lint-staged/lint-staged/pull/1809)[`179b437`](https://redirect.github.com/lint-staged/lint-staged/commit/179b4372b2528f6fa66f927337d238711694d0e0)- Fix *lint-staged* discarding the ongoing merge conflict status(`.git/MERGE_HEAD`) when using the `–hide-unstaged` or `–hide-all`options.-[#1811](https://redirect.github.com/lint-staged/lint-staged/pull/1811)[`3d0b2c0`](https://redirect.github.com/lint-staged/lint-staged/commit/3d0b2c0709a2a39aa7b134e3741fed21250d808e)- Fix issues with Git commands that are successful but also emitwarnings to `stderr`, by ignoring the `stderr` output completely whenthe process exits with code 0. This was the behavior when using`nano-spawn` and `execa`, but when switching to `tinyexec` in 16.3.0both `stdout` and `stderr` were used as interleaved output.</details>—### Configuration📅 **Schedule**: (in timezone Asia/Tokyo)- Branch creation – Only on Wednesday (`* * * * 3`)- Automerge – At any time (no schedule defined)🚦 **Automerge**: Disabled by config. Please merge this manually once youare satisfied.♻ **Rebasing**: Whenever PR is behind base branch, or you tick therebase/retry checkbox.🔕 **Ignore**: Close this PR and you won't be reminded about this updateagain.—- [ ] <!– rebase-check –>If you want to rebase/retry this PR, checkthis box—This PR was generated by [Mend Renovate](https://mend.io/renovate/).View the [repository joblog](https://developer.mend.io/github/FlutterGen/flutter_gen).<!–renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xMS40IiwidXBkYXRlZEluVmVyIjoiNDQuMTIuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==–>Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> , GitHub 🔖 5.15.0 (#773)Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> , GitHub upgrade: update pnpm to v11.9.0 (#771)> ℹ️ **Note**> > This PR body was truncated due to platform limits.This PR contains the following updates:| Package | Change |[Age](https://docs.renovatebot.com/merge-confidence/) |[Confidence](https://docs.renovatebot.com/merge-confidence/) ||—|—|—|—|| [pnpm](https://pnpm.io)([source](https://redirect.github.com/pnpm/pnpm/tree/HEAD/pnpm11/pnpm))| [`11.4.0` →`11.9.0`](https://renovatebot.com/diffs/npm/pnpm/11.4.0/11.9.0) |||—### Release Notes<details><summary>pnpm/pnpm (pnpm)</summary>###[`v11.9.0`](https://redirect.github.com/pnpm/pnpm/blob/HEAD/pnpm11/pnpm/CHANGELOG.md#1190)[CompareSource](https://redirect.github.com/pnpm/pnpm/compare/v11.8.0…v11.9.0)##### Minor Changes- [`bae694f`](https://redirect.github.com/pnpm/pnpm/commit/bae694f):Some registries generate tarballs on-demand and cannot provide anintegrity checksum in their package metadata. In that case pnpm nowcomputes the integrity from the downloaded tarball and stores it in thelockfile, so the entry is verifiable on subsequent installs instead ofbeing written without an integrity (which would fail the next install).This also applies to `–lockfile-only`: the tarball is downloaded so itsintegrity can be computed. A lockfile entry that is still missing itsintegrity is rejected as a `ERR_PNPM_MISSING_TARBALL_INTEGRITY` lockfileverification violation (the install fails closed) rather than beingsilently re-fetched.- [`6c35a43`](https://redirect.github.com/pnpm/pnpm/commit/6c35a43):Added `–exclude-peers` to `pnpm sbom`. With `auto-install-peers` (thedefault), peer dependencies resolve into the lockfile and are otherwiseindistinguishable from the package's own dependencies. The flag dropspeer dependencies (and any transitive subtree reachable only throughthem) from the SBOM. CycloneDX 1.7 has no scope or relationship thatexpresses "consumer-provided peer", so omission is the only spec-cleanhandling. The flag name matches `pnpm list –exclude-peers`; note theSBOM flag prunes a peer's exclusive subtree, which is stricter than`pnpm list` (which only hides leaf peers).##### Patch Changes- [`25a829e`](https://redirect.github.com/pnpm/pnpm/commit/25a829e):`pnpm audit –fix` now writes a single combined`minimumReleaseAgeExclude` entry per package (e.g. `axios@0.18.1 ||0.21.1`) instead of one entry per version, matching the formatdocumented for the setting. Existing per-version entries in`pnpm-workspace.yaml` are merged into the combined form rather than leftas duplicates. Installs that auto-collect immature versions into`minimumReleaseAgeExclude` now report the same combined entries, so the"Added N entries" message matches what is written to the manifest[#12534](https://redirect.github.com/pnpm/pnpm/issues/12534).- [`1cbb5f2`](https://redirect.github.com/pnpm/pnpm/commit/1cbb5f2):Fixed non-deterministic peer resolution that could add or remove anoptional transitive peer — for example `@babel/core`, reached through`styled-jsx` — from a package's peer-dependency suffix across otherwiseidentical installs, churning the lockfile and causing intermittent `pnpmdedupe –check` failures in CI. When a package's children are resolvedby one occurrence (the "owner") and reused by a deeper consumer, whetherthat consumer inherited the owner's missing peers depended on whetherthe owner's resolution had finished yet — a race under concurrentresolution. The decision is now a function of the dependency graph'sstructure rather than resolution-completion order.- [`d577eea`](https://redirect.github.com/pnpm/pnpm/commit/d577eea):Fixed a Windows flakiness in `pnpm dlx` where a failed install couldsurface a spurious `EBUSY: resource busy or locked` error. The cleanupof a partially-populated dlx cache is now best-effort with retries andno longer masks the original error.- [`ec7cf70`](https://redirect.github.com/pnpm/pnpm/commit/ec7cf70):Shortened the `pnpm dlx` cache path so deep dependency trees no longeroverflow Windows' `MAX_PATH`, which could make a dependency's lifecyclescript fail with `spawn cmd.exe ENOENT`.- [`05b95ab`](https://redirect.github.com/pnpm/pnpm/commit/05b95ab):Fixed `pnpm` hanging (and crashing with an unhandled promise rejection)when a non-retryable network error such as `SELF_SIGNED_CERT_IN_CHAIN`occurs while fetching from a registry. The error is now rejected throughthe returned promise instead of being thrown inside the detached retrycallback.- [`d3f68e2`](https://redirect.github.com/pnpm/pnpm/commit/d3f68e2): Fixa `pnpm audit` performance regression on lockfiles that containdependency cycles. The reachable-vulnerability pruning added in pnpm11.5.1 only memoized acyclic subtrees, so any node whose subtree toucheda cycle — together with all of its ancestors — was recomputed on everyquery, making the path walk quadratic. Reachability is now computed onceper node using Tarjan's strongly-connected-components algorithm, socyclic graphs are handled in linear time[#12212](https://redirect.github.com/pnpm/pnpm/issues/12212).The audit path walk also no longer recurses, so a deeply nesteddependency graph can no longer overflow the call stack, and the installpath to each finding is tracked without per-node copying, keeping memorylinear in the graph depth.- [`322f88f`](https://redirect.github.com/pnpm/pnpm/commit/322f88f): Fixfailed optional dependency updates so they don't rewrite unrelateddependency specs[#11267](https://redirect.github.com/pnpm/pnpm/issues/11267).- [`1488db1`](https://redirect.github.com/pnpm/pnpm/commit/1488db1):When `enableGlobalVirtualStore` is toggled on for a project that waspreviously installed without it, stale hoisted symlinks under`node_modules/.pnpm/node_modules` are now replaced instead of being leftpointing at the old per-project virtual store location[#9739](https://redirect.github.com/pnpm/pnpm/issues/9739).- [`6545793`](https://redirect.github.com/pnpm/pnpm/commit/6545793):Fixed `pnpm install –ignore-workspace` overwriting the `allowBuilds`map in `pnpm-workspace.yaml`. The ignored builds of a package with abuild script were auto-populated into `allowBuilds` even though`–ignore-workspace` was passed, clobbering committed `true`/`false`values with the `set this to true or false` placeholder[#12469](https://redirect.github.com/pnpm/pnpm/issues/12469).- [`fbdc0eb`](https://redirect.github.com/pnpm/pnpm/commit/fbdc0eb):Fixed `minimumReleaseAgeExclude` and `trustPolicyExclude` so multipleexact-version entries for the same package behave the same as a single`||` disjunction entry. Previously only the first matching rule'sversions were honored, so a config like `[form-data@4.0.6,form-data@2.5.6]` could still flag `form-data@2.5.6` as violating`minimumReleaseAge`, while `[form-data@4.0.6 || 2.5.6]` worked asexpected[#12463](https://redirect.github.com/pnpm/pnpm/issues/12463).- [`fa7004b`](https://redirect.github.com/pnpm/pnpm/commit/fa7004b): Thein-memory package metadata cache is now populated on the exact-versiondisk fast path, so repeated resolutions of the same package within oneinstall no longer re-read and re-parse the on-disk metadata. In largemonorepos this brings the time for adding a new package down fromminutes to seconds. The in-memory cache key now also includes theregistry, so a package of the same name served by two differentregistries in a single install can no longer share a cache slot andresolve the wrong tarball.- [`0a154b1`](https://redirect.github.com/pnpm/pnpm/commit/0a154b1):Fixed `pnpm patch` dropping the package name (and leaking internaloption fields) when the patched dependency resolves to a singlegit-hosted version.- [`4d3fe4b`](https://redirect.github.com/pnpm/pnpm/commit/4d3fe4b): Thepnpr resolver endpoints moved under the reserved `/-/pnpr` namespace:`POST /v1/resolve` is now `POST /-/pnpr/v0/resolve` and `POST/v1/verify-lockfile` is now `POST /-/pnpr/v0/verify-lockfile`. Thecapability handshake at `GET /-/pnpr` advertises protocol version `0` tomatch. This keeps every pnpr-proprietary route in npm's reservednamespace, so it can never collide with a package path.- [`0ec878d`](https://redirect.github.com/pnpm/pnpm/commit/0ec878d):Removing a runtime dependency now removes the matching`devEngines.runtime` or `engines.runtime` entry that was materializedfrom it. Blank runtime selectors are normalized to `latest`.- [`17e7f2c`](https://redirect.github.com/pnpm/pnpm/commit/17e7f2c):`pnpm sbom` now emits a CycloneDX `issue-tracker` external reference forcomponents (and the root) whose `package.json` declares a `bugs` URL.Email-only `bugs` entries are skipped, since the reference requires aURL.- [`a84d2a1`](https://redirect.github.com/pnpm/pnpm/commit/a84d2a1): Add`@pnpm/resolving.tarball-url`, which builds and recognizes the canonicalnpm tarball URL of a package. It vendors `getNpmTarballUrl` (previouslythe external `get-npm-tarball-url` package) and adds`isCanonicalRegistryTarballUrl`, the predicate the lockfile writer usesto decide whether a tarball URL is derivable from name+version+registry(and can therefore be omitted from `pnpm-lock.yaml`).Exposing `isCanonicalRegistryTarballUrl` lets a custom resolver(pnpmfile `resolvers`) fronting a proxy that serves tarballs on anon-canonical path (e.g. an ephemeral `localhost:<port>`) rewrite theresolved tarball to the canonical form, so nothing host-specific ispersisted to the lockfile. Previously this logic was private to`@pnpm/lockfile.utils`.Two correctness fixes are included while consolidating the logic: thescoped-package unescape now handles uppercase `%2F` as well as `%2f`(percent-encoding is case-insensitive), and protocol-insensitivecomparison strips only a leading `http(s)://` scheme instead ofsplitting on the first `://` (which could truncate URLs containing alater `://`).- [`852d537`](https://redirect.github.com/pnpm/pnpm/commit/852d537):Lockfile verification no longer reports a registry metadata fetchfailure (for example a `403`/`401` on a private registry, or a networkerror) as `ERR_PNPM_TARBALL_URL_MISMATCH`. When the registry can't bereached to verify an entry, the install now aborts with the registry'sown fetch error (such as `ERR_PNPM_FETCH_403`, which already explainsthe authentication situation) instead of mislabeling a transport failureas lockfile tampering. Registry fetch errors no longer leak basic-authcredentials embedded in the registry URL (`https://user:pass@host/`)into their message.###[`v11.8.0`](https://redirect.github.com/pnpm/pnpm/blob/HEAD/pnpm11/pnpm/CHANGELOG.md#1180)[CompareSource](https://redirect.github.com/pnpm/pnpm/compare/v11.7.0…v11.8.0)##### Minor Changes- [`c112b61`](https://redirect.github.com/pnpm/pnpm/commit/c112b61):Added a `–dry-run` option to `pnpm install`. It runs a full dependencyresolution and reports what an install would change, but writes nothingto disk (no lockfile, no `node_modules`) and always exits with code 0.This mirrors the preview semantics of `npm install –dry-run`[#7340](https://redirect.github.com/pnpm/pnpm/issues/7340).- [`179ebc4`](https://redirect.github.com/pnpm/pnpm/commit/179ebc4):`pnpm run –no-bail` now exits with a non-zero exit code when any of theexecuted scripts fail, while still running every matched script tocompletion. This makes the exit-code behavior of `–no-bail` consistentbetween recursive and non-recursive runs (recursive runs already failedat the end). Previously, a non-recursive `pnpm run –no-bail` alwaysexited with code 0, even when a script failed[#8013](https://redirect.github.com/pnpm/pnpm/issues/8013).- [`0474a9c`](https://redirect.github.com/pnpm/pnpm/commit/0474a9c):Added support for generating Node.js package maps at`node_modules/.package-map.json` during isolated and hoisted installs.Added the `node-experimental-package-map` setting to inject thegenerated map into pnpm-managed Node.js script environments, and the`node-package-map-type` setting to choose between `standard` and `loose`package maps.- [`dcededc`](https://redirect.github.com/pnpm/pnpm/commit/dcededc):`pnpm sbom` now marks components reachable only through`devDependencies` with CycloneDX `scope: "excluded"` and the`cdx:npm:package:development` property. The `excluded` scope documents"component usage for test and other non-runtime purposes", which matchesthe semantics of a devDependency; the property is the CycloneDXnpm-taxonomy marker emitted by `@cyclonedx/cyclonedx-npm`, so bothmodern (scope) and existing (property) consumers are covered. Componentsreachable at runtime (including installed `optionalDependencies`) omit`scope` and default to `required`.- [`1495cb0`](https://redirect.github.com/pnpm/pnpm/commit/1495cb0):Added per-package SBOM generation with `–out` and `–split` flags. Use`–out out/%s.cdx.json` to write one SBOM per workspace package toindividual files, or `–split` for NDJSON output to stdout. When`–filter` selects a single package, the SBOM root component now usesthat package's metadata. Workspace inter-dependencies (`workspace:`protocol) and their transitive dependencies are included. Author,repository, and license fall back to the root manifest when the packagedoesn't define them.- [`293921a`](https://redirect.github.com/pnpm/pnpm/commit/293921a):feat(view): support searching project manifest upward when package nameis omittedWhen running `pnpm view` without a package name, the command nowsearchesupward for the nearest project manifest (`package.json`, `package.yaml`,or `package.json5`) and uses its `name` field. If the manifest exists but lacks a `name` field, an error is thrown. This change also replaces the `find-up` dependency with `empathic` for improved performance and consistency across workspace tools.##### Patch Changes- [`29ab905`](https://redirect.github.com/pnpm/pnpm/commit/29ab905):Fixed `pnpm update` overriding the version range policy of a namedcatalog whose name parses as a version (e.g. `catalog:express4-21`). The`catalog:` reference carries no pinning of its own, so the prefix fromthe catalog entry (such as `~`) is now preserved instead of beingwidened to `^`[#10321](https://redirect.github.com/pnpm/pnpm/issues/10321).- [`bee4bf4`](https://redirect.github.com/pnpm/pnpm/commit/bee4bf4):Security: validate config dependency names and versions from the envlockfile (`pnpm-lock.yaml`) before using them to build filesystem paths.A committed lockfile with a traversal-shaped `configDependencies` name(such as `../../PWNED`) or version (such as `../../../PWNED`) couldpreviously cause `pnpm install` to create symlinks or write packagefiles outside `node_modules/.pnpm-config` and the store. Names must nowbe valid npm package names and versions must be exact semver versions;the same validation is applied to optional subdependencies of configdependencies, and to the legacy workspace-manifest format before anylockfile is written. See[GHSA-qrv3-253h-g69c](https://redirect.github.com/pnpm/pnpm/security/advisories/GHSA-qrv3-253h-g69c).- [`96bdd57`](https://redirect.github.com/pnpm/pnpm/commit/96bdd57): Fix`link:` workspace protocol switching to `file:` after `pnpm rm` is runfrom inside a workspace package whose target workspace dependency hasits own dependencies, when `injectWorkspacePackages: true` is set.Follow-up to[#10575](https://redirect.github.com/pnpm/pnpm/pull/10575), whichfixed the same symptom for workspace packages without dependencies.- [`302a2f7`](https://redirect.github.com/pnpm/pnpm/commit/302a2f7): Nolonger warn about using both `packageManager` and`devEngines.packageManager` when the two fields pin the same packagemanager at the same version with the same integrity hash (e.g. both`pnpm@11.5.1+sha512.…`). Previously the hash was stripped from thelegacy `packageManager` field but not from `devEngines.packageManager`,so even identical specifications looked like a mismatch[#12028](https://redirect.github.com/pnpm/pnpm/issues/12028).The warning still fires on any genuine divergence, and several cases nowstate the specific reason instead of a single generic message: adifferent package manager, a different version, or contradictoryintegrity hashes for the same version.- [`3f0fb21`](https://redirect.github.com/pnpm/pnpm/commit/3f0fb21):Fixed the progress line showing leftover characters from externalprocesses that write to the terminal between progress updates (e.g. anSSH passphrase prompt would leave a fragment like `added 0sa':`). Theinteractive reporter now redraws each frame in place, erasing to the endof the display before reprinting, so any such remnants are cleared[#12350](https://redirect.github.com/pnpm/pnpm/issues/12350).- [`564619f`](https://redirect.github.com/pnpm/pnpm/commit/564619f):Fixed `pnpm approve-builds` reporting "no packages awaiting approval"when a build-script dependency whose approval was revoked (e.g. after`git stash` drops the `allowBuilds` from `pnpm-workspace.yaml`) isre-added. The revoked packages are now correctly recorded in`.modules.yaml` so `approve-builds` can find them.[#12221](https://redirect.github.com/pnpm/pnpm/issues/12221)- [`3d1fd20`](https://redirect.github.com/pnpm/pnpm/commit/3d1fd20):Skip the redundant "target bin directory already contains an exe callednode" warning on Windows when the existing `node.exe` already matchesthe target (same hard link or identical content)[pnpm/pnpm#12203](https://redirect.github.com/pnpm/pnpm/issues/12203).- [`1b02b47`](https://redirect.github.com/pnpm/pnpm/commit/1b02b47): FixmacOS Gatekeeper blocking native binaries (`.node`, `.dylib`, `.so`) byremoving the `com.apple.quarantine` extended attribute after importingthem from the store.When pnpm imports files from its content-addressable store into`node_modules`, macOS preserves extended attributes, including`com.apple.quarantine`. If this xattr is present on a store blob (e.g.it was first written under a Gatekeeper-enabled app such as a Gitclient), it propagates to `node_modules`, and Gatekeeper blocks thenative binary from loading even though pnpm already verified the file'sintegrity against the lockfile.After importing a package, pnpm now strips `com.apple.quarantine` fromits native binaries, matching Homebrew's behaviour of droppingquarantine from verified downloads. The cleanup is macOS-only, runs in asingle batched `xattr` call per package, is restricted to nativebinaries (other files are untouched), and is non-fatal (it logs awarning on unexpected errors).Fixes[#11056](https://redirect.github.com/pnpm/pnpm/issues/11056)- [`61969fb`](https://redirect.github.com/pnpm/pnpm/commit/61969fb): Fix`pnpm install` with `optimisticRepeatInstall` incorrectly reporting`Already up to date` when `pnpm-lock.yaml` changed but project manifestsdid not. This affected workflows such as checking out or restoring onlythe lockfile[#12100](https://redirect.github.com/pnpm/pnpm/issues/12100).Also fixes `checkDepsStatus` to use the correct lockfile path when`useGitBranchLockfile` is enabled, so the optimistic fast-path andlockfile modification detection work with `pnpm-lock.<branch>.yaml`files instead of always stat'ing `pnpm-lock.yaml`. Merge-conflictdetection now reads the resolved lockfile name as well, and with`mergeGitBranchLockfiles` enabled every `pnpm-lock.*.yaml` is scannedfor modifications and conflicts. The git branch is now resolved byreading `.git/HEAD` directly (no process spawn) and uses the workspacedirectory rather than `process.cwd()`.- [`5c12968`](https://redirect.github.com/pnpm/pnpm/commit/5c12968): Fixrecursive updates of transitive dependencies when the update commandmixes transitive dependency patterns with direct dependency selectors.For example, `pnpm up -r "@babel/core" uuid` now updates matchingtransitive `@babel/core` dependencies even when `uuid` is a directdependency selector[#12103](https://redirect.github.com/pnpm/pnpm/issues/12103).- [`9d79ba1`](https://redirect.github.com/pnpm/pnpm/commit/9d79ba1):Register the `pnpm update –no-save` flag in the CLI help and optionparser.- [`0474a9c`](https://redirect.github.com/pnpm/pnpm/commit/0474a9c):Fixed `pnpm import` for Yarn v2 lockfiles when `js-yaml` v4 isinstalled.- [`9e0c375`](https://redirect.github.com/pnpm/pnpm/commit/9e0c375):Fixed `pnpm install` repeatedly prompting to remove and reinstall`node_modules` in a workspace package when `enableGlobalVirtualStore` isenabled. The post-install build step recorded a per-project`node_modules/.pnpm` virtual store directory in`node_modules/.modules.yaml`, overwriting the global `<storeDir>/links`value the install step had written. The next install then detected avirtual-store mismatch (`ERR_PNPM_UNEXPECTED_VIRTUAL_STORE`). The buildstep now derives the same global virtual store directory as the installstep[#12307](https://redirect.github.com/pnpm/pnpm/issues/12307).- [`223d060`](https://redirect.github.com/pnpm/pnpm/commit/223d060):Document the `–cpu`, `–os` and `–libc` flags in the output of `pnpminstall –help`. These flags were already supported but were onlydocumented on the website[#12359](https://redirect.github.com/pnpm/pnpm/issues/12359).- [`e85aea2`](https://redirect.github.com/pnpm/pnpm/commit/e85aea2):Avoid reading `README.md` from disk when publishing if the publishmanifest already provides a `readme` field. The README is now only readlazily, inside `createExportableManifest`, when it is actually needed.- [`3188ae7`](https://redirect.github.com/pnpm/pnpm/commit/3188ae7):Fixed `pnpm peers check` to accept loose peer dependency ranges such as`>=3.16.0 || >=4.0.0-` when the installed peer version satisfies therange[#12149](https://redirect.github.com/pnpm/pnpm/issues/12149).- [`531f2a3`](https://redirect.github.com/pnpm/pnpm/commit/531f2a3):Fixed `pnpm update` rewriting a `workspace:` dependency that points at alocal path (e.g. `workspace:../packages/foo/dist`) into a normalized`link:` or version-range specifier. Such specifiers are now preservedverbatim when the workspace protocol is preserved[#3902](https://redirect.github.com/pnpm/pnpm/issues/3902).- [`fe66535`](https://redirect.github.com/pnpm/pnpm/commit/fe66535):Fixed a lockfile non-convergence bug where an incremental install kept aduplicate transitive dependency that a fresh install would not produce.When a package is reused from the lockfile, its child edges are takenverbatim and bypass the preferred-versions walk, so a transitivedependency could stay pinned to an older version even after a directdependency resolved to a higher version that satisfies the same range.The resolver now refreshes such a stale pin to the higherdirect-dependency version during resolution — so the older version isnever resolved or fetched, and the incremental result converges to thefresh one.- [`6d35338`](https://redirect.github.com/pnpm/pnpm/commit/6d35338):`pnpm install` detects changes inside local file dependencies again. Theoptimistic repeat-install fast path only tracks manifest and lockfilemodification times, so edits inside a local dependency's directory (or arepacked local tarball) were reported as "Already up to date". Projectswith local file dependencies (`file:` and bare local path or tarballspecifiers, declared directly or through `pnpm.overrides`) now alwaysrun a full install, which refetches those dependencies, matching pnpmv10 behavior[#11795](https://redirect.github.com/pnpm/pnpm/issues/11795).- [`4ca9247`](https://redirect.github.com/pnpm/pnpm/commit/4ca9247):Preserve the existing Node.js runtime version prefix when resolving`node@runtime:<range>` to a concrete version.- [`30c7590`](https://redirect.github.com/pnpm/pnpm/commit/30c7590):Create shorter CAFS temporary package directories to leave room forlifecycle scripts that create IPC socket paths under TMPDIR.- [`13815ad`](https://redirect.github.com/pnpm/pnpm/commit/13815ad):Reporter output (warnings, progress) for `pnpm store` and `pnpm config`subcommands now goes to stderr instead of stdout. This fixes scriptsthat capture their stdout (e.g. `PNPM_STORE=$(pnpm store path)`, `pnpmconfig list –json | jq`) from getting warnings mixed into the result.- [`1c05876`](https://redirect.github.com/pnpm/pnpm/commit/1c05876):Avoid relinking unchanged child dependencies and remove stale childlinks during warm installs.- [`817f99d`](https://redirect.github.com/pnpm/pnpm/commit/817f99d):Fixed lockfile churn where a package's `transitivePeerDependencies`could be dropped (and shift between packages) when the packageparticipates in a dependency cycle. A cycle re-entry resolves againsttruncated children, so it must not be cached as "pure"; otherwisesibling occurrences of the same package short-circuit and losetransitive peers depending on traversal order[#5108](https://redirect.github.com/pnpm/pnpm/issues/5108).- [`eba03e0`](https://redirect.github.com/pnpm/pnpm/commit/eba03e0): Fix`pnpm install` reporting "Already up to date" after a catalog entry in`pnpm-workspace.yaml` was reverted to a previous version. After anupdate modified a catalog, the workspace state cache stored thepre-update catalog versions, so reverting the entry back to its originalversion was not detected as an outdated state[#12418](https://redirect.github.com/pnpm/pnpm/issues/12418).- [`3b54d79`](https://redirect.github.com/pnpm/pnpm/commit/3b54d79):`pnpm update` now keeps lockfile `overrides` that resolve through acatalog in sync with the catalog. Previously, when an overridereferenced a catalog (e.g. `overrides: { foo: 'catalog:' }`) and `pnpmupdate` bumped that catalog entry, the lockfile's `catalogs` advancedwhile the resolved `overrides` kept the old version. The resultinglockfile was internally inconsistent, so a later `pnpm install–frozen-lockfile` failed with `ERR_PNPM_LOCKFILE_CONFIG_MISMATCH`.- [`9d0a300`](https://redirect.github.com/pnpm/pnpm/commit/9d0a300):Fixed `pnpm version –recursive` so it honors the workspace selection.In recursive mode the version bump now applies to the packages resolvedfrom the workspace filter (`selectedProjectsGraph`), matching thebehavior of `pnpm publish –recursive`, instead of always bumping everyworkspace package[#11348](https://redirect.github.com/pnpm/pnpm/issues/11348).###[`v11.7.0`](https://redirect.github.com/pnpm/pnpm/blob/HEAD/pnpm11/pnpm/CHANGELOG.md#1170)[CompareSource](https://redirect.github.com/pnpm/pnpm/compare/v11.6.0…v11.7.0)##### Minor Changes- Added a new setting `frozenStore` (`–frozen-store`) that lets `pnpminstall` run against a package store on a read-only filesystem (e.g. aNix store, a read-only bind mount, an OCI layer). When enabled, pnpmopens the store's SQLite `index.db` through the `immutable=1` URI —bypassing the WAL/`-shm` sidecar creation that otherwise fails on aread-only directory — and suppresses every store-write path (the`index.db` writer and the project-registry write). Pair it with`–offline –frozen-lockfile` against a fully-populated store. Under theglobal virtual store, package directories live inside the store, so ifthe store is missing the build output of a package whose lifecyclescripts are approved (or that has a patch), pnpm fails up front with`ERR_PNPM_FROZEN_STORE_NEEDS_BUILD` rather than crashing mid-build on aread-only write — seed the store with those builds first. Incompatiblewith `–force` and with a configured pnpr server, since both write intothe store; the side-effects cache is likewise not written under`frozenStore`. If the store is missing its content directory, theinstall fails fast with `ERR_PNPM_FROZEN_STORE_INCOMPLETE` rather thanattempting to initialize it. The read-only `immutable=1` open requiresNode.js >=22.15.0, >=23.11.0, or >=24.0.0; on older runtimes`–frozen-store` fails with a clear`ERR_PNPM_FROZEN_STORE_UNSUPPORTED_NODE` error. Bin-linking alsotolerates a read-only store: under the global virtual store a package'sbin source lives inside the store, so the `chmod` that makes itexecutable would be refused — with `EPERM`/`EACCES`, or with `EROFS` ona genuinely read-only filesystem. That `chmod` is redundant when theseed already ships its bins executable with a normalized shebang, so itis now skipped in that case, while a non-executable bin (or one stillcarrying a Windows CRLF shebang) on a read-only store still errors.- When[`pacquet`](https://redirect.github.com/pnpm/pnpm/tree/main/pacquet)(the Rust port of pnpm) is declared in `configDependencies`, pnpm nowdelegates dependency **resolution** to it too — not just materialization— provided the installed pacquet is new enough to support full resolvinginstalls (>= 0.11.7).Previously pacquet only ran in frozen-install mode: pnpm always resolvedthe dependency graph itself (writing `pnpm-lock.yaml`) and handedpacquet a finished lockfile to fetch / import / link. With pacquet >=0.11.7, a non-frozen `pnpm install` (default isolated `nodeLinker`,plain install) is delegated to pacquet end-to-end in a single pass —pacquet resolves the manifests, writes the lockfile, and materializes`node_modules`. pnpm detects the capability from the installed pacquet'sversion; older pacquet releases keep the resolve-then-materialize split,and `add` / `update` / `remove` still resolve in pnpm (it has to mutatethe manifests first). This remains an opt-in preview of the Rust installengine[#11723](https://redirect.github.com/pnpm/pnpm/issues/11723).- Added a new opt-in `–batch` flag to `pnpm publish –recursive` thatsends all selected packages to the registry in a single `PUT/-/pnpm/v1/publish` request instead of one request per package. Thetarget registry has to implement the batch publish endpoint (pnpr does);registries that don't are reported with a clear`ERR_PNPM_BATCH_PUBLISH_UNSUPPORTED` error. The batch is processedall-or-nothing by pnpr: if any package in the batch fails validation,none of the packages are published.##### Patch Changes- Reject path-traversal and reserved dependency aliases (such as`../../../escape`, `.bin`, `.pnpm`, or `node_modules`) that come from alockfile rather than a freshly resolved manifest. A crafted lockfilealias could otherwise be joined directly under a hoisted `node_modules`directory, letting package files be written outside the intended installroot or overwrite pnpm-owned layout. The fix adds two layers:- The `nodeLinker: hoisted` graph builder now validates each alias atthe directory sink (`safeJoinModulesDir`), matching the validation pnpmalready performs when resolving aliases from manifests.- The lockfile verification gate (`verifyLockfileResolutions`) now runsan always-on, policy-independent check that rejects any importer orsnapshot dependency alias that is not a valid package name, failing theinstall early — before any fetch or filesystem work — for every nodelinker at once.- Made shared package child resolution deterministic when the samepackage is reached through multiple contexts. pnpm now chooses theshallowest occurrence, then importer order, then parent path, instead ofletting request timing decide the child context and missing-peer report[pnpm/pnpm#12358](https://redirect.github.com/pnpm/pnpm/issues/12358).- Fix garbled summary line after submitting `pnpm update -i` and `pnpmaudit –fix -i`. The interactive checkbox prompt previously printedevery selected choice's full table row (label, current/target versions,workspace, URL) joined by commas, producing a wall of text afterpressing Enter. The summary now lists only the selected package names(or vulnerability keys) by setting an explicit `short` per choice; thein-progress selection UI is unchanged.- Prevent `pnpm patch-remove` from removing files outside the configuredpatches directory.- Fixed `pnpm publish` ignoring `strictSsl: false` when publishing toregistries with self-signed certificates. The `strictSSL` option is nowforwarded to `libnpmpublish` / `npm-registry-fetch` so that`strict-ssl=false` in `.npmrc` or `strictSsl: false` in`pnpm-workspace.yaml` is respected during publish, the same way it isfor `pnpm install`[pnpm/pnpm#12012](https://redirect.github.com/pnpm/pnpm/issues/12012).- Fixed `Cannot destructure property 'manifest' of'manifestsByPath[rootDir]' as it is undefined` regression introduced in11.6.0 when running `pnpm add <pkg>` outside a workspace on Windows.`selectProjectByDir` was keying the resulting `ProjectsGraph` by`opts.dir` instead of `project.rootDir`, so downstream `manifestsByPath`lookups missed when the two paths normalized differently (typicallydrive-letter casing).[pnpm/pnpm#12379](https://redirect.github.com/pnpm/pnpm/issues/12379)- Git dependencies that point to a subdirectory of a repository(`repo#commit&path:/sub/dir`) keep their `path` in the lockfile again.Since the integrity of git-hosted tarballs started being pinned in thelockfile, any install that actually downloaded the tarball rebuilt thelockfile resolution as `{ integrity, tarball, gitHosted }` and droppedthe `path` field, while installs served from the store kept it — so thefield disappeared seemingly at random. Without `path`, later installsfrom that lockfile silently unpacked the repository root instead of thesubdirectory[#12304](https://redirect.github.com/pnpm/pnpm/issues/12304).- Fixed nondeterministic lockfile output that made `pnpm dedupe –check`fail intermittently in CI. When a locked peer provider was pinned for adependency that has no child dependencies of its own, the pinnedprovider leaked into the shared parent scope, so siblings resolved afterit could pick up an optional peer they should not see. Which siblingswere affected depended on resolution order, which varies with networktiming.- Sped up `pnpm install` with a frozen lockfile by running lockfileverification (the policy revalidation gate added for`minimumReleaseAge`/`trustPolicy` and the tarball-URL anti-tamper check)concurrently with fetching and linking instead of blocking the wholeinstall on it. Dependency lifecycle scripts are still held back untilverification succeeds, so no script runs on an unverified lockfile: ifverification fails the install aborts before any dependency build, andif linking finishes first the install waits for the verification verdictbefore completing.- User-defined `npm_config_*` environment variables are now preservedduring lifecycle script execution. Previously, all `npm_`-prefixed envvars were stripped, which caused user-set variables like`npm_config_platform_arch` to be lost[pnpm/pnpm#12399](https://redirect.github.com/pnpm/pnpm/issues/12399).- pnpm can now use different auth tokens for different package scopes,even when those scopes use the same registry URL.Previously, auth was selected only by registry URL. If `@org-a` and`@org-b` both used `https://npm.pkg.github.com/`, they had to share thesame token. This caused problems for registries that issue tokens perorganization or per scope.Configure a scope-specific token by adding the package scope after theregistry URL in the auth key: “`ini @org-a:registry=https://npm.pkg.github.com/ @org-b:registry=https://npm.pkg.github.com/ //npm.pkg.github.com/:@org-a:_authToken=${ORG_A_TOKEN} //npm.pkg.github.com/:@org-b:_authToken=${ORG_B_TOKEN} //npm.pkg.github.com/:_authToken=${FALLBACK_TOKEN} ““pnpm login –registry=https://npm.pkg.github.com –scope=@org-a`writes the token to the same scope-specific auth key.When installing or publishing `@org-a/*`, pnpm uses `ORG_A_TOKEN`. For`@org-b/*`, pnpm uses `ORG_B_TOKEN`. Packages without a matching scopecontinue to use the registry-wide fallback token.- `pnpm setup` no longer prompts to approve build scripts for`@pnpm/exe` when installing the standalone executable. pnpm links theplatform-specific binary itself, so the package's install scripts areskipped during the global self-install[#12377](https://redirect.github.com/pnpm/pnpm/issues/12377).- Close lockfile reads deterministically before rewriting lockfiles andkeep pacquet's virtual store directory length aligned with pnpm onWindows.- A `304 Not Modified` answer from the registry now renews the cachedmetadata file's mtime, so the `minimumReleaseAge` freshness shortcutkeeps serving resolutions from the cache. Previously, once a cachedpackument grew older than `minimumReleaseAge`, every subsequent installre-validated it against the registry forever, because a 304 neverrewrites the file.- Updated dependency ranges. Notably: – `@pnpm/logger` peer dependency range moved to `^1100.0.0`.- `msgpackr` 1.11.8 → 2.0.4 (store index files remain byte-compatible inboth directions).- `open` ^7.4.2 → ^11.0.0, `memoize` ^10 → ^11, `cli-truncate` ^5 → ^6,`pidtree` ^0.6 → ^1.- `@yarnpkg/core` 4.5.0 → 4.8.0, `@rushstack/worker-pool` 0.7.7 →0.7.18, `@cyclonedx/cyclonedx-library` 10.0.0 → 10.1.0,`@pnpm/config.nerf-dart` ^1 → ^2, `@pnpm/log.group` 3.0.2 → 4.0.1,`@pnpm/util.lex-comparator` ^3 → ^4.- Updated `@zkochan/cmd-shim` to v9.0.6.- Fixed a Windows-only hang where a failed command could take 20–46seconds to exit. On error, pnpm enumerates descendant processes (via`pidtree`) to terminate them, which on Windows shells out to`wmic`/PowerShell `Get-CimInstance Win32_Process` — a lookup that isextremely slow on some machines. The lookup is now bounded by a shorttimeout so it can no longer stall the process exit.###[`v11.6.0`](https://redirect.github.com/pnpm/pnpm/blob/HEAD/pnpm11/pnpm/CHANGELOG.md#1160)[CompareSource](https://redirect.github.com/pnpm/pnpm/compare/v11.5.3…v11.6.0)##### Minor Changes- `pnpm install` completes without re-resolving when `pnpm-lock.yaml`was deleted but `node_modules` is intact: the up-to-date check nowtreats the current lockfile (`node_modules/.pnpm/lock.yaml`) — therecord of what the previous install materialized — as the wantedlockfile, verifies the manifests still match it, restores`pnpm-lock.yaml` from it, and reports "Already up to date". Previouslythis scenario triggered a full resolution and a re-verification of everylocked package against the registry.- [`615c669`](https://redirect.github.com/pnpm/pnpm/commit/615c669):Added support for configuring URL-scoped registry settings through`npm_config_//…` and `pnpm_config_//…` environment variables, forexample: “`text npm_config_//registry.npmjs.org/:_authToken=<token> pnpm_config_//registry.npmjs.org/:_authToken=<token> “`This provides a file-free way to supply registry authentication. Becausethe registry a value applies to is encoded in the (trusted) environmentvariable name, it is host-scoped by construction and cannot beredirected to another registry by repository-controlled config. Theenvironment value is treated as trusted config: it takes precedence overa project/workspace `.npmrc` but is still overridden by command-lineoptions. When the same key is provided through both prefixes,`pnpm_config_` wins.- Raised the default network concurrency from `min(64, max(cpuCores * 3,16))` to `min(96, max(cpuCores * 3, 64))`. Package downloads areI/O-bound, not CPU-bound, so deriving the floor from the core count leftmachines with few cores (for example 4-vCPU CI runners) downloading only16 tarballs at a time and unable to saturate a low-latency registry. The`networkConcurrency` setting still overrides the default.##### Patch Changes- Improved the warning printed when a project `.npmrc` uses anenvironment variable in a registry/proxy URL or in registry credentials.The message now explains why the setting was ignored and how to migrateit to a trusted source — for example by moving the line to theuser-level `~/.npmrc` or running `pnpm config set "<key>" <value>` —with a link to <https://pnpm.io/npmrc>. The `pnpm config set` example isonly suggested when the key has no `${…}` placeholder, so the snippetis always safe to copy-paste.- Print a "Lockfile passes supply-chain policies (verified 2h ago)"message when lockfile verification is skipped because a cached verdictfor the same lockfile content and policy is reused. Previously thecached short-circuit was completely silent, which made it look like thepolicy gate never ran[#12324](https://redirect.github.com/pnpm/pnpm/issues/12324).- Platform-specific optional dependencies are now skipped even whentheir `os`/`cpu`/`libc` fields are missing from the registry metadata orthe lockfile. Some registries strip these fields from the packagemetadata, which made pnpm download and install the binaries of everyplatform regardless of `supportedArchitectures`. The missing platformfields of an optional dependency are now inferred from its name (e.g.`@nx/nx-win32-arm64-msvc` → `os: win32`, `cpu: arm64`), soforeign-platform binaries are skipped without even downloading them[#11702](https://redirect.github.com/pnpm/pnpm/issues/11702).###[`v11.5.3`](https://redirect.github.com/pnpm/pnpm/blob/HEAD/pnpm11/pnpm/CHANGELOG.md#1153)[CompareSource](https://redirect.github.com/pnpm/pnpm/compare/v11.5.2…v11.5.3)##### Patch Changes- Stopped expanding environment variables in repository-controlledregistry/proxy request destinations and registry credential values from`.npmrc`, and in workspace registry URLs from `pnpm-workspace.yaml`.Move dynamic registry URL and token configuration to trusted user,global, CLI, or environment config.- Resolve package-manager bootstrap dependencies with trusted user orCLI registry and network config, and reject package-manager env-lockfilerecords that do not use registry package paths with integrity-onlyresolutions before auto-switch execution.- Avoid writing `packageManagerDependencies` to `pnpm-lock.yaml` whenpackage manager policy is set to `onFail: ignore` or `pmOnFail: ignore`[#12228](https://redirect.github.com/pnpm/pnpm/issues/12228).- Avoid running dependency-status auto-install when the dependencystatus is unavailable without a project manifest.- Using the `$` version reference syntax in `overrides` (e.g. `"react":"$react"`) now prints a deprecation warning. The syntax still works, but[catalogs](https://pnpm.io/catalogs) are the recommended way to keep anoverridden version in sync with the rest of the workspace. Reference acatalog entry with the `catalog:` protocol instead.- Fixed `pnpm config get globalconfig` to return the global`config.yaml` path again[pnpm/pnpm#11962](https://redirect.github.com/pnpm/pnpm/issues/11962).- Fixed bare `–color` so it does not consume the following CLI flag,allowing command shorthands like `–parallel` to expand correctly andforms like `pnpm –color with current <command>` to dispatch the innercommand instead of failing with `MISSING_WITH_CURRENT_CMD`.- Fix `pnpm install` ignoring `enableGlobalVirtualStore` toggle byincluding it in the workspace state settings check[#12142](https://redirect.github.com/pnpm/pnpm/issues/12142).- Security: pnpm now verifies the npm registry signature of apackage-manager binary before spawning it, so a cloned repository cannotmake pnpm download and execute an arbitrary native binary.This covers two paths that select an executable fromrepository-controlled input:- **pacquet install engine** — declaring `pacquet` (or `@pnpm/pacquet`)in `configDependencies` opts in to pnpm's Rust install engine. pnpm nowverifies that the installed `pacquet` shim and the host's`@pacquet/<platform>-<arch>` binary carry a valid npm registry signaturefor their exact `name@version`, and refuses to run pacquet (failing thecommand) if the signature does not verify or cannot be checked. The onlygraceful fallback to pnpm's own engine is when pacquet has no binary forthe current platform.- **automatic version switch / `self-update`** — the `packageManager` /`devEngines.packageManager` field makes pnpm download and run a specificpnpm version. pnpm now verifies the registry signature of `pnpm`,`@pnpm/exe`, and the host platform binary before installing/spawningthem, and refuses to run an engine whose signature does not match apublished, signed release. The check runs only on an actual download(store cache miss), so it does not add a network round trip to everycommand.In both cases the signature is verified over the *installed* integrity,against npm's public signing keys that ship embedded in the pnpm CLI(like corepack), so bytes substituted via a tampered lockfile or arepository-controlled registry fail verification — and a registry theuser did not vouch for cannot supply its own signing keys. The signedpackument is fetched from the configured registry, so an npm mirrorworks transparently. Verification fails closed: if it cannot becompleted (for example, the registry is unreachable), the command failsrather than running an unverified binary. The embedded keys are keptcurrent by a release-time check against npm's signing-keys endpoint.- Made peer-dependent deduplication deterministic. When a peer-suffixedpackage variant was a subset of two or more mutually incompatible largervariants, the variant it collapsed into depended on the order importerswere resolved in, which varies between machines. This could resolve thesame workspace to different lockfiles on different platforms and make`pnpm dedupe –check` alternate between passing and failing.- Reject invalid package names and versions from staged tarballmanifests before deriving filenames for `pnpm stage download`.- Clarified in CLI help that the pnpm store is trusted shared state andstore integrity checks are corruption detection, not a tamper boundaryfor untrusted store writers.- Reject reserved manifest `bin` names (`""`, `"."`, `".."`, and scopedforms such as `@scope/..`) when resolving a package's bins. These namespreviously passed the bin-name guard and, when joined to the global bindirectory during global remove/update/add operations, could resolve tothe global bin directory itself or its parent and have it recursivelydeleted.- Require trusted package identity before package-name `allowBuilds`entries can approve lifecycle scripts for git, git-hosted tarball,direct tarball, and local directory artifacts. To approve one of thoseartifacts explicitly, use its peer-suffix-free lockfile depPath as the`allowBuilds` key. Lockfile verification now rejects lockfiles where aregistry-style dependency path (`name@semver`) is backed by a git,directory, or git-hosted tarball resolution(`ERR_PNPM_RESOLUTION_SHAPE_MISMATCH`), so the dependency path is areliable artifact identity by the time scripts can run.- Security: pnpm now verifies the OpenPGP signature of a downloadedNode.js runtime's `SHASUMS256.txt` before trusting its integrity hashes.When a repository requests a Node.js runtime (e.g. via`devEngines.runtime` / `useNodeVersion`), the download mirror isrepository-configurable through `node-mirror:<channel>`. The integrityof the downloaded binary was only checked against `SHASUMS256.txt`fetched from that same mirror — a circular check that a malicious mirrorcould satisfy by serving a tampered binary together with a matching`SHASUMS256.txt`. pnpm then executes the binary (for example to runlifecycle scripts).pnpm now fetches `SHASUMS256.txt.sig` and verifies the detached OpenPGPsignature against the Node.js release team's public keys, which shipembedded in the pnpm CLI. A mirror that serves a tampered binary cannotalso produce a valid signature, so the download fails to verify. Theembedded keys are kept current by a release-time check against thecanonical `nodejs/release-keys` list.The musl variants from the hardcoded `unofficial-builds.nodejs.org`mirror are not repository-configurable and are signed by a differentkey, so they continue to be trusted over TLS.###[`v11.5.2`](https://redirect.github.com/pnpm/pnpm/blob/HEAD/pnpm11/pnpm/CHANGELOG.md#1152)[CompareSource](https://redirect.github.com/pnpm/pnpm/compare/v11.5.1…v11.5.2)##### Patch Changes- Peer dependency resolution now reuses the peer contexts alreadyrecorded in the lockfile when those providers are still present in thedependency graph and still satisfy the peer ranges. This avoidsunnecessary peer-context rewrites during lockfile regeneration. Currentmanifest choices remain authoritative: a newly added, explicitlyupdated, or aliased direct provider, a changed nested provider, or alocked version that no longer satisfies the range still takesprecedence.- The lockfile verifier now checks that a registry entry pinning anexplicit `tarball` URL points at the artifact the registry's ownmetadata lists for that `name@version`. Previously a tampered lockfilecould pair a trusted `name@version` with an attacker-chosen tarball URL(and a matching integrity for those bytes), so the install fetched theattacker's bytes. A mismatch — or any entry that can't be confirmedagainst the registry — is rejected with `ERR_PNPM_TARBALL_URL_MISMATCH`.Non-registry resolutions (`file:`, git-hosted, etc.) and registryentries without an explicit tarball URL (the URL is reconstructed fromname+version+registry, so it is inherently bound) are unaffected;non-standard registry tarball URLs (npm Enterprise, GitHub Packages)still pass because they match the metadata.- Fix `pnpm update –recursive –lockfile-only <pkg>@<version>`crashing with `Invalid Version` when the catalog entry for `<pkg>` is aversion range (e.g. `^21.2.10`) and `catalogMode` is `strict` or`prefer`. The catalog–version comparison now skips the equality checkwhen either side is a range rather than passing a range to`semver.eq()`, so range specifiers fall through to the existing mismatchhandling instead of throwing[#11570](https://redirect.github.com/pnpm/pnpm/issues/11570).- Avoided a Node.js crash when pnpm exits after network requests onWindows.- Fixed packages being materialized into the virtual store without theirroot-level files (`package.json`, `LICENSE`, README, root entrypoints)when multiple `pnpm install` processes ran against the samestore/workspace concurrently. The fast import path used to destructivelyempty the shared target directory, so a concurrent importer could wipefiles another importer had already written; if the surviving filesincluded the `package.json` completion marker, every later installtreated the broken directory as complete and never repaired it. The fastpath now imports directly only when it can create the target directoryexclusively, and otherwise builds the package in a private tempdirectory and atomically renames it into place[#12197](https://redirect.github.com/pnpm/pnpm/issues/12197).- Fix dependency build scripts not running under the global virtualstore (`enableGlobalVirtualStore`).In a workspace install, dependency build scripts are deferred to asingle `rebuild` pass (`buildProjects`). That pass resolved eachpackage's location from the classic`node_modules/.pnpm/<depPathToFilename>` layout, which does not existunder the global virtual store — so native dependencies (e.g. packagesusing `node-gyp` / `prebuild-install`) were never built and failed toload at runtime (`Cannot find module …/build/Release/*.node`).`buildProjects` now resolves the global-virtual-store projectiondirectory (`<storeDir>/links/<hash>`, computed with the same graph hashthe installer uses) when `enableGlobalVirtualStore` is set, andserializes concurrent builds of the same shared projection so parallelworkspace projects don't race on the same directory.- Don't promote a `runtime:` dependency (such as the Node.js versionfrom `devEngines.runtime` or `pnpm runtime set`) into a catalog when`catalogMode` is `strict` or `prefer`. A `runtime:` dependencyround-trips to `devEngines.runtime`, which only recognizes the`runtime:` protocol; cataloging it rewrote the manifest entry to`catalog:`, which broke that round-trip, stranded it in`devDependencies`, and left `devEngines.runtime` untouched.- Skip lockfile `minimumReleaseAge`/`trustPolicy` verification fornon-registry tarball protocols (for example `file:`), so local tarballdependencies are not incorrectly checked against npm registry metadata.###[`v11.5.1`](https://redirect.github.com/pnpm/pnpm/blob/HEAD/pnpm11/pnpm/CHANGELOG.md#1151)[CompareSource](https://redirect.github.com/pnpm/pnpm/compare/v11.5.0…v11.5.1)##### Patch Changes- Improve `pnpm audit` performance by pruning non-vulnerable lockfilesubtrees and stopping path enumeration once vulnerable findings reachthe path cap.- Avoid crashing when the workspace state cache is partially written ormalformed.- Set `npm_config_user_agent` for root lifecycle scripts during headlessinstalls.- Preserve the `integrity` field of a remote (non-registry) tarballdependency when its lockfile entry is rebuilt. Re-resolving such adependency without re-fetching it (for example via `pnpm update`, orwhen another dependency changes) produced a resolution with no integrity— URL/tarball resolvers only learn the integrity after the tarball isdownloaded — so the previously recorded integrity was dropped, makinglater installs fail with `ERR_PNPM_MISSING_TARBALL_INTEGRITY`[#12067](https://redirect.github.com/pnpm/pnpm/issues/12067).- Normalize a string `repository` field into the `{ type, url }` objectform when creating the publish manifest, matching npm's behavior. Someregistries (e.g. Gitea/Codeberg) reject a string `repository` with a 500Internal Server Error during `pnpm publish`[#12099](https://redirect.github.com/pnpm/pnpm/issues/12099).- Preserve compatible optional peer versions already present in thelockfile when resolving dependencies.- Fixed inconsistent resolution of a peer dependency that is sharedthrough a diamond. When a package peer-depends on both another packageand one of that package's own peer dependencies (for example`@typescript-eslint/eslint-plugin` peer-depends on both`@typescript-eslint/parser` and `typescript`, and`@typescript-eslint/parser` peer-depends on `typescript`), pnpm nolonger reuses a hoisted instance of the shared peer that was resolvedagainst a different version[#12079](https://redirect.github.com/pnpm/pnpm/issues/12079).###[`v11.5.0`](https://redirect.github.com/pnpm/pnpm/blob/HEAD/pnpm11/pnpm/CHANGELOG.md#1150)[CompareSource](https://redirect.github.com/pnpm/pnpm/compare/v11.4.0…v11.5.0)##### Minor Changes- Added a new `hoistingLimits` setting for `nodeLinker: hoisted`installs, mirroring yarn's `nmHoistingLimits`. It accepts `none` (thedefault — hoist as far as possible), `workspaces` (hoist only as far aseach workspace package), or `dependencies` (hoist only up to eachworkspace package's direct dependencies). Originally proposed in[#6468](https://redirect.github.com/pnpm/pnpm/pull/6468), closing[#6457](https://redirect.github.com/pnpm/pnpm/issues/6457).- Replaced `enquirer` with `@inquirer/prompts` for all interactiveprompts. Fixes the `update -i` scrolling overflow bug where long choicelists were clipped in the terminal[#6643](https://redirect.github.com/pnpm/pnpm/issues/6643). **User-facing changes:**- `pnpm update -i` / `pnpm update -i –latest`: Scrolling now workscorrectly when many packages are available; the new library usesvisual-line-aware pagination via `usePagination`- `pnpm audit –fix -i`: Same scrolling fix for vulnerability selection – `pnpm approve-builds`: Interactive build approval prompts updated – `pnpm patch`: Version selection and "apply to all" prompts updated – `pnpm patch-remove`: Patch removal selection updated – `pnpm publish`: Branch confirmation prompt updated – `pnpm login`: Credential prompts updated- `pnpm run` / `pnpm exec` (with `verifyDepsBeforeRun=prompt`):Confirmation prompt updatedVim-style `j`/`k` keys still work for up/down navigation in allinteractive prompts.**Internal:** The `OtpEnquirer` and `LoginEnquirer` DI interfaceschanged from `{ prompt }` to `{ input }` / `{ input, password }`respectively. Plugins or custom builds that inject their own enquirermock will need to update.- Staged publishes are now recognized in the trust scale. When a packageversion's registry metadata carries an `approver` field, it is treatedas the strongest trust evidence (ranked above trusted publishers andprovenance attes> ✂ **Note**> > PR body was truncated to here.</details>—### Configuration📅 **Schedule**: (in timezone Asia/Tokyo)- Branch creation – Only on Wednesday (`* * * * 3`)- Automerge – At any time (no schedule defined)🚦 **Automerge**: Disabled by config. Please merge this manually once youare satisfied.♻ **Rebasing**: Whenever PR is behind base branch, or you tick therebase/retry checkbox.🔕 **Ignore**: Close this PR and you won't be reminded about this updateagain.—- [ ] <!– rebase-check –>If you want to rebase/retry this PR, checkthis box—This PR was generated by [Mend Renovate](https://mend.io/renovate/).View the [repository joblog](https://developer.mend.io/github/FlutterGen/flutter_gen).<!–renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yNDIuMiIsInVwZGF0ZWRJblZlciI6IjQzLjI1OS4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119–>Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> , GitHub
Provides the list of the opensource Flutter apps collection with GitHub repository.