@savvy-web/silk 3.4.1 → 3.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2334,7 +2334,7 @@ var GlobSet = class GlobSet extends effect.Schema.Class("GlobSet")(effect.Schema
2334
2334
  }
2335
2335
  };
2336
2336
  //#endregion
2337
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._ff048038a9678f5144f817ad24d8f96e/node_modules/@effected/lockfiles/BunExtension.js
2337
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._3c1784fba62fde9a5bac4cf15387fd04/node_modules/@effected/lockfiles/BunExtension.js
2338
2338
  /**
2339
2339
  * Extension data specific to bun lockfiles, attached to `Lockfile.extension`
2340
2340
  * when the format is `"bun"`.
@@ -2355,7 +2355,7 @@ var BunExtension = class extends effect.Schema.Class("BunExtension")({
2355
2355
  trustedDependencies: effect.Schema.optionalKey(effect.Schema.Array(effect.Schema.String))
2356
2356
  }) {};
2357
2357
  //#endregion
2358
- //#region ../../node_modules/.pnpm/@effected+npm@0.8.2_@effected+semver@0.3.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/CatalogResolver.js
2358
+ //#region ../../node_modules/.pnpm/@effected+npm@0.8.3_@effected+semver@0.3.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/CatalogResolver.js
2359
2359
  /**
2360
2360
  * Contract for resolving pnpm `catalog:` dependency specifiers to concrete
2361
2361
  * version ranges.
@@ -2391,7 +2391,7 @@ var BunExtension = class extends effect.Schema.Class("BunExtension")({
2391
2391
  *
2392
2392
  * @public
2393
2393
  */
2394
- var CatalogResolver = class CatalogResolver extends effect.Context.Service()("@effected/npm/CatalogResolver") {
2394
+ var CatalogResolver$1 = class CatalogResolver extends effect.Context.Service()("@effected/npm/CatalogResolver") {
2395
2395
  /**
2396
2396
  * No-op default: `rangeOf` always succeeds with `Option.none()`, never
2397
2397
  * consulting an actual catalog. A pure `Layer.succeed`, bound to a const
@@ -2401,7 +2401,7 @@ var CatalogResolver = class CatalogResolver extends effect.Context.Service()("@e
2401
2401
  static noop = effect.Layer.succeed(CatalogResolver, { rangeOf: () => effect.Effect.succeed(effect.Option.none()) });
2402
2402
  };
2403
2403
  //#endregion
2404
- //#region ../../node_modules/.pnpm/@effected+npm@0.8.2_@effected+semver@0.3.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/WorkspaceResolver.js
2404
+ //#region ../../node_modules/.pnpm/@effected+npm@0.8.3_@effected+semver@0.3.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/WorkspaceResolver.js
2405
2405
  /**
2406
2406
  * Raised when a `catalog:` or `workspace:` specifier cannot be resolved
2407
2407
  * because the resolution mechanism itself failed — not for an ordinary
@@ -2415,7 +2415,7 @@ var CatalogResolver = class CatalogResolver extends effect.Context.Service()("@e
2415
2415
  *
2416
2416
  * @public
2417
2417
  */
2418
- var DependencyResolutionError = class extends effect.Schema.TaggedErrorClass()("DependencyResolutionError", {
2418
+ var DependencyResolutionError$1 = class extends effect.Schema.TaggedErrorClass()("DependencyResolutionError", {
2419
2419
  specifier: effect.Schema.String,
2420
2420
  cause: effect.Schema.Defect()
2421
2421
  }) {
@@ -2453,7 +2453,7 @@ var DependencyResolutionError = class extends effect.Schema.TaggedErrorClass()("
2453
2453
  *
2454
2454
  * @public
2455
2455
  */
2456
- var WorkspaceResolver = class WorkspaceResolver extends effect.Context.Service()("@effected/npm/WorkspaceResolver") {
2456
+ var WorkspaceResolver$1 = class WorkspaceResolver extends effect.Context.Service()("@effected/npm/WorkspaceResolver") {
2457
2457
  /**
2458
2458
  * No-op default: `versionOf` always succeeds with `Option.none()`, never
2459
2459
  * consulting an actual workspace. A pure `Layer.succeed`, bound to a
@@ -2462,7 +2462,7 @@ var WorkspaceResolver = class WorkspaceResolver extends effect.Context.Service()
2462
2462
  static noop = effect.Layer.succeed(WorkspaceResolver, { versionOf: () => effect.Effect.succeed(effect.Option.none()) });
2463
2463
  };
2464
2464
  //#endregion
2465
- //#region ../../node_modules/.pnpm/@effected+npm@0.8.2_@effected+semver@0.3.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/CatalogAssemblyError.js
2465
+ //#region ../../node_modules/.pnpm/@effected+npm@0.8.3_@effected+semver@0.3.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/CatalogAssemblyError.js
2466
2466
  /**
2467
2467
  * Raised when a workspace's catalogs cannot be assembled — a `pnpm-workspace.yaml`
2468
2468
  * that is unreadable or not valid YAML, a root `package.json` `workspaces` field
@@ -2505,15 +2505,7 @@ var CatalogAssemblyError = class extends effect.Schema.TaggedErrorClass()("Catal
2505
2505
  return `Failed to assemble catalogs from ${this.source} ${this.path}`;
2506
2506
  }
2507
2507
  };
2508
- //#endregion
2509
- //#region ../../node_modules/.pnpm/@effected+npm@0.8.2_@effected+semver@0.3.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/DependencySection.js
2510
- /**
2511
- * The short dependency kind: which dependency map an entry came from, named the
2512
- * way consumers branch on it.
2513
- *
2514
- * @public
2515
- */
2516
- const DependencyKind = effect.Schema.Literals([
2508
+ effect.Schema.Literals([
2517
2509
  "prod",
2518
2510
  "dev",
2519
2511
  "peer",
@@ -2525,7 +2517,7 @@ const DependencyKind = effect.Schema.Literals([
2525
2517
  *
2526
2518
  * @public
2527
2519
  */
2528
- const DependencyField = effect.Schema.Literals([
2520
+ const DependencyField$1 = effect.Schema.Literals([
2529
2521
  "dependencies",
2530
2522
  "devDependencies",
2531
2523
  "peerDependencies",
@@ -2912,7 +2904,7 @@ const parseRangeComparators = (s) => {
2912
2904
  * Parse a range expression into comparator sets (OR of ANDs). The empty
2913
2905
  * string parses as the match-all range.
2914
2906
  */
2915
- const parseRange$1 = (raw) => {
2907
+ const parseRange$2 = (raw) => {
2916
2908
  const trimmed = raw.trim();
2917
2909
  if (trimmed.length === 0) return {
2918
2910
  ok: true,
@@ -3811,7 +3803,7 @@ sets: effect.Schema.Array(effect.Schema.Array(Comparator)) }) {
3811
3803
  */
3812
3804
  static FromString = effect.Schema.String.pipe(effect.Schema.decodeTo(Range, effect.SchemaTransformation.transformOrFail({
3813
3805
  decode: (input) => {
3814
- const result = parseRange$1(input);
3806
+ const result = parseRange$2(input);
3815
3807
  return result.ok ? effect.Effect.succeed({ sets: normalizeSets(result.value) }) : effect.Effect.fail(new effect.SchemaIssue.InvalidValue(effect.Option.some(input), { message: `Invalid range expression: "${result.input}" at position ${result.position}` }));
3816
3808
  },
3817
3809
  encode: (parts) => effect.Effect.succeed(formatRange(parts.sets))
@@ -3842,7 +3834,7 @@ sets: effect.Schema.Array(effect.Schema.Array(Comparator)) }) {
3842
3834
  * with {@link InvalidRangeError}.
3843
3835
  */
3844
3836
  static parseResult(input) {
3845
- const result = parseRange$1(input);
3837
+ const result = parseRange$2(input);
3846
3838
  if (!result.ok) return effect.Result.fail(new InvalidRangeError({
3847
3839
  input: result.input,
3848
3840
  position: result.position
@@ -4121,7 +4113,7 @@ const isComparatorSetSubset = (sub, sup) => {
4121
4113
  return true;
4122
4114
  };
4123
4115
  //#endregion
4124
- //#region ../../node_modules/.pnpm/@effected+npm@0.8.2_@effected+semver@0.3.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/DependencySpecifier.js
4116
+ //#region ../../node_modules/.pnpm/@effected+npm@0.8.3_@effected+semver@0.3.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/DependencySpecifier.js
4125
4117
  /**
4126
4118
  * Indicates that a string could not be parsed as a valid dependency specifier.
4127
4119
  *
@@ -4130,50 +4122,50 @@ const isComparatorSetSubset = (sub, sup) => {
4130
4122
  *
4131
4123
  * @public
4132
4124
  */
4133
- var InvalidDependencySpecifierError = class extends effect.Schema.TaggedErrorClass()("InvalidDependencySpecifierError", {
4125
+ var InvalidDependencySpecifierError$1 = class extends effect.Schema.TaggedErrorClass()("InvalidDependencySpecifierError", {
4134
4126
  /** The raw input string that failed validation. */
4135
4127
  input: effect.Schema.String }) {
4136
4128
  get message() {
4137
4129
  return `Invalid dependency specifier "${this.input}": not a recognized specifier`;
4138
4130
  }
4139
4131
  };
4140
- const CATALOG_PREFIX = "catalog:";
4141
- const WORKSPACE_PREFIX = "workspace:";
4142
- const isBarePath = (value) => value.startsWith("./") || value.startsWith("../") || value.startsWith("~/") || value.startsWith("/");
4143
- const isGitHubShorthand = (value) => !value.startsWith(".") && !value.startsWith("~") && !value.startsWith("/") && /^[a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-]+(#.*)?$/.test(value);
4144
- const isGit = (value) => value.startsWith("git+") || value.startsWith("git://") || value.startsWith("github:") || value.startsWith("gist:") || value.startsWith("bitbucket:") || value.startsWith("gitlab:") || isGitHubShorthand(value);
4145
- const isLocal = (value) => value.startsWith("file:") || value.startsWith("link:") || value.startsWith("portal:") || isBarePath(value);
4146
- const isLink = (value) => value.startsWith("link:");
4147
- const isPortal = (value) => value.startsWith("portal:");
4148
- const isCatalog = (value) => value.startsWith(CATALOG_PREFIX);
4149
- const isWorkspace = (value) => value.startsWith(WORKSPACE_PREFIX);
4150
- const isUrl$1 = (value) => value.startsWith("http://") || value.startsWith("https://");
4151
- const parseRange = (value) => {
4132
+ const CATALOG_PREFIX$1 = "catalog:";
4133
+ const WORKSPACE_PREFIX$1 = "workspace:";
4134
+ const isBarePath$1 = (value) => value.startsWith("./") || value.startsWith("../") || value.startsWith("~/") || value.startsWith("/");
4135
+ const isGitHubShorthand$1 = (value) => !value.startsWith(".") && !value.startsWith("~") && !value.startsWith("/") && /^[a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-]+(#.*)?$/.test(value);
4136
+ const isGit$1 = (value) => value.startsWith("git+") || value.startsWith("git://") || value.startsWith("github:") || value.startsWith("gist:") || value.startsWith("bitbucket:") || value.startsWith("gitlab:") || isGitHubShorthand$1(value);
4137
+ const isLocal$1 = (value) => value.startsWith("file:") || value.startsWith("link:") || value.startsWith("portal:") || isBarePath$1(value);
4138
+ const isLink$1 = (value) => value.startsWith("link:");
4139
+ const isPortal$1 = (value) => value.startsWith("portal:");
4140
+ const isCatalog$1 = (value) => value.startsWith(CATALOG_PREFIX$1);
4141
+ const isWorkspace$1 = (value) => value.startsWith(WORKSPACE_PREFIX$1);
4142
+ const isUrl$2 = (value) => value.startsWith("http://") || value.startsWith("https://");
4143
+ const parseRange$1 = (value) => {
4152
4144
  const exit = effect.Schema.decodeUnknownExit(Range$2.FromString)(value);
4153
4145
  return effect.Exit.isSuccess(exit) ? effect.Option.some(exit.value) : effect.Option.none();
4154
4146
  };
4155
- const isRange = (value) => effect.Option.isSome(parseRange(value));
4156
- const protocolOf = (value) => {
4157
- if (value.startsWith(CATALOG_PREFIX)) return "catalog";
4158
- if (value.startsWith(WORKSPACE_PREFIX)) return "workspace";
4147
+ const isRange$1 = (value) => effect.Option.isSome(parseRange$1(value));
4148
+ const protocolOf$1 = (value) => {
4149
+ if (value.startsWith(CATALOG_PREFIX$1)) return "catalog";
4150
+ if (value.startsWith(WORKSPACE_PREFIX$1)) return "workspace";
4159
4151
  if (value.startsWith("link:")) return "link";
4160
4152
  if (value.startsWith("portal:")) return "portal";
4161
- if (value.startsWith("file:") || isBarePath(value)) return "file";
4153
+ if (value.startsWith("file:") || isBarePath$1(value)) return "file";
4162
4154
  if (value.startsWith("npm:")) return "npm";
4163
- if (isGit(value)) return "git";
4164
- if (isUrl$1(value)) return "url";
4165
- if (isRange(value)) return "range";
4155
+ if (isGit$1(value)) return "git";
4156
+ if (isUrl$2(value)) return "url";
4157
+ if (isRange$1(value)) return "range";
4166
4158
  if (/^[a-zA-Z][a-zA-Z0-9._-]*$/.test(value)) return "tag";
4167
4159
  return "unknown";
4168
4160
  };
4169
- const isTag = (value) => protocolOf(value) === "tag";
4170
- const catalogNameOf$1 = (specifier) => {
4171
- if (!isCatalog(specifier)) return effect.Option.none();
4161
+ const isTag$1 = (value) => protocolOf$1(value) === "tag";
4162
+ const catalogNameOf$2 = (specifier) => {
4163
+ if (!isCatalog$1(specifier)) return effect.Option.none();
4172
4164
  const rest = specifier.slice(8).trim();
4173
4165
  return rest.length === 0 ? effect.Option.none() : effect.Option.some(rest);
4174
4166
  };
4175
- const projectRangeModifier = (range, version) => range === "*" || range === "" ? version : range === "~" ? `~${version}` : range === "^" ? `^${version}` : range;
4176
- const splitWorkspaceRest = (rest) => {
4167
+ const projectRangeModifier$1 = (range, version) => range === "*" || range === "" ? version : range === "~" ? `~${version}` : range === "^" ? `^${version}` : range;
4168
+ const splitWorkspaceRest$1 = (rest) => {
4177
4169
  const at = rest.lastIndexOf("@");
4178
4170
  return at > 0 ? {
4179
4171
  target: rest.slice(0, at),
@@ -4183,15 +4175,15 @@ const splitWorkspaceRest = (rest) => {
4183
4175
  range: rest
4184
4176
  };
4185
4177
  };
4186
- const projectWorkspaceRange = (rest, version) => {
4187
- const { target, range } = splitWorkspaceRest(rest);
4188
- const projected = projectRangeModifier(range, version);
4178
+ const projectWorkspaceRange$1 = (rest, version) => {
4179
+ const { target, range } = splitWorkspaceRest$1(rest);
4180
+ const projected = projectRangeModifier$1(range, version);
4189
4181
  return target === void 0 ? projected : `npm:${target}@${projected}`;
4190
4182
  };
4191
- const resolveWorkspace = (specifier, version) => isWorkspace(specifier) ? projectWorkspaceRange(specifier.slice(10), version) : specifier;
4192
- const workspaceTargetOf = (specifier) => {
4193
- if (!isWorkspace(specifier)) return effect.Option.none();
4194
- const { target } = splitWorkspaceRest(specifier.slice(10));
4183
+ const resolveWorkspace$1 = (specifier, version) => isWorkspace$1(specifier) ? projectWorkspaceRange$1(specifier.slice(10), version) : specifier;
4184
+ const workspaceTargetOf$1 = (specifier) => {
4185
+ if (!isWorkspace$1(specifier)) return effect.Option.none();
4186
+ const { target } = splitWorkspaceRest$1(specifier.slice(10));
4195
4187
  return target === void 0 ? effect.Option.none() : effect.Option.some(target);
4196
4188
  };
4197
4189
  /**
@@ -4201,14 +4193,14 @@ const workspaceTargetOf = (specifier) => {
4201
4193
  *
4202
4194
  * @public
4203
4195
  */
4204
- const isValidDependencySpecifier = (value) => value.length > 0 && protocolOf(value) !== "unknown";
4196
+ const isValidDependencySpecifier$1 = (value) => value.length > 0 && protocolOf$1(value) !== "unknown";
4205
4197
  /**
4206
4198
  * A `catalog:` reference. `name` carries the catalog name, or `Option.none()`
4207
4199
  * for the default catalog (`catalog:`).
4208
4200
  *
4209
4201
  * @public
4210
4202
  */
4211
- var CatalogSpecifier = class extends effect.Schema.TaggedClass()("catalog", {
4203
+ var CatalogSpecifier$1 = class extends effect.Schema.TaggedClass()("catalog", {
4212
4204
  /** The original specifier string. */
4213
4205
  raw: effect.Schema.String,
4214
4206
  /** The catalog name, or `Option.none()` for the default catalog. */
@@ -4220,7 +4212,7 @@ var CatalogSpecifier = class extends effect.Schema.TaggedClass()("catalog", {
4220
4212
  *
4221
4213
  * @public
4222
4214
  */
4223
- var WorkspaceSpecifier = class extends effect.Schema.TaggedClass()("workspace", {
4215
+ var WorkspaceSpecifier$1 = class extends effect.Schema.TaggedClass()("workspace", {
4224
4216
  /** The original specifier string. */
4225
4217
  raw: effect.Schema.String,
4226
4218
  /** The part after `workspace:` (e.g. `*`, `^1.2.3`, or an alias form). */
@@ -4244,7 +4236,7 @@ var WorkspaceSpecifier = class extends effect.Schema.TaggedClass()("workspace",
4244
4236
  * specifier points at (the alias target's version for the alias form).
4245
4237
  */
4246
4238
  resolve(version) {
4247
- return projectWorkspaceRange(this.range, version);
4239
+ return projectWorkspaceRange$1(this.range, version);
4248
4240
  }
4249
4241
  };
4250
4242
  /**
@@ -4252,7 +4244,7 @@ var WorkspaceSpecifier = class extends effect.Schema.TaggedClass()("workspace",
4252
4244
  *
4253
4245
  * @public
4254
4246
  */
4255
- var RangeSpecifier = class extends effect.Schema.TaggedClass()("range", {
4247
+ var RangeSpecifier$1 = class extends effect.Schema.TaggedClass()("range", {
4256
4248
  /** The original specifier string. */
4257
4249
  raw: effect.Schema.String }) {};
4258
4250
  /**
@@ -4260,7 +4252,7 @@ raw: effect.Schema.String }) {};
4260
4252
  *
4261
4253
  * @public
4262
4254
  */
4263
- var DistTagSpecifier = class extends effect.Schema.TaggedClass()("dist-tag", {
4255
+ var DistTagSpecifier$1 = class extends effect.Schema.TaggedClass()("dist-tag", {
4264
4256
  /** The original specifier string (also the tag name). */
4265
4257
  raw: effect.Schema.String }) {};
4266
4258
  /**
@@ -4269,35 +4261,35 @@ raw: effect.Schema.String }) {};
4269
4261
  *
4270
4262
  * @public
4271
4263
  */
4272
- var RawSpecifier = class extends effect.Schema.TaggedClass()("raw", {
4264
+ var RawSpecifier$1 = class extends effect.Schema.TaggedClass()("raw", {
4273
4265
  /** The original specifier string. */
4274
4266
  raw: effect.Schema.String }) {};
4275
- const Classified = effect.Schema.Union([
4276
- CatalogSpecifier,
4277
- WorkspaceSpecifier,
4278
- RangeSpecifier,
4279
- DistTagSpecifier,
4280
- RawSpecifier
4267
+ const Classified$1 = effect.Schema.Union([
4268
+ CatalogSpecifier$1,
4269
+ WorkspaceSpecifier$1,
4270
+ RangeSpecifier$1,
4271
+ DistTagSpecifier$1,
4272
+ RawSpecifier$1
4281
4273
  ]);
4282
- const classify$1 = (value) => {
4283
- if (isCatalog(value)) return CatalogSpecifier.make({
4274
+ const classify$2 = (value) => {
4275
+ if (isCatalog$1(value)) return CatalogSpecifier$1.make({
4284
4276
  raw: value,
4285
- name: catalogNameOf$1(value)
4277
+ name: catalogNameOf$2(value)
4286
4278
  });
4287
- if (isWorkspace(value)) return WorkspaceSpecifier.make({
4279
+ if (isWorkspace$1(value)) return WorkspaceSpecifier$1.make({
4288
4280
  raw: value,
4289
4281
  range: value.slice(10)
4290
4282
  });
4291
- if (isRange(value)) return RangeSpecifier.make({ raw: value });
4292
- if (isTag(value)) return DistTagSpecifier.make({ raw: value });
4293
- return RawSpecifier.make({ raw: value });
4283
+ if (isRange$1(value)) return RangeSpecifier$1.make({ raw: value });
4284
+ if (isTag$1(value)) return DistTagSpecifier$1.make({ raw: value });
4285
+ return RawSpecifier$1.make({ raw: value });
4294
4286
  };
4295
- const fromString = effect.Schema.String.pipe(effect.Schema.decodeTo(Classified, effect.SchemaTransformation.transformOrFail({
4296
- decode: (input) => isValidDependencySpecifier(input) ? effect.Effect.succeed(classify$1(input)) : effect.Effect.fail(new effect.SchemaIssue.InvalidValue(effect.Option.some(input), { message: `Invalid dependency specifier: "${input}"` })),
4287
+ const fromString$1 = effect.Schema.String.pipe(effect.Schema.decodeTo(Classified$1, effect.SchemaTransformation.transformOrFail({
4288
+ decode: (input) => isValidDependencySpecifier$1(input) ? effect.Effect.succeed(classify$2(input)) : effect.Effect.fail(new effect.SchemaIssue.InvalidValue(effect.Option.some(input), { message: `Invalid dependency specifier: "${input}"` })),
4297
4289
  encode: (classified) => effect.Effect.succeed(classified.raw)
4298
4290
  })));
4299
- const brandedSpecifier = effect.Schema.String.pipe(effect.Schema.check(effect.Schema.makeFilter((value) => isValidDependencySpecifier(value) ? void 0 : "Expected a valid dependency specifier")), effect.Schema.brand("DependencySpecifier"));
4300
- const decode$3 = (input) => effect.Schema.decodeUnknownEffect(brandedSpecifier)(input).pipe(effect.Effect.mapError(() => new InvalidDependencySpecifierError({ input })));
4291
+ const brandedSpecifier$1 = effect.Schema.String.pipe(effect.Schema.check(effect.Schema.makeFilter((value) => isValidDependencySpecifier$1(value) ? void 0 : "Expected a valid dependency specifier")), effect.Schema.brand("DependencySpecifier"));
4292
+ const decode$5 = (input) => effect.Schema.decodeUnknownEffect(brandedSpecifier$1)(input).pipe(effect.Effect.mapError(() => new InvalidDependencySpecifierError$1({ input })));
4301
4293
  /**
4302
4294
  * A valid dependency version specifier, carrying the protocol taxonomy statics
4303
4295
  * (`DependencySpecifier.protocolOf` and friends) that classify any specifier
@@ -4308,43 +4300,43 @@ const decode$3 = (input) => effect.Schema.decodeUnknownEffect(brandedSpecifier)(
4308
4300
  *
4309
4301
  * @public
4310
4302
  */
4311
- const DependencySpecifier = Object.assign(brandedSpecifier, {
4312
- protocolOf,
4313
- parseRange,
4314
- isRange,
4315
- isTag,
4316
- isGit,
4317
- isUrl: isUrl$1,
4318
- isLocal,
4319
- isLink,
4320
- isPortal,
4321
- isCatalog,
4322
- isWorkspace,
4323
- catalogNameOf: catalogNameOf$1,
4324
- resolveWorkspace,
4325
- workspaceTargetOf,
4326
- isValid: isValidDependencySpecifier,
4327
- decode: decode$3,
4328
- FromString: fromString
4303
+ const DependencySpecifier$1 = Object.assign(brandedSpecifier$1, {
4304
+ protocolOf: protocolOf$1,
4305
+ parseRange: parseRange$1,
4306
+ isRange: isRange$1,
4307
+ isTag: isTag$1,
4308
+ isGit: isGit$1,
4309
+ isUrl: isUrl$2,
4310
+ isLocal: isLocal$1,
4311
+ isLink: isLink$1,
4312
+ isPortal: isPortal$1,
4313
+ isCatalog: isCatalog$1,
4314
+ isWorkspace: isWorkspace$1,
4315
+ catalogNameOf: catalogNameOf$2,
4316
+ resolveWorkspace: resolveWorkspace$1,
4317
+ workspaceTargetOf: workspaceTargetOf$1,
4318
+ isValid: isValidDependencySpecifier$1,
4319
+ decode: decode$5,
4320
+ FromString: fromString$1
4329
4321
  });
4330
4322
  //#endregion
4331
- //#region ../../node_modules/.pnpm/@effected+npm@0.8.2_@effected+semver@0.3.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/IntegrityHash.js
4332
- const SRI_RE = /^(sha1|sha256|sha384|sha512)-[A-Za-z0-9+/]+={0,2}$/;
4333
- const COREPACK_RE = /^(sha1|sha224|sha256|sha384|sha512)\.[0-9a-f]+$/;
4334
- const YARN_RE = /^[0-9]+(c[0-9]+)?\/[0-9a-f]+$/;
4335
- const isSri = (value) => SRI_RE.test(value);
4336
- const isCorepack = (value) => COREPACK_RE.test(value);
4337
- const isYarnChecksum = (value) => YARN_RE.test(value);
4323
+ //#region ../../node_modules/.pnpm/@effected+npm@0.8.3_@effected+semver@0.3.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/IntegrityHash.js
4324
+ const SRI_RE$1 = /^(sha1|sha256|sha384|sha512)-[A-Za-z0-9+/]+={0,2}$/;
4325
+ const COREPACK_RE$1 = /^(sha1|sha224|sha256|sha384|sha512)\.[0-9a-f]+$/;
4326
+ const YARN_RE$1 = /^[0-9]+(c[0-9]+)?\/[0-9a-f]+$/;
4327
+ const isSri$1 = (value) => SRI_RE$1.test(value);
4328
+ const isCorepack$1 = (value) => COREPACK_RE$1.test(value);
4329
+ const isYarnChecksum$1 = (value) => YARN_RE$1.test(value);
4338
4330
  /**
4339
4331
  * Whether a string is a valid integrity hash in the SRI (`<algo>-<base64>`),
4340
4332
  * corepack (`<algo>.<hex>`) or yarn (`<cachekey>/<hex>`) form.
4341
4333
  *
4342
4334
  * @public
4343
4335
  */
4344
- const isValidIntegrityHash = (value) => isSri(value) || isCorepack(value) || isYarnChecksum(value);
4345
- const algorithmOf = (value) => {
4346
- if (isSri(value)) return effect.Option.some(value.slice(0, value.indexOf("-")));
4347
- if (isCorepack(value)) return effect.Option.some(value.slice(0, value.indexOf(".")));
4336
+ const isValidIntegrityHash$1 = (value) => isSri$1(value) || isCorepack$1(value) || isYarnChecksum$1(value);
4337
+ const algorithmOf$1 = (value) => {
4338
+ if (isSri$1(value)) return effect.Option.some(value.slice(0, value.indexOf("-")));
4339
+ if (isCorepack$1(value)) return effect.Option.some(value.slice(0, value.indexOf(".")));
4348
4340
  return effect.Option.none();
4349
4341
  };
4350
4342
  /**
@@ -4355,15 +4347,15 @@ const algorithmOf = (value) => {
4355
4347
  *
4356
4348
  * @public
4357
4349
  */
4358
- var InvalidIntegrityHashError = class extends effect.Schema.TaggedErrorClass()("InvalidIntegrityHashError", {
4350
+ var InvalidIntegrityHashError$1 = class extends effect.Schema.TaggedErrorClass()("InvalidIntegrityHashError", {
4359
4351
  /** The raw input string that failed validation. */
4360
4352
  input: effect.Schema.String }) {
4361
4353
  get message() {
4362
4354
  return `Invalid integrity hash "${this.input}": expected an SRI (<algo>-<base64>), corepack (<algo>.<hex>) or yarn (<cachekey>/<hex>) form`;
4363
4355
  }
4364
4356
  };
4365
- const brandedIntegrity = effect.Schema.String.pipe(effect.Schema.check(effect.Schema.makeFilter((value) => isValidIntegrityHash(value) ? void 0 : "Expected an SRI, corepack or yarn integrity hash")), effect.Schema.brand("IntegrityHash"));
4366
- const decode$2 = (input) => effect.Schema.decodeUnknownEffect(brandedIntegrity)(input).pipe(effect.Effect.mapError(() => new InvalidIntegrityHashError({ input })));
4357
+ const brandedIntegrity$1 = effect.Schema.String.pipe(effect.Schema.check(effect.Schema.makeFilter((value) => isValidIntegrityHash$1(value) ? void 0 : "Expected an SRI, corepack or yarn integrity hash")), effect.Schema.brand("IntegrityHash"));
4358
+ const decode$4 = (input) => effect.Schema.decodeUnknownEffect(brandedIntegrity$1)(input).pipe(effect.Effect.mapError(() => new InvalidIntegrityHashError$1({ input })));
4367
4359
  /**
4368
4360
  * A subresource-integrity hash, covering the SRI (`sha512-<base64>`), corepack
4369
4361
  * (`sha512.<hex>`) and yarn (`10c0/<hex>`) textual forms, carrying taxonomy
@@ -4372,66 +4364,15 @@ const decode$2 = (input) => effect.Schema.decodeUnknownEffect(brandedIntegrity)(
4372
4364
  *
4373
4365
  * @public
4374
4366
  */
4375
- const IntegrityHash = Object.assign(brandedIntegrity, {
4376
- isSri,
4377
- isCorepack,
4378
- isYarnChecksum,
4379
- isValid: isValidIntegrityHash,
4380
- algorithmOf,
4381
- decode: decode$2
4367
+ const IntegrityHash$1 = Object.assign(brandedIntegrity$1, {
4368
+ isSri: isSri$1,
4369
+ isCorepack: isCorepack$1,
4370
+ isYarnChecksum: isYarnChecksum$1,
4371
+ isValid: isValidIntegrityHash$1,
4372
+ algorithmOf: algorithmOf$1,
4373
+ decode: decode$4
4382
4374
  });
4383
- /**
4384
- * {@link (IntegrityHash:variable)} narrowed to the corepack `<algo>.<hex>` form
4385
- * — `sha512.deadbeef`, and corepack's own sha224 default pins
4386
- * (`sha224.877304e3…`). An SRI (`sha512-<base64>`) or yarn (`10c0/<hex>`)
4387
- * hash, both valid `IntegrityHash` values, fails this schema.
4388
- *
4389
- * @remarks
4390
- * The corepack pin tail (`<name>@<version>+<integrity>`) is the one place the
4391
- * kit meets this form, and two schemas name it: `PackageManagerPin.integrity`
4392
- * here and `@effected/package-json`'s `PackageManager.integrity`. Both consume
4393
- * **this** schema — the restriction existed privately in each module until they
4394
- * were consolidated, and a private copy is exactly how the two drift (the
4395
- * widening that admitted sha224 had to be made twice).
4396
- *
4397
- * It decodes to the same {@link IntegrityHashBrand} the unrestricted schema
4398
- * does, so a corepack-validated value assigns anywhere an `IntegrityHash` is
4399
- * expected; there is no second brand. Reach for
4400
- * `IntegrityHash.isCorepack(value)` to ask the same question about a raw
4401
- * string without decoding.
4402
- *
4403
- * That single brand is also why sharing this schema is not type-enforced, and
4404
- * the consequence is sharper than it looks: a `Schema.check` is **erased from
4405
- * the built type**, so this schema and the unrestricted one are the same
4406
- * declared type. A consumer that quietly reverts to a private copy compiles
4407
- * clean, and — if the copy is faithful — passes every rejection test too.
4408
- * Neither `tsc` nor behaviour can see the re-fork.
4409
- *
4410
- * What does see it is **object identity**, so each consumer's suite asserts
4411
- * that its field schema IS this export:
4412
- * `PackageManagerPin.fields.integrity.schema === CorepackIntegrityHash` (an
4413
- * `optionalKey` field keeps the inner schema on `.schema`), and
4414
- * `PackageManager.fields.integrity.value === CorepackIntegrityHash` on the
4415
- * `@effected/package-json` side (a `Schema.Option` keeps it on `.value`). Both
4416
- * assertions carry a control against the unrestricted brand, so they discriminate
4417
- * rather than passing on any schema at all. That identity assertion is the only
4418
- * thing standing between the two surfaces and a silent re-fork; do not replace
4419
- * it with a behavioural test, which cannot fail.
4420
- *
4421
- * @example
4422
- * ```ts
4423
- * import { CorepackIntegrityHash } from "@effected/npm";
4424
- * import { Schema } from "effect";
4425
- *
4426
- * const decode = Schema.decodeUnknownExit(CorepackIntegrityHash);
4427
- *
4428
- * decode("sha512.deadbeef"); // success
4429
- * decode("sha512-3q2+7w=="); // failure — SRI form
4430
- * ```
4431
- *
4432
- * @public
4433
- */
4434
- const CorepackIntegrityHash = brandedIntegrity.pipe(effect.Schema.check(effect.Schema.makeFilter((value) => isCorepack(value) ? void 0 : "Expected a corepack (<algo>.<hex>) integrity hash")));
4375
+ brandedIntegrity$1.pipe(effect.Schema.check(effect.Schema.makeFilter((value) => isCorepack$1(value) ? void 0 : "Expected a corepack (<algo>.<hex>) integrity hash")));
4435
4376
  effect.Schema.Literals([
4436
4377
  "npm",
4437
4378
  "pnpm",
@@ -4627,96 +4568,767 @@ var LocalExec = class LocalExec extends effect.Context.Service()("@effected/comm
4627
4568
  static layerTest = (overrides = {}) => effect.Layer.succeed(LocalExec, LocalExec.makeTest(overrides));
4628
4569
  };
4629
4570
  //#endregion
4630
- //#region ../../node_modules/.pnpm/@effected+npm@0.8.2_@effected+semver@0.3.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/ReleaseAgeGate.js
4631
- const MS_PER_MINUTE = 6e4;
4571
+ //#region ../../node_modules/.pnpm/@effected+commands@0.3.1_effect@4.0.0-beta.101/node_modules/@effected/commands/Redaction.js
4632
4572
  /**
4633
- * A source's partial contribution to a {@link ReleaseAgeGate}: the effective
4634
- * gate is assembled from more than one place (inline `pnpm-workspace.yaml`
4635
- * keys, replayed `updateConfig` hooks, `pnpm config get` output), and each
4636
- * source may set the age, the exclude list, both, or neither. Absent fields
4637
- * contribute nothing to the combination.
4573
+ * Argument tokens whose *following* positional (or `=`-joined value) is a
4574
+ * secret. Lowercase; matching is case-insensitive.
4638
4575
  *
4639
- * Deliberately permissive: unlike {@link ReleaseAgeGate} it does not constrain
4640
- * `ageMinutes` to be non-negative, because the raw values arrive from arbitrary
4641
- * config sources and {@link ReleaseAgeGate.combine} is the single authority
4642
- * that clamps them.
4576
+ * @remarks
4577
+ * This is the heuristic backstop, not the primary mechanism it can only know
4578
+ * about flags someone thought to list. The primary mechanism is
4579
+ * {@link Redaction.applyArgs}, which redacts by **value**: the caller says what
4580
+ * its secrets are and every occurrence goes, whatever flag carried it.
4643
4581
  *
4644
4582
  * @public
4645
4583
  */
4646
- const PartialReleaseAgeGate = effect.Schema.Struct({
4647
- /** Minutes a release must age; absent means this source sets no age. */
4648
- ageMinutes: effect.Schema.optionalKey(effect.Schema.Number),
4649
- /** Exempt package-name patterns; absent means this source adds no exemptions. */
4650
- exclude: effect.Schema.optionalKey(effect.Schema.Array(effect.Schema.String))
4651
- });
4652
- const AgeMinutes = effect.Schema.Number.check(effect.Schema.isGreaterThanOrEqualTo(0), effect.Schema.isFinite());
4653
- const matchesPattern = (name, pattern) => {
4654
- if (pattern === name) return true;
4655
- if (!pattern.includes("*")) return false;
4656
- let nameIndex = 0;
4657
- let patternIndex = 0;
4658
- let starIndex = -1;
4659
- let retryNameIndex = 0;
4660
- while (nameIndex < name.length) if (pattern[patternIndex] === "*") {
4661
- starIndex = patternIndex;
4662
- patternIndex += 1;
4663
- retryNameIndex = nameIndex;
4664
- } else if (pattern[patternIndex] === name[nameIndex]) {
4665
- patternIndex += 1;
4666
- nameIndex += 1;
4667
- } else if (starIndex !== -1) {
4668
- patternIndex = starIndex + 1;
4669
- retryNameIndex += 1;
4670
- nameIndex = retryNameIndex;
4671
- } else return false;
4672
- while (pattern[patternIndex] === "*") patternIndex += 1;
4673
- return patternIndex === pattern.length;
4674
- };
4675
- const matchesExclude = (name, patterns) => patterns.some((pattern) => matchesPattern(name, pattern));
4584
+ const SECRET_FLAGS = /* @__PURE__ */ new Set([
4585
+ "--access-token",
4586
+ "--api-key",
4587
+ "--auth",
4588
+ "--auth-token",
4589
+ "--otp",
4590
+ "--password",
4591
+ "--registry-token",
4592
+ "--token"
4593
+ ]);
4676
4594
  /**
4677
- * pnpm's publish-time release-age gate: the number of minutes a published
4678
- * version must age before it is eligible, and the set of package-name patterns
4679
- * exempt from the gate. Mirrors pnpm's `minimumReleaseAge` /
4680
- * `minimumReleaseAgeExclude` config so a resolver can drop too-young candidate
4681
- * versions before picking, avoiding `ERR_PNPM_NO_MATURE_MATCHING_VERSION`.
4682
- *
4683
- * `ageMinutes` is constrained non-negative and finite; a `ReleaseAgeGate` with
4684
- * `ageMinutes <= 0` is an inert gate that filters nothing. Assemble a gate from
4685
- * multiple config sources with {@link ReleaseAgeGate.combine}, and apply it to
4686
- * a package's candidate versions with {@link ReleaseAgeGate.filterVersions}.
4687
- *
4688
- * @example
4689
- * ```ts
4690
- * import { ReleaseAgeGate } from "@effected/npm";
4595
+ * npm config keys whose value is a credential (`//registry/:_authToken`,
4596
+ * `//registry/:_password`).
4597
+ */
4598
+ const AUTH_KEY = /:(?:_authtoken|_password)$/i;
4599
+ /**
4600
+ * The distinct, non-empty secret values, longest first.
4691
4601
  *
4692
- * const gate = ReleaseAgeGate.combine(
4693
- * { ageMinutes: 1440 },
4694
- * { exclude: ["@my-scope/*"] },
4695
- * );
4696
- * // gate.ageMinutes === 1440, gate.exclude === ["@my-scope/*"]
4602
+ * @remarks
4603
+ * Longest-first is load-bearing: redacting `"ab"` before `"abcd"` rewrites
4604
+ * `"abcd"` to `"***cd"`, leaking `"cd"` — a fragment of the longer secret.
4605
+ * Empty values are dropped because `"abc".split("").join("***")` would insert
4606
+ * the placeholder between every character.
4607
+ */
4608
+ const prepare = (secrets) => [...new Set(secrets.map(effect.Redacted.value))].filter((value) => value.length > 0).sort((a, b) => b.length - a.length);
4609
+ /** Replaces each prepared value with {@link REDACTED}, literally (never as a pattern). */
4610
+ const replaceAll = (text, values) => {
4611
+ let out = text;
4612
+ for (const value of values) out = out.split(value).join("***");
4613
+ return out;
4614
+ };
4615
+ const apply = (text, secrets) => secrets.length === 0 ? text : replaceAll(text, prepare(secrets));
4616
+ const applyArgs = (args, secrets) => {
4617
+ if (secrets.length === 0) return args;
4618
+ const values = prepare(secrets);
4619
+ return args.map((arg) => replaceAll(arg, values));
4620
+ };
4621
+ /** Whether `name` introduces a credential value. */
4622
+ const isSecretName = (name, extra) => {
4623
+ const lower = name.toLowerCase();
4624
+ return SECRET_FLAGS.has(lower) || extra.has(lower) || AUTH_KEY.test(name);
4625
+ };
4626
+ const scrubArgs = (args, options) => {
4627
+ const extra = new Set((options?.flags ?? []).map((flag) => flag.toLowerCase()));
4628
+ const out = [];
4629
+ for (let index = 0; index < args.length; index++) {
4630
+ const arg = args[index] ?? "";
4631
+ const equals = arg.indexOf("=");
4632
+ if (equals > 0 && isSecretName(arg.slice(0, equals), extra)) {
4633
+ out.push(`${arg.slice(0, equals)}=***`);
4634
+ continue;
4635
+ }
4636
+ out.push(arg);
4637
+ if (isSecretName(arg, extra) && index + 1 < args.length) {
4638
+ out.push("***");
4639
+ index++;
4640
+ }
4641
+ }
4642
+ return out;
4643
+ };
4644
+ /**
4645
+ * Secret scrubbing for command arguments and captured output.
4697
4646
  *
4698
- * const eligible = gate.filterVersions(
4699
- * ["1.0.0", "1.0.1"],
4700
- * { "1.0.0": "2020-01-01T00:00:00Z", "1.0.1": "2026-07-21T00:00:00Z" },
4701
- * "prettier",
4702
- * Date.now(),
4703
- * );
4704
- * ```
4647
+ * @remarks
4648
+ * Two mechanisms, deliberately layered. {@link Redaction.apply} and
4649
+ * {@link Redaction.applyArgs} redact **by value** — the caller declares its
4650
+ * secrets as `Redacted` and every occurrence is removed wherever it appears.
4651
+ * {@link Redaction.scrubArgs} is a **flag heuristic** that runs in addition, for
4652
+ * the secrets a caller forgot to declare.
4705
4653
  *
4706
4654
  * @public
4707
4655
  */
4708
- var ReleaseAgeGate = class ReleaseAgeGate extends effect.Schema.Class("ReleaseAgeGate")({
4709
- /** Minutes a published version must age before it is eligible (non-negative, finite). */
4710
- ageMinutes: AgeMinutes,
4711
- /** Package-name patterns exempt from the gate (exact names or `*`-globs). */
4712
- exclude: effect.Schema.Array(effect.Schema.String)
4713
- }) {
4656
+ var Redaction = class {
4657
+ constructor() {}
4714
4658
  /**
4715
- * Combine partial contributions from multiple sources into one effective
4716
- * gate: **strictest age wins** (the maximum of the contributed ages,
4717
- * clamped to be non-negative) and the exclude sets **union** (deduplicated,
4718
- * lexicographically sorted — a canonical wire form, so the combined gate is
4719
- * deterministic regardless of the order contributions arrive in). A
4659
+ * Replaces every occurrence of every secret's value in `text` with
4660
+ * {@link REDACTED}.
4661
+ *
4662
+ * @remarks
4663
+ * Exact, literal matching no pattern compilation, no encoding-aware search. A
4664
+ * secret that reaches the text base64-encoded, URL-encoded, or split across a
4665
+ * line break is **not** found; declare the encoded form as a secret too if that
4666
+ * is a real risk.
4667
+ *
4668
+ * A secret composed only of the placeholder's own characters (`*`, `**`, `***`)
4669
+ * cannot be fully removed, because the replacement reintroduces it. That is a
4670
+ * documented limitation, not a defect.
4671
+ */
4672
+ static apply = apply;
4673
+ /**
4674
+ * {@link Redaction.apply} over each entry of an argv array. An entry is
4675
+ * redacted whether it *is* a secret or merely *contains* one
4676
+ * (`--url=https://u:s3cr3t@host`).
4677
+ */
4678
+ static applyArgs = applyArgs;
4679
+ /**
4680
+ * Heuristic backstop: redact any argv value that is introduced by a known
4681
+ * secret-bearing flag or npm auth key, in either the separated
4682
+ * (`--token abc`) or inline (`--token=abc`) form.
4683
+ *
4684
+ * @remarks
4685
+ * This catches secrets the caller forgot to declare; it cannot catch a flag
4686
+ * nobody listed. Prefer {@link Redaction.applyArgs} with the actual
4687
+ * `Redacted` values — this runs *in addition*, never instead.
4688
+ */
4689
+ static scrubArgs = scrubArgs;
4690
+ /** Flags treated as secret-bearing by {@link Redaction.scrubArgs}. See {@link SECRET_FLAGS}. */
4691
+ static SECRET_FLAGS = SECRET_FLAGS;
4692
+ };
4693
+ //#endregion
4694
+ //#region ../../node_modules/.pnpm/@effected+commands@0.3.1_effect@4.0.0-beta.101/node_modules/@effected/commands/internal/capture.js
4695
+ /**
4696
+ * Raised when a captured stream exceeds its byte budget.
4697
+ *
4698
+ * @remarks
4699
+ * Internal and never exported from the package: `Run` maps it to the public
4700
+ * `CommandOutputError`. `Data.TaggedError` is appropriate precisely because it
4701
+ * never escapes — it is an in-process signal, not a contract.
4702
+ */
4703
+ var OutputTooLarge = class extends effect.Data.TaggedError("OutputTooLarge") {};
4704
+ /**
4705
+ * Collects a byte stream into a string, failing once more than `limit` bytes
4706
+ * have arrived.
4707
+ *
4708
+ * @remarks
4709
+ * The budget is enforced **during** accumulation, not after: checking the
4710
+ * length of an already-collected string would mean the memory was already
4711
+ * spent, which is the exact failure the budget exists to prevent. Counting is
4712
+ * on raw bytes, before decoding, because bytes are what the process actually
4713
+ * produced.
4714
+ */
4715
+ const collectBounded = (stream, limit) => effect.Effect.gen(function* () {
4716
+ const seen = yield* effect.Ref.make(0);
4717
+ const bounded = effect.Stream.mapEffect(stream, (chunk) => effect.Effect.flatMap(effect.Ref.updateAndGet(seen, (total) => total + chunk.length), (total) => total > limit ? effect.Effect.fail(new OutputTooLarge({ limit })) : effect.Effect.succeed(chunk)));
4718
+ return yield* effect.Stream.mkString(effect.Stream.decodeText(bounded));
4719
+ });
4720
+ //#endregion
4721
+ //#region ../../node_modules/.pnpm/@effected+commands@0.3.1_effect@4.0.0-beta.101/node_modules/@effected/commands/Run.js
4722
+ /**
4723
+ * Default ceiling on captured bytes per stream (16 MiB).
4724
+ *
4725
+ * @remarks
4726
+ * Collecting a child's output without a bound is a memory-exhaustion vector.
4727
+ * Output genuinely larger than this belongs on {@link Run.stream}, which never
4728
+ * accumulates.
4729
+ *
4730
+ * @public
4731
+ */
4732
+ const DEFAULT_MAX_OUTPUT_BYTES = 16777216;
4733
+ /** Characters shown from the tail of captured output in an error message. */
4734
+ const MAX_MESSAGE_CHARS = 2e3;
4735
+ /**
4736
+ * What one completed run produced.
4737
+ *
4738
+ * @public
4739
+ */
4740
+ var CommandOutput = class extends effect.Schema.Class("CommandOutput")({
4741
+ /** Captured standard output, redacted. */
4742
+ stdout: effect.Schema.String,
4743
+ /** Captured standard error, redacted. */
4744
+ stderr: effect.Schema.String,
4745
+ /** The process exit code. A non-zero value is NOT an error at this level. */
4746
+ exitCode: effect.Schema.Number
4747
+ }) {
4748
+ /** Whether the process exited zero. */
4749
+ get succeeded() {
4750
+ return this.exitCode === 0;
4751
+ }
4752
+ };
4753
+ /** The executable and argv an error should report for `command`. */
4754
+ const describeCommand = (command) => {
4755
+ if (effect_unstable_process.ChildProcess.isStandardCommand(command)) return {
4756
+ command: command.command,
4757
+ args: command.args
4758
+ };
4759
+ const left = describeCommand(command.left);
4760
+ const right = describeCommand(command.right);
4761
+ return {
4762
+ command: `${left.command} | ${right.command}`,
4763
+ args: []
4764
+ };
4765
+ };
4766
+ /** argv as an error should store it: declared secrets removed, then the flag heuristic. */
4767
+ const safeArgs = (args, secrets) => Redaction.scrubArgs(Redaction.applyArgs(args, secrets ?? []));
4768
+ /** Captured text as an error should store it. */
4769
+ const safeText = (text, secrets) => Redaction.apply(text, secrets ?? []);
4770
+ /** Tail-bounded rendering: tools write warnings first and the real error last. */
4771
+ const tail = (text) => {
4772
+ const trimmed = text.trim();
4773
+ if (trimmed.length <= MAX_MESSAGE_CHARS) return trimmed;
4774
+ return `...[${trimmed.length - MAX_MESSAGE_CHARS} chars truncated from head]...\n${trimmed.slice(-2e3)}`;
4775
+ };
4776
+ /**
4777
+ * A command that could not be run, or that ran and failed.
4778
+ *
4779
+ * @remarks
4780
+ * `kind` is the routing surface, never the message: `"nonZero"` (the process
4781
+ * ran and exited non-zero), `"spawn"` (it never started — the executable is
4782
+ * missing, or the platform refused), `"timeout"` (a caller-supplied ceiling
4783
+ * elapsed). Composed retry and fallback logic branches on `kind`; nothing in
4784
+ * this package asks a caller to match on prose.
4785
+ *
4786
+ * `args` is **always** stored redacted.
4787
+ *
4788
+ * @public
4789
+ */
4790
+ var CommandFailedError = class CommandFailedError extends effect.Schema.TaggedErrorClass()("CommandFailedError", {
4791
+ /** Why it failed. */
4792
+ kind: effect.Schema.Literals([
4793
+ "nonZero",
4794
+ "spawn",
4795
+ "timeout"
4796
+ ]),
4797
+ /** The executable (or `"a | b"` for a pipeline). */
4798
+ command: effect.Schema.String,
4799
+ /** argv, redacted. */
4800
+ args: effect.Schema.Array(effect.Schema.String),
4801
+ /** The exit code, when the process ran. */
4802
+ exitCode: effect.Schema.optionalKey(effect.Schema.Number),
4803
+ /** Captured standard error, redacted, when the process ran. */
4804
+ stderr: effect.Schema.optionalKey(effect.Schema.String),
4805
+ /** Captured standard output, redacted, when the process ran. */
4806
+ stdout: effect.Schema.optionalKey(effect.Schema.String),
4807
+ /** The absorbed platform failure, for `"spawn"`. */
4808
+ cause: effect.Schema.optionalKey(effect.Schema.Defect())
4809
+ }) {
4810
+ /** The process ran and exited non-zero. */
4811
+ static nonZero = (command, output, secrets) => {
4812
+ const described = describeCommand(command);
4813
+ return new CommandFailedError({
4814
+ kind: "nonZero",
4815
+ command: described.command,
4816
+ args: safeArgs(described.args, secrets),
4817
+ exitCode: output.exitCode,
4818
+ stderr: output.stderr,
4819
+ stdout: output.stdout
4820
+ });
4821
+ };
4822
+ /** The process never started. */
4823
+ static spawn = (command, cause, secrets) => {
4824
+ const described = describeCommand(command);
4825
+ return new CommandFailedError({
4826
+ kind: "spawn",
4827
+ command: described.command,
4828
+ args: safeArgs(described.args, secrets),
4829
+ cause
4830
+ });
4831
+ };
4832
+ /** A caller-supplied ceiling elapsed; the child was killed with its scope. */
4833
+ static timedOut = (command, secrets) => {
4834
+ const described = describeCommand(command);
4835
+ return new CommandFailedError({
4836
+ kind: "timeout",
4837
+ command: described.command,
4838
+ args: safeArgs(described.args, secrets)
4839
+ });
4840
+ };
4841
+ /**
4842
+ * Whether this is a spawn failure caused by the executable not existing —
4843
+ * the structural "tool is not installed" signal.
4844
+ */
4845
+ get notFound() {
4846
+ return this.kind === "spawn" && this.cause instanceof effect.PlatformError.PlatformError && this.cause.reason._tag === "NotFound";
4847
+ }
4848
+ /** Names the command and surfaces the tail of whichever stream carries the cause. */
4849
+ get message() {
4850
+ const parts = [`Command "${this.args.length > 0 ? `${this.command} ${this.args.join(" ")}` : this.command}" failed`];
4851
+ if (this.kind === "timeout") parts.push("(timed out)");
4852
+ if (this.exitCode !== void 0) parts.push(`(exit ${this.exitCode})`);
4853
+ const stream = this.stderr?.trim() ? this.stderr : this.stdout?.trim() ? this.stdout : void 0;
4854
+ if (stream !== void 0) parts.push(`:\n${tail(stream)}`);
4855
+ return parts.join(" ");
4856
+ }
4857
+ };
4858
+ /**
4859
+ * A command ran, but its output could not be used.
4860
+ *
4861
+ * @remarks
4862
+ * Separate from {@link CommandFailedError} because the process itself
4863
+ * succeeded: `"notJson"` (stdout is not JSON), `"schema"` (it is JSON but does
4864
+ * not decode), `"tooLarge"` (capture exceeded its byte budget). Keeping the two
4865
+ * distinguishable is the point — a schema drift and a crashed tool call for
4866
+ * different responses.
4867
+ *
4868
+ * The context fields (`exitCode`, `stderr`, `stdout`) are populated by
4869
+ * {@link Run.jsonLine}, whose payload framing parses regardless of exit code —
4870
+ * when no payload arrives, the exit code and captured streams are the only
4871
+ * evidence of what actually went wrong. Both streams are **always** stored
4872
+ * redacted.
4873
+ *
4874
+ * @public
4875
+ */
4876
+ var CommandOutputError = class extends effect.Schema.TaggedErrorClass()("CommandOutputError", {
4877
+ /** Which way the output was unusable. */
4878
+ kind: effect.Schema.Literals([
4879
+ "notJson",
4880
+ "schema",
4881
+ "tooLarge"
4882
+ ]),
4883
+ /** The executable that produced it. */
4884
+ command: effect.Schema.String,
4885
+ /** The underlying parse or decode failure. */
4886
+ cause: effect.Schema.optionalKey(effect.Schema.Defect()),
4887
+ /** The exit code, when the combinator parses independently of it. */
4888
+ exitCode: effect.Schema.optionalKey(effect.Schema.Number),
4889
+ /** Captured standard error, redacted, when the process ran. */
4890
+ stderr: effect.Schema.optionalKey(effect.Schema.String),
4891
+ /** Captured standard output, redacted, when the process ran. */
4892
+ stdout: effect.Schema.optionalKey(effect.Schema.String)
4893
+ }) {
4894
+ get message() {
4895
+ const parts = [];
4896
+ if (this.kind === "notJson") parts.push(`Command "${this.command}" did not produce JSON`);
4897
+ else if (this.kind === "schema") parts.push(`Command "${this.command}" produced JSON that did not match the expected schema`);
4898
+ else parts.push(`Command "${this.command}" produced more output than the configured limit`);
4899
+ if (this.exitCode !== void 0) parts.push(`(exit ${this.exitCode})`);
4900
+ if (this.stderr !== void 0 && this.stderr.trim().length > 0) parts.push(`:\n${tail(this.stderr)}`);
4901
+ return parts.join(" ");
4902
+ }
4903
+ };
4904
+ /** Spawns, collects both streams concurrently, and awaits exit. */
4905
+ const collectRaw = (command, options, tee) => effect.Effect.scoped(effect.Effect.gen(function* () {
4906
+ const handle = yield* (yield* effect_unstable_process.ChildProcessSpawner.ChildProcessSpawner).spawn(command);
4907
+ const limit = options?.maxOutputBytes ?? 16777216;
4908
+ const out = tee === void 0 ? handle.stdout : effect.Stream.tapSink(handle.stdout, tee.stdout());
4909
+ const err = tee === void 0 ? handle.stderr : effect.Stream.tapSink(handle.stderr, tee.stderr());
4910
+ const [stdout, stderr, exitCode] = yield* effect.Effect.all([
4911
+ collectBounded(out, limit),
4912
+ collectBounded(err, limit),
4913
+ handle.exitCode
4914
+ ], { concurrency: "unbounded" });
4915
+ const secrets = options?.redact;
4916
+ return CommandOutput.make({
4917
+ stdout: safeText(stdout, secrets),
4918
+ stderr: safeText(stderr, secrets),
4919
+ exitCode: Number(exitCode)
4920
+ });
4921
+ }));
4922
+ /** Maps the raw failure modes onto this package's taxonomy, and applies any ceiling. */
4923
+ const collectClassified = (command, options, tee) => {
4924
+ const described = describeCommand(command);
4925
+ const classified = collectRaw(command, options, tee).pipe(effect.Effect.catch((error) => effect.Effect.fail(error instanceof OutputTooLarge ? new CommandOutputError({
4926
+ kind: "tooLarge",
4927
+ command: described.command,
4928
+ cause: error
4929
+ }) : CommandFailedError.spawn(command, error, options?.redact))));
4930
+ return options?.timeout === void 0 ? classified : effect.Effect.timeoutOrElse(classified, {
4931
+ duration: options.timeout,
4932
+ orElse: () => effect.Effect.fail(CommandFailedError.timedOut(command, options.redact))
4933
+ });
4934
+ };
4935
+ /** Fails a run whose process exited non-zero. */
4936
+ const requireZero = (command, output, options) => output.succeeded ? effect.Effect.succeed(output) : effect.Effect.fail(CommandFailedError.nonZero(command, output, options?.redact));
4937
+ /** Span attributes: what ran and how many arguments — never the arguments. */
4938
+ const annotate = (command) => {
4939
+ const described = describeCommand(command);
4940
+ return effect.Effect.annotateCurrentSpan({
4941
+ command: described.command,
4942
+ argc: described.args.length
4943
+ });
4944
+ };
4945
+ const collect = effect.Effect.fn("Run.collect")(function* (command, options) {
4946
+ yield* annotate(command);
4947
+ return yield* collectClassified(command, options, void 0);
4948
+ });
4949
+ const collectTee = effect.Effect.fn("Run.collectTee")(function* (command, options) {
4950
+ yield* annotate(command);
4951
+ const stdio = yield* effect.Stdio.Stdio;
4952
+ return yield* collectClassified(command, options, stdio);
4953
+ });
4954
+ const text$4 = effect.Effect.fn("Run.text")(function* (command, options) {
4955
+ yield* annotate(command);
4956
+ const output = yield* collectClassified(command, options, void 0);
4957
+ return (yield* requireZero(command, output, options)).stdout.trim();
4958
+ });
4959
+ const lines = effect.Effect.fn("Run.lines")(function* (command, options) {
4960
+ yield* annotate(command);
4961
+ const output = yield* collectClassified(command, options, void 0);
4962
+ return (yield* requireZero(command, output, options)).stdout.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0);
4963
+ });
4964
+ const json = effect.Effect.fn("Run.json")(function* (command, schema, options) {
4965
+ yield* annotate(command);
4966
+ const described = describeCommand(command);
4967
+ const output = yield* collectClassified(command, options, void 0);
4968
+ const checked = yield* requireZero(command, output, options);
4969
+ const parsed = yield* effect.Effect.try({
4970
+ try: () => JSON.parse(checked.stdout),
4971
+ catch: (cause) => new CommandOutputError({
4972
+ kind: "notJson",
4973
+ command: described.command,
4974
+ cause
4975
+ })
4976
+ });
4977
+ return yield* effect.Schema.decodeUnknownEffect(schema)(parsed).pipe(effect.Effect.catch((cause) => effect.Effect.fail(new CommandOutputError({
4978
+ kind: "schema",
4979
+ command: described.command,
4980
+ cause
4981
+ }))));
4982
+ });
4983
+ const jsonLine = effect.Effect.fn("Run.jsonLine")(function* (command, schema, options) {
4984
+ yield* annotate(command);
4985
+ const described = describeCommand(command);
4986
+ const output = yield* collectClassified(command, options, void 0);
4987
+ const context = {
4988
+ exitCode: output.exitCode,
4989
+ stderr: output.stderr,
4990
+ stdout: output.stdout
4991
+ };
4992
+ const candidates = output.stdout.split(/\r?\n/).filter((candidate) => candidate.trim().length > 0);
4993
+ if (candidates.length === 0) return yield* effect.Effect.fail(new CommandOutputError({
4994
+ kind: "notJson",
4995
+ command: described.command,
4996
+ cause: /* @__PURE__ */ new Error("stdout carried no non-empty line"),
4997
+ ...context
4998
+ }));
4999
+ let notJsonCause;
5000
+ let schemaCause;
5001
+ for (let index = candidates.length - 1; index >= 0; index--) {
5002
+ const candidate = candidates[index];
5003
+ if (candidate === void 0) continue;
5004
+ let parsed;
5005
+ try {
5006
+ parsed = JSON.parse(candidate);
5007
+ } catch (cause) {
5008
+ notJsonCause ??= cause;
5009
+ continue;
5010
+ }
5011
+ const decoded = yield* effect.Effect.result(effect.Schema.decodeUnknownEffect(schema)(parsed));
5012
+ if (effect.Result.isSuccess(decoded)) return decoded.success;
5013
+ schemaCause ??= decoded.failure;
5014
+ }
5015
+ return yield* effect.Effect.fail(schemaCause !== void 0 ? new CommandOutputError({
5016
+ kind: "schema",
5017
+ command: described.command,
5018
+ cause: schemaCause,
5019
+ ...context
5020
+ }) : new CommandOutputError({
5021
+ kind: "notJson",
5022
+ command: described.command,
5023
+ cause: notJsonCause,
5024
+ ...context
5025
+ }));
5026
+ });
5027
+ const exitCode = effect.Effect.fn("Run.exitCode")(function* (command, options) {
5028
+ yield* annotate(command);
5029
+ return (yield* collectClassified(command, options, void 0)).exitCode;
5030
+ });
5031
+ const succeeds = effect.Effect.fn("Run.succeeds")(function* (command, options) {
5032
+ yield* annotate(command);
5033
+ return yield* collectClassified(command, options, void 0).pipe(effect.Effect.map((output) => output.succeeded), effect.Effect.catch(() => effect.Effect.succeed(false)));
5034
+ });
5035
+ const detach = effect.Effect.fn("Run.detach")(function* (command) {
5036
+ yield* annotate(command);
5037
+ return yield* effect.Effect.scoped(effect.Effect.gen(function* () {
5038
+ const handle = yield* (yield* effect_unstable_process.ChildProcessSpawner.ChildProcessSpawner).spawn(command);
5039
+ yield* handle.unref;
5040
+ return handle.pid;
5041
+ })).pipe(effect.Effect.catch((error) => effect.Effect.fail(CommandFailedError.spawn(command, error))));
5042
+ });
5043
+ const stream = (command, options) => effect.Stream.unwrap(effect.Effect.map(effect_unstable_process.ChildProcessSpawner.ChildProcessSpawner, (spawner) => spawner.streamLines(command, { includeStderr: options?.includeStderr ?? false }))).pipe(effect.Stream.mapError((error) => CommandFailedError.spawn(command, error)));
5044
+ const extendEnv = effect.Function.dual(2, (self, env) => {
5045
+ if (effect_unstable_process.ChildProcess.isStandardCommand(self)) {
5046
+ const merged = self.options.env === void 0 ? env : {
5047
+ ...self.options.env,
5048
+ ...env
5049
+ };
5050
+ return effect_unstable_process.ChildProcess.make(self.command, self.args, {
5051
+ ...self.options,
5052
+ env: merged,
5053
+ extendEnv: true
5054
+ });
5055
+ }
5056
+ return effect_unstable_process.ChildProcess.pipeTo(extendEnv(self.left, env), extendEnv(self.right, env), self.options);
5057
+ });
5058
+ /**
5059
+ * Structured running of core `ChildProcess.Command` values.
5060
+ *
5061
+ * @remarks
5062
+ * These are free functions over core's contract, **not** a service: core's
5063
+ * `ChildProcessSpawner` already is the subprocess service, and wrapping it in a
5064
+ * second one is the re-declaration this package exists not to repeat. Tests
5065
+ * stub the spawner (`ChildProcessSpawner.make(mockSpawn)`), not these.
5066
+ *
5067
+ * A non-zero exit is a *result* for {@link Run.collect}, {@link Run.exitCode},
5068
+ * {@link Run.succeeds} and {@link Run.jsonLine}, and a typed *failure* for
5069
+ * {@link Run.text}, {@link Run.lines} and {@link Run.json} — the split is
5070
+ * deliberate, matching core (where a non-zero exit is a success) at the
5071
+ * reporting level while giving the interpreting helpers the ergonomics callers
5072
+ * actually want.
5073
+ *
5074
+ * The interpreting helpers also **trim**: {@link Run.text} strips leading and
5075
+ * trailing whitespace from the whole result — not just a trailing newline —
5076
+ * and {@link Run.lines} trims each line. Fixed-column output whose first
5077
+ * column can be whitespace (`git status --porcelain`) silently loses that
5078
+ * column through either, producing plausible wrong values rather than an
5079
+ * error. Parse that kind of output from the untrimmed `stdout` of
5080
+ * {@link Run.collect}'s {@link CommandOutput} instead.
5081
+ *
5082
+ * @public
5083
+ */
5084
+ var Run = class {
5085
+ constructor() {}
5086
+ /**
5087
+ * Spawns `command`, collects stdout and stderr concurrently, and resolves
5088
+ * with the {@link CommandOutput} once the process exits.
5089
+ *
5090
+ * @remarks
5091
+ * A non-zero exit is a *result* here, not a failure — see {@link Run}'s
5092
+ * remarks for the split against {@link Run.text}, {@link Run.lines} and
5093
+ * {@link Run.json}.
5094
+ */
5095
+ static collect = collect;
5096
+ /**
5097
+ * Like {@link Run.collect}, but also tees each stream to the `Stdio` in `R`
5098
+ * as it arrives, for a caller that wants live output alongside the captured
5099
+ * {@link CommandOutput}.
5100
+ */
5101
+ static collectTee = collectTee;
5102
+ /**
5103
+ * Runs `command` and resolves with trimmed stdout on a zero exit.
5104
+ *
5105
+ * @remarks
5106
+ * A non-zero exit is a typed failure here — {@link CommandFailedError} —
5107
+ * unlike {@link Run.collect}, {@link Run.exitCode} and {@link Run.succeeds},
5108
+ * which treat it as a result.
5109
+ *
5110
+ * The trim strips **leading and trailing whitespace**, not just the trailing
5111
+ * newline. For parse-sensitive output where leading whitespace is data
5112
+ * (`git status --porcelain`, whose first entry's status column it would
5113
+ * silently eat), use {@link Run.collect} and read its {@link CommandOutput}'s
5114
+ * untrimmed `stdout` instead.
5115
+ */
5116
+ static text = text$4;
5117
+ /**
5118
+ * Runs `command` and resolves with stdout split into trimmed, non-empty
5119
+ * lines on a zero exit.
5120
+ *
5121
+ * @remarks
5122
+ * A non-zero exit is a typed failure here — {@link CommandFailedError} —
5123
+ * matching {@link Run.text} and {@link Run.json}.
5124
+ */
5125
+ static lines = lines;
5126
+ /**
5127
+ * Runs `command`, parses stdout as JSON and decodes it against `schema` on
5128
+ * a zero exit.
5129
+ *
5130
+ * @remarks
5131
+ * Fails with {@link CommandOutputError} when stdout is not JSON or does not
5132
+ * decode; a non-zero exit fails with {@link CommandFailedError}, matching
5133
+ * {@link Run.text} and {@link Run.lines}.
5134
+ *
5135
+ * This parses the **whole** of stdout and requires a zero exit. For a
5136
+ * protocol payload located by scanning stdout lines from the end — tolerant
5137
+ * of noise around it and of a non-zero exit — use {@link Run.jsonLine}
5138
+ * instead.
5139
+ */
5140
+ static json = json;
5141
+ /**
5142
+ * Runs `command` and, **scanning stdout lines from the end**, resolves with
5143
+ * the first line that both parses as JSON and decodes against `schema` —
5144
+ * the framing variant of {@link Run.json}, for a child that reports through
5145
+ * a single JSON protocol payload near the end of its output.
5146
+ *
5147
+ * @remarks
5148
+ * The framing tolerates noise on **both sides** of the payload: noise before
5149
+ * it (a subprocess-loaded hook's own `console.log`, a tool's warnings) and
5150
+ * noise after it (a hook logging from `process.on("exit", ...)` fires after
5151
+ * the payload has flushed — the trigger for widening the old "last non-empty
5152
+ * line must decode" contract, spencerbeggs/effected#292). Lines are split on
5153
+ * `\r?\n`, whitespace-only lines are dropped, and the scan runs from the last
5154
+ * line backwards until one decodes. The tolerance is positional, not
5155
+ * volumetric: the whole of stdout is still captured under
5156
+ * {@link RunOptions.maxOutputBytes} (default
5157
+ * {@link DEFAULT_MAX_OUTPUT_BYTES}, 16 MiB), so a child whose noise exceeds
5158
+ * the ceiling fails typed as `"tooLarge"` before any line is examined —
5159
+ * raise the ceiling for a child known to be loud in volume.
5160
+ *
5161
+ * The scan's consequence: when **multiple** lines decode under `schema`, the
5162
+ * **last** one wins. A child must therefore never emit two schema-valid
5163
+ * lines, and a consumer schema should be shaped so an accidental log line
5164
+ * cannot satisfy it — a discriminated envelope with a required literal field
5165
+ * (`ok: true | false`, the shape `@effected/workspaces`' `ReplayPayload`
5166
+ * uses) rather than a permissive record a stray `console.log(someObject)`
5167
+ * might match.
5168
+ *
5169
+ * Unlike {@link Run.json}, this parses **regardless of the exit code** — a
5170
+ * deliberate posture, not an oversight. A protocol payload discriminates
5171
+ * success in-band (its own `ok` field, its own error shape), so the payload
5172
+ * outranks the exit code: a child that crashes *after* flushing its payload
5173
+ * still reported, and a caller that wants exit-code semantics has
5174
+ * {@link Run.json}. When no line decodes anywhere, the typed
5175
+ * {@link CommandOutputError} carries the exit code and both captured streams
5176
+ * (redacted) as context, so the failure is diagnosable without re-running.
5177
+ * Its `kind` preserves the near-miss diagnostic: `"schema"` when at least
5178
+ * one line parsed as JSON but none decoded — with the **last parseable
5179
+ * line's** decode failure as `cause`, that line being the most probable
5180
+ * intended payload — and `"notJson"` only when no non-empty line was JSON at
5181
+ * all (carrying the last non-empty line's parse error). A spawn failure or
5182
+ * an opted-in timeout still fails with {@link CommandFailedError}.
5183
+ */
5184
+ static jsonLine = jsonLine;
5185
+ /**
5186
+ * Runs `command` and resolves with its exit code alone.
5187
+ *
5188
+ * @remarks
5189
+ * A non-zero exit is a *result* here, not a failure — see {@link Run}'s
5190
+ * remarks for the split against {@link Run.text}, {@link Run.lines} and
5191
+ * {@link Run.json}.
5192
+ */
5193
+ static exitCode = exitCode;
5194
+ /**
5195
+ * Runs `command` and resolves with whether it exited zero, collapsing a
5196
+ * spawn or other classified failure to `false` rather than propagating it.
5197
+ */
5198
+ static succeeds = succeeds;
5199
+ /** Decoded stdout lines as they arrive, for output too large or too long-lived to collect. */
5200
+ static stream = stream;
5201
+ /**
5202
+ * Spawns `command` and resolves with its pid without waiting for exit.
5203
+ *
5204
+ * @remarks
5205
+ * Unrefs the child **before** this scope closes, so it survives the
5206
+ * caller's scope closing — the Node backend's release skips the kill for an
5207
+ * unref'd child, and reversing that order kills it with the scope instead.
5208
+ * Fails with {@link CommandFailedError} if the process never starts.
5209
+ */
5210
+ static detach = detach;
5211
+ /**
5212
+ * Adds environment variables to a command WITHOUT losing the parent
5213
+ * environment: merges `env` over any existing command environment (new values
5214
+ * win, matching core's `ChildProcess.setEnv`) and sets `extendEnv: true`.
5215
+ *
5216
+ * @remarks
5217
+ * This combinator exists because of a core trap: `ChildProcess.setEnv` merges
5218
+ * into `options.env` but never sets `extendEnv`, and the Node spawner resolves
5219
+ * the child environment as `extendEnv ? { ...process.env, ...env } : env` — so
5220
+ * a command built with bare `setEnv({ SOME_VAR: x })` spawns a child whose
5221
+ * ENTIRE environment is that one variable: no `PATH`, no `HOME`. The failure is
5222
+ * silent at the type level and surfaces as "spawned tool cannot find its own
5223
+ * binary" at runtime.
5224
+ *
5225
+ * Deliberately forces `extendEnv: true` even where construction set it `false`
5226
+ * — inheriting the parent environment is this combinator's entire purpose. A
5227
+ * caller who wants a hermetic environment uses core's `setEnv` or construction
5228
+ * options (`ChildProcess.make(cmd, args, { env, extendEnv: false })`) directly.
5229
+ *
5230
+ * For a pipeline, applies to every command in the pipeline (mirroring core's
5231
+ * `setEnv`), preserving the pipe's own options. Composes core's public
5232
+ * vocabulary (`ChildProcess.make`, `ChildProcess.pipeTo`) — it re-declares
5233
+ * nothing.
5234
+ */
5235
+ static extendEnv = extendEnv;
5236
+ /** Default ceiling on captured bytes per stream. See {@link DEFAULT_MAX_OUTPUT_BYTES}. */
5237
+ static DEFAULT_MAX_OUTPUT_BYTES = DEFAULT_MAX_OUTPUT_BYTES;
5238
+ /** The placeholder written in place of a redacted secret. See {@link REDACTED}. */
5239
+ static REDACTED = "***";
5240
+ };
5241
+ //#endregion
5242
+ //#region ../../node_modules/.pnpm/@effected+npm@0.8.3_@effected+semver@0.3.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/ReleaseAgeGate.js
5243
+ const MS_PER_MINUTE = 6e4;
5244
+ /**
5245
+ * A source's partial contribution to a {@link ReleaseAgeGate}: the effective
5246
+ * gate is assembled from more than one place (inline `pnpm-workspace.yaml`
5247
+ * keys, replayed `updateConfig` hooks, `pnpm config get` output), and each
5248
+ * source may set the age, the exclude list, both, or neither. Absent fields
5249
+ * contribute nothing to the combination.
5250
+ *
5251
+ * Deliberately permissive: unlike {@link ReleaseAgeGate} it does not constrain
5252
+ * `ageMinutes` to be non-negative, because the raw values arrive from arbitrary
5253
+ * config sources and {@link ReleaseAgeGate.combine} is the single authority
5254
+ * that clamps them.
5255
+ *
5256
+ * @public
5257
+ */
5258
+ const PartialReleaseAgeGate = effect.Schema.Struct({
5259
+ /** Minutes a release must age; absent means this source sets no age. */
5260
+ ageMinutes: effect.Schema.optionalKey(effect.Schema.Number),
5261
+ /** Exempt package-name patterns; absent means this source adds no exemptions. */
5262
+ exclude: effect.Schema.optionalKey(effect.Schema.Array(effect.Schema.String))
5263
+ });
5264
+ const AgeMinutes = effect.Schema.Number.check(effect.Schema.isGreaterThanOrEqualTo(0), effect.Schema.isFinite());
5265
+ const matchesPattern = (name, pattern) => {
5266
+ if (pattern === name) return true;
5267
+ if (!pattern.includes("*")) return false;
5268
+ let nameIndex = 0;
5269
+ let patternIndex = 0;
5270
+ let starIndex = -1;
5271
+ let retryNameIndex = 0;
5272
+ while (nameIndex < name.length) if (pattern[patternIndex] === "*") {
5273
+ starIndex = patternIndex;
5274
+ patternIndex += 1;
5275
+ retryNameIndex = nameIndex;
5276
+ } else if (pattern[patternIndex] === name[nameIndex]) {
5277
+ patternIndex += 1;
5278
+ nameIndex += 1;
5279
+ } else if (starIndex !== -1) {
5280
+ patternIndex = starIndex + 1;
5281
+ retryNameIndex += 1;
5282
+ nameIndex = retryNameIndex;
5283
+ } else return false;
5284
+ while (pattern[patternIndex] === "*") patternIndex += 1;
5285
+ return patternIndex === pattern.length;
5286
+ };
5287
+ const matchesExclude = (name, patterns) => patterns.some((pattern) => matchesPattern(name, pattern));
5288
+ /**
5289
+ * pnpm's publish-time release-age gate: the number of minutes a published
5290
+ * version must age before it is eligible, and the set of package-name patterns
5291
+ * exempt from the gate. Mirrors pnpm's `minimumReleaseAge` /
5292
+ * `minimumReleaseAgeExclude` config so a resolver can drop too-young candidate
5293
+ * versions before picking, avoiding `ERR_PNPM_NO_MATURE_MATCHING_VERSION`.
5294
+ *
5295
+ * `ageMinutes` is constrained non-negative and finite; a `ReleaseAgeGate` with
5296
+ * `ageMinutes <= 0` is an inert gate that filters nothing. Assemble a gate from
5297
+ * multiple config sources with {@link ReleaseAgeGate.combine}, and apply it to
5298
+ * a package's candidate versions with {@link ReleaseAgeGate.filterVersions}.
5299
+ *
5300
+ * @example
5301
+ * ```ts
5302
+ * import { ReleaseAgeGate } from "@effected/npm";
5303
+ *
5304
+ * const gate = ReleaseAgeGate.combine(
5305
+ * { ageMinutes: 1440 },
5306
+ * { exclude: ["@my-scope/*"] },
5307
+ * );
5308
+ * // gate.ageMinutes === 1440, gate.exclude === ["@my-scope/*"]
5309
+ *
5310
+ * const eligible = gate.filterVersions(
5311
+ * ["1.0.0", "1.0.1"],
5312
+ * { "1.0.0": "2020-01-01T00:00:00Z", "1.0.1": "2026-07-21T00:00:00Z" },
5313
+ * "prettier",
5314
+ * Date.now(),
5315
+ * );
5316
+ * ```
5317
+ *
5318
+ * @public
5319
+ */
5320
+ var ReleaseAgeGate = class ReleaseAgeGate extends effect.Schema.Class("ReleaseAgeGate")({
5321
+ /** Minutes a published version must age before it is eligible (non-negative, finite). */
5322
+ ageMinutes: AgeMinutes,
5323
+ /** Package-name patterns exempt from the gate (exact names or `*`-globs). */
5324
+ exclude: effect.Schema.Array(effect.Schema.String)
5325
+ }) {
5326
+ /**
5327
+ * Combine partial contributions from multiple sources into one effective
5328
+ * gate: **strictest age wins** (the maximum of the contributed ages,
5329
+ * clamped to be non-negative) and the exclude sets **union** (deduplicated,
5330
+ * lexicographically sorted — a canonical wire form, so the combined gate is
5331
+ * deterministic regardless of the order contributions arrive in). A
4720
5332
  * contribution's absent field adds nothing; a
4721
5333
  * negative or non-finite contributed age is ignored by the clamp. With no
4722
5334
  * contributions (or only empty ones) the result is the inert zero gate
@@ -4797,7 +5409,7 @@ var ReleaseAgeGate = class ReleaseAgeGate extends effect.Schema.Class("ReleaseAg
4797
5409
  }
4798
5410
  };
4799
5411
  //#endregion
4800
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._ff048038a9678f5144f817ad24d8f96e/node_modules/@effected/lockfiles/ImporterDependency.js
5412
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._3c1784fba62fde9a5bac4cf15387fd04/node_modules/@effected/lockfiles/ImporterDependency.js
4801
5413
  /**
4802
5414
  * One declared dependency of one workspace importer, as the lockfile records it.
4803
5415
  *
@@ -4829,13 +5441,13 @@ var ReleaseAgeGate = class ReleaseAgeGate extends effect.Schema.Class("ReleaseAg
4829
5441
  */
4830
5442
  var ImporterDependency = class extends effect.Schema.Class("ImporterDependency")({
4831
5443
  name: effect.Schema.NonEmptyString,
4832
- specifier: DependencySpecifier.FromString,
5444
+ specifier: DependencySpecifier$1.FromString,
4833
5445
  version: effect.Schema.optionalKey(effect.Schema.String),
4834
5446
  peerSuffix: effect.Schema.optionalKey(effect.Schema.String),
4835
- depType: DependencyField
5447
+ depType: DependencyField$1
4836
5448
  }) {};
4837
5449
  //#endregion
4838
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._ff048038a9678f5144f817ad24d8f96e/node_modules/@effected/lockfiles/LockfileImporter.js
5450
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._3c1784fba62fde9a5bac4cf15387fd04/node_modules/@effected/lockfiles/LockfileImporter.js
4839
5451
  /**
4840
5452
  * One workspace importer's declared dependencies, as the lockfile records them.
4841
5453
  *
@@ -4859,7 +5471,7 @@ var LockfileImporter = class extends effect.Schema.Class("LockfileImporter")({
4859
5471
  dependencies: effect.Schema.Array(ImporterDependency)
4860
5472
  }) {};
4861
5473
  //#endregion
4862
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._ff048038a9678f5144f817ad24d8f96e/node_modules/@effected/lockfiles/ResolvedPackage.js
5474
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._3c1784fba62fde9a5bac4cf15387fd04/node_modules/@effected/lockfiles/ResolvedPackage.js
4863
5475
  const EMPTY_DEPENDENCIES = {};
4864
5476
  /**
4865
5477
  * A package resolved from a lockfile.
@@ -4888,13 +5500,13 @@ const EMPTY_DEPENDENCIES = {};
4888
5500
  var ResolvedPackage = class extends effect.Schema.Class("ResolvedPackage")({
4889
5501
  name: effect.Schema.NonEmptyString,
4890
5502
  version: effect.Schema.String,
4891
- integrity: effect.Schema.optionalKey(IntegrityHash),
5503
+ integrity: effect.Schema.optionalKey(IntegrityHash$1),
4892
5504
  isWorkspace: effect.Schema.Boolean,
4893
5505
  relativePath: effect.Schema.optionalKey(effect.Schema.String),
4894
5506
  dependencies: effect.Schema.Record(effect.Schema.String, effect.Schema.String).pipe(effect.Schema.withDecodingDefaultKey(effect.Effect.succeed(EMPTY_DEPENDENCIES)), effect.Schema.withConstructorDefault(effect.Effect.succeed(EMPTY_DEPENDENCIES)))
4895
5507
  }) {};
4896
5508
  //#endregion
4897
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._ff048038a9678f5144f817ad24d8f96e/node_modules/@effected/lockfiles/WorkspaceDependency.js
5509
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._3c1784fba62fde9a5bac4cf15387fd04/node_modules/@effected/lockfiles/WorkspaceDependency.js
4898
5510
  /**
4899
5511
  * A directed dependency edge between two workspace packages as recorded in
4900
5512
  * the lockfile.
@@ -4912,11 +5524,11 @@ var ResolvedPackage = class extends effect.Schema.Class("ResolvedPackage")({
4912
5524
  var WorkspaceDependency = class extends effect.Schema.Class("WorkspaceDependency")({
4913
5525
  from: effect.Schema.NonEmptyString,
4914
5526
  to: effect.Schema.NonEmptyString,
4915
- depType: DependencyField,
5527
+ depType: DependencyField$1,
4916
5528
  constraint: effect.Schema.String
4917
5529
  }) {};
4918
5530
  //#endregion
4919
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._ff048038a9678f5144f817ad24d8f96e/node_modules/@effected/lockfiles/PnpmExtension.js
5531
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._3c1784fba62fde9a5bac4cf15387fd04/node_modules/@effected/lockfiles/PnpmExtension.js
4920
5532
  /**
4921
5533
  * Extension data specific to pnpm lockfiles, attached to `Lockfile.extension`
4922
5534
  * when the format is `"pnpm"`.
@@ -4941,7 +5553,7 @@ var PnpmExtension = class extends effect.Schema.Class("PnpmExtension")({
4941
5553
  }))
4942
5554
  }) {};
4943
5555
  //#endregion
4944
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._ff048038a9678f5144f817ad24d8f96e/node_modules/@effected/lockfiles/LockfileFormat.js
5556
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._3c1784fba62fde9a5bac4cf15387fd04/node_modules/@effected/lockfiles/LockfileFormat.js
4945
5557
  /**
4946
5558
  * The lockfile formats this package parses: bun's `bun.lock` (JSONC), npm's
4947
5559
  * `package-lock.json` (v2/v3 JSON), pnpm's `pnpm-lock.yaml` and yarn Berry's
@@ -4979,7 +5591,7 @@ const FILENAMES = {
4979
5591
  */
4980
5592
  const filenameFor = (format) => FILENAMES[format][0];
4981
5593
  //#endregion
4982
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._ff048038a9678f5144f817ad24d8f96e/node_modules/@effected/lockfiles/internal/shared.js
5594
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._3c1784fba62fde9a5bac4cf15387fd04/node_modules/@effected/lockfiles/internal/shared.js
4983
5595
  /**
4984
5596
  * The four dependency sections of a manifest, in a stable order — the shared
4985
5597
  * dependency-sections table (v3's `DEP_SECTIONS`). Each entry is both the
@@ -5014,9 +5626,9 @@ const DEP_TYPES = [
5014
5626
  */
5015
5627
  const toIntegrityHash = (raw) => {
5016
5628
  if (raw === void 0) return effect.Effect.succeed(void 0);
5017
- return effect.Schema.decodeUnknownEffect(IntegrityHash)(raw).pipe(effect.Effect.mapError(validationFailure));
5629
+ return effect.Schema.decodeUnknownEffect(IntegrityHash$1)(raw).pipe(effect.Effect.mapError(validationFailure));
5018
5630
  };
5019
- const decodeSpecifier = effect.Schema.decodeUnknownExit(DependencySpecifier.FromString);
5631
+ const decodeSpecifier = effect.Schema.decodeUnknownExit(DependencySpecifier$1.FromString);
5020
5632
  /**
5021
5633
  * Split pnpm's peer-disambiguation suffix off a recorded string: everything
5022
5634
  * from the first `(` on is suffix, since package names and versions never
@@ -6908,7 +7520,7 @@ var JsoncModifier = class {
6908
7520
  });
6909
7521
  };
6910
7522
  //#endregion
6911
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._ff048038a9678f5144f817ad24d8f96e/node_modules/@effected/lockfiles/internal/bun.js
7523
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._3c1784fba62fde9a5bac4cf15387fd04/node_modules/@effected/lockfiles/internal/bun.js
6912
7524
  const DepRecord$2 = effect.Schema.optionalKey(effect.Schema.Record(effect.Schema.String, effect.Schema.String));
6913
7525
  const BunWorkspaceEntry = effect.Schema.Struct({
6914
7526
  name: effect.Schema.optionalKey(effect.Schema.String),
@@ -7001,7 +7613,7 @@ const toFields$3 = (raw) => effect.Effect.gen(function* () {
7001
7613
  };
7002
7614
  });
7003
7615
  //#endregion
7004
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._ff048038a9678f5144f817ad24d8f96e/node_modules/@effected/lockfiles/internal/npm.js
7616
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._3c1784fba62fde9a5bac4cf15387fd04/node_modules/@effected/lockfiles/internal/npm.js
7005
7617
  const DepRecord$1 = effect.Schema.optionalKey(effect.Schema.Record(effect.Schema.String, effect.Schema.String));
7006
7618
  const NpmPackageEntry = effect.Schema.Struct({
7007
7619
  name: effect.Schema.optionalKey(effect.Schema.String),
@@ -13923,7 +14535,7 @@ function deepEqualValues(a, b) {
13923
14535
  return false;
13924
14536
  }
13925
14537
  //#endregion
13926
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._ff048038a9678f5144f817ad24d8f96e/node_modules/@effected/lockfiles/internal/documents.js
14538
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._3c1784fba62fde9a5bac4cf15387fd04/node_modules/@effected/lockfiles/internal/documents.js
13927
14539
  /**
13928
14540
  * An empty YAML document composes to `null` (`Yaml.parseAll("")` is `[null]`,
13929
14541
  * and the trailing document of an env-only `pnpm-lock.yaml` is `null` too).
@@ -13993,7 +14605,7 @@ const selectSoleDocument = (content) => effect.Effect.gen(function* () {
13993
14605
  };
13994
14606
  });
13995
14607
  //#endregion
13996
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._ff048038a9678f5144f817ad24d8f96e/node_modules/@effected/lockfiles/internal/pnpm.js
14608
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._3c1784fba62fde9a5bac4cf15387fd04/node_modules/@effected/lockfiles/internal/pnpm.js
13997
14609
  const PnpmImporterDeps = effect.Schema.optionalKey(effect.Schema.Record(effect.Schema.String, effect.Schema.Struct({
13998
14610
  specifier: effect.Schema.String,
13999
14611
  version: effect.Schema.String
@@ -14118,7 +14730,7 @@ const toFields$1 = (raw) => effect.Effect.gen(function* () {
14118
14730
  };
14119
14731
  });
14120
14732
  //#endregion
14121
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._ff048038a9678f5144f817ad24d8f96e/node_modules/@effected/lockfiles/internal/yarn.js
14733
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._3c1784fba62fde9a5bac4cf15387fd04/node_modules/@effected/lockfiles/internal/yarn.js
14122
14734
  const YarnLockfileRaw = effect.Schema.Record(effect.Schema.String, effect.Schema.Unknown);
14123
14735
  const DepRecord = effect.Schema.optionalKey(effect.Schema.Record(effect.Schema.String, effect.Schema.String));
14124
14736
  const YarnEntry = effect.Schema.Struct({
@@ -14241,7 +14853,7 @@ const cleanYarnDeps = (deps) => {
14241
14853
  return Object.fromEntries(Object.entries(deps).map(([name, value]) => [name, value.startsWith("npm:") ? value.slice(4) : value]));
14242
14854
  };
14243
14855
  //#endregion
14244
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._ff048038a9678f5144f817ad24d8f96e/node_modules/@effected/lockfiles/Lockfile.js
14856
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._3c1784fba62fde9a5bac4cf15387fd04/node_modules/@effected/lockfiles/Lockfile.js
14245
14857
  const EMPTY_IMPORTERS = [];
14246
14858
  /**
14247
14859
  * Failure of `Lockfile.parse`: the given content is not a valid lockfile of
@@ -14485,121 +15097,538 @@ var Lockfile = class Lockfile extends effect.Schema.Class("Lockfile")({
14485
15097
  }
14486
15098
  };
14487
15099
  //#endregion
14488
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._ff048038a9678f5144f817ad24d8f96e/node_modules/@effected/lockfiles/LockfileIntegrity.js
15100
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._3c1784fba62fde9a5bac4cf15387fd04/node_modules/@effected/lockfiles/LockfileIntegrity.js
15101
+ /**
15102
+ * The minimal manifest shape {@link LockfileIntegrity.compare} checks a
15103
+ * lockfile against: a package name plus the four optional dependency maps.
15104
+ *
15105
+ * @remarks
15106
+ * Deliberately *not* a `@effected/package-json` type — this package takes
15107
+ * manifests as plain values so its consumers own the manifest IO (and may
15108
+ * derive these from any richer model).
15109
+ *
15110
+ * @public
15111
+ */
15112
+ var WorkspaceManifest = class extends effect.Schema.Class("WorkspaceManifest")({
15113
+ name: effect.Schema.NonEmptyString,
15114
+ dependencies: effect.Schema.optionalKey(effect.Schema.Record(effect.Schema.String, effect.Schema.String)),
15115
+ devDependencies: effect.Schema.optionalKey(effect.Schema.Record(effect.Schema.String, effect.Schema.String)),
15116
+ peerDependencies: effect.Schema.optionalKey(effect.Schema.Record(effect.Schema.String, effect.Schema.String)),
15117
+ optionalDependencies: effect.Schema.optionalKey(effect.Schema.Record(effect.Schema.String, effect.Schema.String))
15118
+ }) {};
15119
+ const decodeRange = effect.Schema.decodeUnknownExit(Range$2.FromString);
15120
+ const decodeSemVer = effect.Schema.decodeUnknownExit(SemVer.FromString);
15121
+ /**
15122
+ * Result of checking a parsed lockfile against the workspace's declared
15123
+ * manifests.
15124
+ *
15125
+ * @remarks
15126
+ * A data type, not an error: it reports *what* mismatches exist without
15127
+ * failing anything.
15128
+ *
15129
+ * - `valid` — `true` when the lockfile is fully consistent.
15130
+ * - `missingWorkspaces` — workspace names present in the manifests but
15131
+ * absent from the lockfile.
15132
+ * - `extraWorkspaces` — workspace names in the lockfile with no matching
15133
+ * manifest.
15134
+ * - `unsatisfiedConstraints` — declared constraints the lockfile's resolved
15135
+ * versions do not satisfy.
15136
+ *
15137
+ * @public
15138
+ */
15139
+ var LockfileIntegrity = class LockfileIntegrity extends effect.Schema.Class("LockfileIntegrity")({
15140
+ valid: effect.Schema.Boolean,
15141
+ missingWorkspaces: effect.Schema.Array(effect.Schema.String),
15142
+ extraWorkspaces: effect.Schema.Array(effect.Schema.String),
15143
+ unsatisfiedConstraints: effect.Schema.Array(effect.Schema.Struct({
15144
+ workspace: effect.Schema.String,
15145
+ dependency: effect.Schema.String,
15146
+ constraint: effect.Schema.String,
15147
+ resolved: effect.Schema.String,
15148
+ depType: DependencyField$1
15149
+ }))
15150
+ }) {
15151
+ /**
15152
+ * Check a lockfile's consistency against workspace manifests — a total,
15153
+ * pure function: no Effect, no error channel, no IO.
15154
+ *
15155
+ * @remarks
15156
+ * Constraint checking is best-effort by design: `workspace:` / `link:` /
15157
+ * `file:` specifiers and rows whose range (or every resolved version) does
15158
+ * not parse as SemVer are skipped, exactly as in the v3 implementation.
15159
+ * A lockfile may resolve the same package at several versions; a
15160
+ * constraint is satisfied when *any* resolved version matches, and an
15161
+ * unsatisfied row reports every candidate in `resolved`. The
15162
+ * caller reads the manifests (this package does no IO). For pnpm, apply
15163
+ * `Lockfile#withImporterNames` first so workspace names align with
15164
+ * manifest names.
15165
+ *
15166
+ * (Named `compare`, not `check`: every v4 `Schema.Class` already carries
15167
+ * a `static check(...checks)` for attaching schema checks, and statics
15168
+ * cannot be shadowed with an incompatible signature.)
15169
+ *
15170
+ * @param lockfile - The parsed lockfile.
15171
+ * @param manifests - The workspace manifests to compare against.
15172
+ * @returns The integrity report.
15173
+ */
15174
+ static compare(lockfile, manifests) {
15175
+ const workspacePackages = lockfile.packages.filter((p) => p.isWorkspace && p.relativePath !== void 0);
15176
+ const lockfileWsNames = new Set(workspacePackages.map((p) => p.name));
15177
+ const manifestNames = new Set(manifests.map((m) => m.name));
15178
+ const missingWorkspaces = [...manifestNames].filter((n) => !lockfileWsNames.has(n));
15179
+ const extraWorkspaces = [...lockfileWsNames].filter((n) => !manifestNames.has(n));
15180
+ const resolvedIndex = /* @__PURE__ */ new Map();
15181
+ for (const p of lockfile.packages) {
15182
+ const versions = resolvedIndex.get(p.name);
15183
+ if (versions === void 0) resolvedIndex.set(p.name, [p.version]);
15184
+ else versions.push(p.version);
15185
+ }
15186
+ const unsatisfiedConstraints = [];
15187
+ for (const manifest of manifests) for (const depType of DEP_TYPES) {
15188
+ const depMap = manifest[depType];
15189
+ if (!depMap) continue;
15190
+ for (const [dependency, constraint] of Object.entries(depMap)) {
15191
+ if (isWorkspaceSpecifier(constraint)) continue;
15192
+ const candidates = resolvedIndex.get(dependency);
15193
+ if (candidates === void 0) continue;
15194
+ const rangeExit = decodeRange(constraint);
15195
+ if (effect.Exit.isFailure(rangeExit)) continue;
15196
+ const versions = candidates.map((candidate) => decodeSemVer(candidate)).filter(effect.Exit.isSuccess);
15197
+ if (versions.length === 0) continue;
15198
+ if (!versions.some((v) => rangeExit.value.test(v.value))) unsatisfiedConstraints.push({
15199
+ workspace: manifest.name,
15200
+ dependency,
15201
+ constraint,
15202
+ resolved: candidates.join(", "),
15203
+ depType
15204
+ });
15205
+ }
15206
+ }
15207
+ return LockfileIntegrity.make({
15208
+ valid: missingWorkspaces.length === 0 && extraWorkspaces.length === 0 && unsatisfiedConstraints.length === 0,
15209
+ missingWorkspaces,
15210
+ extraWorkspaces,
15211
+ unsatisfiedConstraints
15212
+ });
15213
+ }
15214
+ };
15215
+ //#endregion
15216
+ //#region ../../node_modules/.pnpm/@effected+npm@0.8.2_@effected+semver@0.3.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/CatalogResolver.js
15217
+ /**
15218
+ * Contract for resolving pnpm `catalog:` dependency specifiers to concrete
15219
+ * version ranges.
15220
+ *
15221
+ * `rangeOf` takes a package name and an optional catalog name
15222
+ * (`Option.none()` selects the default catalog) and returns the configured
15223
+ * range as `Option.some`, or `Option.none()` when the specifier is absent
15224
+ * from the catalog. By convention the error channel is reserved for a
15225
+ * failure in the resolution mechanism itself — an unmatched package or
15226
+ * catalog name is an `Option.none()` success, never an error. A failure to
15227
+ * *assemble* the catalogs (an unreadable or malformed catalog source)
15228
+ * surfaces typed as a {@link CatalogAssemblyError}; any other mechanism
15229
+ * failure is a {@link DependencyResolutionError}.
15230
+ *
15231
+ * This is a contract-only service: {@link CatalogResolver.noop} is the sole
15232
+ * implementation this package ships, and it resolves nothing. Real consumers
15233
+ * (e.g. `@effected/workspaces`) provide a working implementation at the
15234
+ * application boundary.
15235
+ *
15236
+ * @example
15237
+ * ```ts
15238
+ * import { Effect, Option } from "effect";
15239
+ * import { CatalogResolver } from "@effected/npm";
15240
+ *
15241
+ * const program = Effect.gen(function* () {
15242
+ * const resolver = yield* CatalogResolver;
15243
+ * return yield* resolver.rangeOf("effect", Option.none());
15244
+ * });
15245
+ *
15246
+ * Effect.runPromise(Effect.provide(program, CatalogResolver.noop));
15247
+ * // => Option.none()
15248
+ * ```
15249
+ *
15250
+ * @public
15251
+ */
15252
+ var CatalogResolver = class CatalogResolver extends effect.Context.Service()("@effected/npm/CatalogResolver") {
15253
+ /**
15254
+ * No-op default: `rangeOf` always succeeds with `Option.none()`, never
15255
+ * consulting an actual catalog. A pure `Layer.succeed`, bound to a const
15256
+ * so it memoizes by reference — the layer is built once, not once per
15257
+ * reference to `CatalogResolver.noop`.
15258
+ */
15259
+ static noop = effect.Layer.succeed(CatalogResolver, { rangeOf: () => effect.Effect.succeed(effect.Option.none()) });
15260
+ };
15261
+ effect.Schema.TaggedErrorClass()("DependencyResolutionError", {
15262
+ specifier: effect.Schema.String,
15263
+ cause: effect.Schema.Defect()
15264
+ });
15265
+ /**
15266
+ * Contract for resolving pnpm `workspace:` dependency specifiers to concrete
15267
+ * versions.
15268
+ *
15269
+ * `versionOf` takes a workspace package name and returns its concrete
15270
+ * version (the range modifier stripped) as `Option.some`, or
15271
+ * `Option.none()` when the name is not a known workspace member.
15272
+ *
15273
+ * This is a contract-only service: {@link WorkspaceResolver.noop} is the
15274
+ * sole implementation this package ships, and it resolves nothing. Real
15275
+ * consumers (e.g. `@effected/workspaces`) provide a working implementation
15276
+ * at the application boundary.
15277
+ *
15278
+ * @example
15279
+ * ```ts
15280
+ * import { Effect } from "effect";
15281
+ * import { WorkspaceResolver } from "@effected/npm";
15282
+ *
15283
+ * const program = Effect.gen(function* () {
15284
+ * const resolver = yield* WorkspaceResolver;
15285
+ * return yield* resolver.versionOf("@effected/semver");
15286
+ * });
15287
+ *
15288
+ * Effect.runPromise(Effect.provide(program, WorkspaceResolver.noop));
15289
+ * // => Option.none()
15290
+ * ```
15291
+ *
15292
+ * @public
15293
+ */
15294
+ var WorkspaceResolver = class WorkspaceResolver extends effect.Context.Service()("@effected/npm/WorkspaceResolver") {
15295
+ /**
15296
+ * No-op default: `versionOf` always succeeds with `Option.none()`, never
15297
+ * consulting an actual workspace. A pure `Layer.succeed`, bound to a
15298
+ * const so it memoizes by reference.
15299
+ */
15300
+ static noop = effect.Layer.succeed(WorkspaceResolver, { versionOf: () => effect.Effect.succeed(effect.Option.none()) });
15301
+ };
15302
+ //#endregion
15303
+ //#region ../../node_modules/.pnpm/@effected+npm@0.8.2_@effected+semver@0.3.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/DependencySection.js
15304
+ /**
15305
+ * The short dependency kind: which dependency map an entry came from, named the
15306
+ * way consumers branch on it.
15307
+ *
15308
+ * @public
15309
+ */
15310
+ const DependencyKind = effect.Schema.Literals([
15311
+ "prod",
15312
+ "dev",
15313
+ "peer",
15314
+ "optional"
15315
+ ]);
15316
+ effect.Schema.Literals([
15317
+ "dependencies",
15318
+ "devDependencies",
15319
+ "peerDependencies",
15320
+ "optionalDependencies"
15321
+ ]);
15322
+ Object.fromEntries(Object.entries({
15323
+ prod: "dependencies",
15324
+ dev: "devDependencies",
15325
+ peer: "peerDependencies",
15326
+ optional: "optionalDependencies"
15327
+ }).map(([kind, field]) => [field, kind]));
15328
+ //#endregion
15329
+ //#region ../../node_modules/.pnpm/@effected+npm@0.8.2_@effected+semver@0.3.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/DependencySpecifier.js
15330
+ /**
15331
+ * Indicates that a string could not be parsed as a valid dependency specifier.
15332
+ *
15333
+ * Raised by {@link DependencySpecifier.decode}. The offending string is
15334
+ * preserved on `input`.
15335
+ *
15336
+ * @public
15337
+ */
15338
+ var InvalidDependencySpecifierError = class extends effect.Schema.TaggedErrorClass()("InvalidDependencySpecifierError", {
15339
+ /** The raw input string that failed validation. */
15340
+ input: effect.Schema.String }) {
15341
+ get message() {
15342
+ return `Invalid dependency specifier "${this.input}": not a recognized specifier`;
15343
+ }
15344
+ };
15345
+ const CATALOG_PREFIX = "catalog:";
15346
+ const WORKSPACE_PREFIX = "workspace:";
15347
+ const isBarePath = (value) => value.startsWith("./") || value.startsWith("../") || value.startsWith("~/") || value.startsWith("/");
15348
+ const isGitHubShorthand = (value) => !value.startsWith(".") && !value.startsWith("~") && !value.startsWith("/") && /^[a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-]+(#.*)?$/.test(value);
15349
+ const isGit = (value) => value.startsWith("git+") || value.startsWith("git://") || value.startsWith("github:") || value.startsWith("gist:") || value.startsWith("bitbucket:") || value.startsWith("gitlab:") || isGitHubShorthand(value);
15350
+ const isLocal = (value) => value.startsWith("file:") || value.startsWith("link:") || value.startsWith("portal:") || isBarePath(value);
15351
+ const isLink = (value) => value.startsWith("link:");
15352
+ const isPortal = (value) => value.startsWith("portal:");
15353
+ const isCatalog = (value) => value.startsWith(CATALOG_PREFIX);
15354
+ const isWorkspace = (value) => value.startsWith(WORKSPACE_PREFIX);
15355
+ const isUrl$1 = (value) => value.startsWith("http://") || value.startsWith("https://");
15356
+ const parseRange = (value) => {
15357
+ const exit = effect.Schema.decodeUnknownExit(Range$2.FromString)(value);
15358
+ return effect.Exit.isSuccess(exit) ? effect.Option.some(exit.value) : effect.Option.none();
15359
+ };
15360
+ const isRange = (value) => effect.Option.isSome(parseRange(value));
15361
+ const protocolOf = (value) => {
15362
+ if (value.startsWith(CATALOG_PREFIX)) return "catalog";
15363
+ if (value.startsWith(WORKSPACE_PREFIX)) return "workspace";
15364
+ if (value.startsWith("link:")) return "link";
15365
+ if (value.startsWith("portal:")) return "portal";
15366
+ if (value.startsWith("file:") || isBarePath(value)) return "file";
15367
+ if (value.startsWith("npm:")) return "npm";
15368
+ if (isGit(value)) return "git";
15369
+ if (isUrl$1(value)) return "url";
15370
+ if (isRange(value)) return "range";
15371
+ if (/^[a-zA-Z][a-zA-Z0-9._-]*$/.test(value)) return "tag";
15372
+ return "unknown";
15373
+ };
15374
+ const isTag = (value) => protocolOf(value) === "tag";
15375
+ const catalogNameOf$1 = (specifier) => {
15376
+ if (!isCatalog(specifier)) return effect.Option.none();
15377
+ const rest = specifier.slice(8).trim();
15378
+ return rest.length === 0 ? effect.Option.none() : effect.Option.some(rest);
15379
+ };
15380
+ const projectRangeModifier = (range, version) => range === "*" || range === "" ? version : range === "~" ? `~${version}` : range === "^" ? `^${version}` : range;
15381
+ const splitWorkspaceRest = (rest) => {
15382
+ const at = rest.lastIndexOf("@");
15383
+ return at > 0 ? {
15384
+ target: rest.slice(0, at),
15385
+ range: rest.slice(at + 1)
15386
+ } : {
15387
+ target: void 0,
15388
+ range: rest
15389
+ };
15390
+ };
15391
+ const projectWorkspaceRange = (rest, version) => {
15392
+ const { target, range } = splitWorkspaceRest(rest);
15393
+ const projected = projectRangeModifier(range, version);
15394
+ return target === void 0 ? projected : `npm:${target}@${projected}`;
15395
+ };
15396
+ const resolveWorkspace = (specifier, version) => isWorkspace(specifier) ? projectWorkspaceRange(specifier.slice(10), version) : specifier;
15397
+ const workspaceTargetOf = (specifier) => {
15398
+ if (!isWorkspace(specifier)) return effect.Option.none();
15399
+ const { target } = splitWorkspaceRest(specifier.slice(10));
15400
+ return target === void 0 ? effect.Option.none() : effect.Option.some(target);
15401
+ };
15402
+ /**
15403
+ * Whether a string is a recognized dependency specifier: a semver range, exact
15404
+ * version, dist-tag, URL, git ref, GitHub shorthand, file path, or an
15405
+ * `npm:` / `catalog:` / `workspace:` protocol.
15406
+ *
15407
+ * @public
15408
+ */
15409
+ const isValidDependencySpecifier = (value) => value.length > 0 && protocolOf(value) !== "unknown";
15410
+ /**
15411
+ * A `catalog:` reference. `name` carries the catalog name, or `Option.none()`
15412
+ * for the default catalog (`catalog:`).
15413
+ *
15414
+ * @public
15415
+ */
15416
+ var CatalogSpecifier = class extends effect.Schema.TaggedClass()("catalog", {
15417
+ /** The original specifier string. */
15418
+ raw: effect.Schema.String,
15419
+ /** The catalog name, or `Option.none()` for the default catalog. */
15420
+ name: effect.Schema.Option(effect.Schema.String)
15421
+ }) {};
15422
+ /**
15423
+ * A `workspace:` reference. `range` carries the part after `workspace:` — a
15424
+ * range modifier (`*`, `^`, `~`), a concrete range, or an alias form.
15425
+ *
15426
+ * @public
15427
+ */
15428
+ var WorkspaceSpecifier = class extends effect.Schema.TaggedClass()("workspace", {
15429
+ /** The original specifier string. */
15430
+ raw: effect.Schema.String,
15431
+ /** The part after `workspace:` (e.g. `*`, `^1.2.3`, or an alias form). */
15432
+ range: effect.Schema.String
15433
+ }) {
15434
+ /**
15435
+ * The pnpm publish-time projection of this specifier against a concrete
15436
+ * workspace version: `*` (or an empty range) becomes `version`, `~` becomes
15437
+ * `~version`, `^` becomes `^version`, and a pinned range passes through
15438
+ * unchanged. The alias form (`workspace:<name>@<range>`) becomes pnpm's
15439
+ * publish-time aliased dependency `npm:<name>@<projected>`, with the range
15440
+ * modifier projected the same way — `version` must then be the TARGET
15441
+ * package's version (see `DependencySpecifier.workspaceTargetOf`).
15442
+ *
15443
+ * @remarks
15444
+ * The same projection as `DependencySpecifier.resolveWorkspace`, applied to
15445
+ * this instance's already-extracted `range`; the two share one internal
15446
+ * implementation.
15447
+ *
15448
+ * @param version - The concrete version of the workspace package the
15449
+ * specifier points at (the alias target's version for the alias form).
15450
+ */
15451
+ resolve(version) {
15452
+ return projectWorkspaceRange(this.range, version);
15453
+ }
15454
+ };
15455
+ /**
15456
+ * A plain semver range or exact version (e.g. `^1.2.3`, `1.x`, `>=1 <2`).
15457
+ *
15458
+ * @public
15459
+ */
15460
+ var RangeSpecifier = class extends effect.Schema.TaggedClass()("range", {
15461
+ /** The original specifier string. */
15462
+ raw: effect.Schema.String }) {};
15463
+ /**
15464
+ * A bare dist-tag (e.g. `latest`, `next`).
15465
+ *
15466
+ * @public
15467
+ */
15468
+ var DistTagSpecifier = class extends effect.Schema.TaggedClass()("dist-tag", {
15469
+ /** The original specifier string (also the tag name). */
15470
+ raw: effect.Schema.String }) {};
15471
+ /**
15472
+ * The honest fallback for `file:` / `link:` / `portal:` / git / URL / `npm:`
15473
+ * forms this concept does not further interpret.
15474
+ *
15475
+ * @public
15476
+ */
15477
+ var RawSpecifier = class extends effect.Schema.TaggedClass()("raw", {
15478
+ /** The original specifier string. */
15479
+ raw: effect.Schema.String }) {};
15480
+ const Classified = effect.Schema.Union([
15481
+ CatalogSpecifier,
15482
+ WorkspaceSpecifier,
15483
+ RangeSpecifier,
15484
+ DistTagSpecifier,
15485
+ RawSpecifier
15486
+ ]);
15487
+ const classify$1 = (value) => {
15488
+ if (isCatalog(value)) return CatalogSpecifier.make({
15489
+ raw: value,
15490
+ name: catalogNameOf$1(value)
15491
+ });
15492
+ if (isWorkspace(value)) return WorkspaceSpecifier.make({
15493
+ raw: value,
15494
+ range: value.slice(10)
15495
+ });
15496
+ if (isRange(value)) return RangeSpecifier.make({ raw: value });
15497
+ if (isTag(value)) return DistTagSpecifier.make({ raw: value });
15498
+ return RawSpecifier.make({ raw: value });
15499
+ };
15500
+ const fromString = effect.Schema.String.pipe(effect.Schema.decodeTo(Classified, effect.SchemaTransformation.transformOrFail({
15501
+ decode: (input) => isValidDependencySpecifier(input) ? effect.Effect.succeed(classify$1(input)) : effect.Effect.fail(new effect.SchemaIssue.InvalidValue(effect.Option.some(input), { message: `Invalid dependency specifier: "${input}"` })),
15502
+ encode: (classified) => effect.Effect.succeed(classified.raw)
15503
+ })));
15504
+ const brandedSpecifier = effect.Schema.String.pipe(effect.Schema.check(effect.Schema.makeFilter((value) => isValidDependencySpecifier(value) ? void 0 : "Expected a valid dependency specifier")), effect.Schema.brand("DependencySpecifier"));
15505
+ const decode$3 = (input) => effect.Schema.decodeUnknownEffect(brandedSpecifier)(input).pipe(effect.Effect.mapError(() => new InvalidDependencySpecifierError({ input })));
15506
+ /**
15507
+ * A valid dependency version specifier, carrying the protocol taxonomy statics
15508
+ * (`DependencySpecifier.protocolOf` and friends) that classify any specifier
15509
+ * string, plus the {@link (DependencySpecifier:variable).FromString} codec that
15510
+ * decodes a string into a {@link ClassifiedSpecifier} tagged union. Use it as a
15511
+ * schema for a specifier field and reach for the statics to inspect a raw
15512
+ * string.
15513
+ *
15514
+ * @public
15515
+ */
15516
+ const DependencySpecifier = Object.assign(brandedSpecifier, {
15517
+ protocolOf,
15518
+ parseRange,
15519
+ isRange,
15520
+ isTag,
15521
+ isGit,
15522
+ isUrl: isUrl$1,
15523
+ isLocal,
15524
+ isLink,
15525
+ isPortal,
15526
+ isCatalog,
15527
+ isWorkspace,
15528
+ catalogNameOf: catalogNameOf$1,
15529
+ resolveWorkspace,
15530
+ workspaceTargetOf,
15531
+ isValid: isValidDependencySpecifier,
15532
+ decode: decode$3,
15533
+ FromString: fromString
15534
+ });
15535
+ //#endregion
15536
+ //#region ../../node_modules/.pnpm/@effected+npm@0.8.2_@effected+semver@0.3.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/IntegrityHash.js
15537
+ const SRI_RE = /^(sha1|sha256|sha384|sha512)-[A-Za-z0-9+/]+={0,2}$/;
15538
+ const COREPACK_RE = /^(sha1|sha224|sha256|sha384|sha512)\.[0-9a-f]+$/;
15539
+ const YARN_RE = /^[0-9]+(c[0-9]+)?\/[0-9a-f]+$/;
15540
+ const isSri = (value) => SRI_RE.test(value);
15541
+ const isCorepack = (value) => COREPACK_RE.test(value);
15542
+ const isYarnChecksum = (value) => YARN_RE.test(value);
14489
15543
  /**
14490
- * The minimal manifest shape {@link LockfileIntegrity.compare} checks a
14491
- * lockfile against: a package name plus the four optional dependency maps.
15544
+ * Whether a string is a valid integrity hash in the SRI (`<algo>-<base64>`),
15545
+ * corepack (`<algo>.<hex>`) or yarn (`<cachekey>/<hex>`) form.
14492
15546
  *
14493
- * @remarks
14494
- * Deliberately *not* a `@effected/package-json` type — this package takes
14495
- * manifests as plain values so its consumers own the manifest IO (and may
14496
- * derive these from any richer model).
15547
+ * @public
15548
+ */
15549
+ const isValidIntegrityHash = (value) => isSri(value) || isCorepack(value) || isYarnChecksum(value);
15550
+ const algorithmOf = (value) => {
15551
+ if (isSri(value)) return effect.Option.some(value.slice(0, value.indexOf("-")));
15552
+ if (isCorepack(value)) return effect.Option.some(value.slice(0, value.indexOf(".")));
15553
+ return effect.Option.none();
15554
+ };
15555
+ /**
15556
+ * Indicates that a string could not be parsed as a valid integrity hash.
15557
+ *
15558
+ * Raised by {@link IntegrityHash.decode}. The offending string is preserved on
15559
+ * `input`.
14497
15560
  *
14498
15561
  * @public
14499
15562
  */
14500
- var WorkspaceManifest = class extends effect.Schema.Class("WorkspaceManifest")({
14501
- name: effect.Schema.NonEmptyString,
14502
- dependencies: effect.Schema.optionalKey(effect.Schema.Record(effect.Schema.String, effect.Schema.String)),
14503
- devDependencies: effect.Schema.optionalKey(effect.Schema.Record(effect.Schema.String, effect.Schema.String)),
14504
- peerDependencies: effect.Schema.optionalKey(effect.Schema.Record(effect.Schema.String, effect.Schema.String)),
14505
- optionalDependencies: effect.Schema.optionalKey(effect.Schema.Record(effect.Schema.String, effect.Schema.String))
14506
- }) {};
14507
- const decodeRange = effect.Schema.decodeUnknownExit(Range$2.FromString);
14508
- const decodeSemVer = effect.Schema.decodeUnknownExit(SemVer.FromString);
15563
+ var InvalidIntegrityHashError = class extends effect.Schema.TaggedErrorClass()("InvalidIntegrityHashError", {
15564
+ /** The raw input string that failed validation. */
15565
+ input: effect.Schema.String }) {
15566
+ get message() {
15567
+ return `Invalid integrity hash "${this.input}": expected an SRI (<algo>-<base64>), corepack (<algo>.<hex>) or yarn (<cachekey>/<hex>) form`;
15568
+ }
15569
+ };
15570
+ const brandedIntegrity = effect.Schema.String.pipe(effect.Schema.check(effect.Schema.makeFilter((value) => isValidIntegrityHash(value) ? void 0 : "Expected an SRI, corepack or yarn integrity hash")), effect.Schema.brand("IntegrityHash"));
15571
+ const decode$2 = (input) => effect.Schema.decodeUnknownEffect(brandedIntegrity)(input).pipe(effect.Effect.mapError(() => new InvalidIntegrityHashError({ input })));
15572
+ Object.assign(brandedIntegrity, {
15573
+ isSri,
15574
+ isCorepack,
15575
+ isYarnChecksum,
15576
+ isValid: isValidIntegrityHash,
15577
+ algorithmOf,
15578
+ decode: decode$2
15579
+ });
14509
15580
  /**
14510
- * Result of checking a parsed lockfile against the workspace's declared
14511
- * manifests.
15581
+ * {@link (IntegrityHash:variable)} narrowed to the corepack `<algo>.<hex>` form
15582
+ * — `sha512.deadbeef`, and corepack's own sha224 default pins
15583
+ * (`sha224.877304e3…`). An SRI (`sha512-<base64>`) or yarn (`10c0/<hex>`)
15584
+ * hash, both valid `IntegrityHash` values, fails this schema.
14512
15585
  *
14513
15586
  * @remarks
14514
- * A data type, not an error: it reports *what* mismatches exist without
14515
- * failing anything.
15587
+ * The corepack pin tail (`<name>@<version>+<integrity>`) is the one place the
15588
+ * kit meets this form, and two schemas name it: `PackageManagerPin.integrity`
15589
+ * here and `@effected/package-json`'s `PackageManager.integrity`. Both consume
15590
+ * **this** schema — the restriction existed privately in each module until they
15591
+ * were consolidated, and a private copy is exactly how the two drift (the
15592
+ * widening that admitted sha224 had to be made twice).
14516
15593
  *
14517
- * - `valid` `true` when the lockfile is fully consistent.
14518
- * - `missingWorkspaces` workspace names present in the manifests but
14519
- * absent from the lockfile.
14520
- * - `extraWorkspaces` workspace names in the lockfile with no matching
14521
- * manifest.
14522
- * - `unsatisfiedConstraints` — declared constraints the lockfile's resolved
14523
- * versions do not satisfy.
15594
+ * It decodes to the same {@link IntegrityHashBrand} the unrestricted schema
15595
+ * does, so a corepack-validated value assigns anywhere an `IntegrityHash` is
15596
+ * expected; there is no second brand. Reach for
15597
+ * `IntegrityHash.isCorepack(value)` to ask the same question about a raw
15598
+ * string without decoding.
15599
+ *
15600
+ * That single brand is also why sharing this schema is not type-enforced, and
15601
+ * the consequence is sharper than it looks: a `Schema.check` is **erased from
15602
+ * the built type**, so this schema and the unrestricted one are the same
15603
+ * declared type. A consumer that quietly reverts to a private copy compiles
15604
+ * clean, and — if the copy is faithful — passes every rejection test too.
15605
+ * Neither `tsc` nor behaviour can see the re-fork.
15606
+ *
15607
+ * What does see it is **object identity**, so each consumer's suite asserts
15608
+ * that its field schema IS this export:
15609
+ * `PackageManagerPin.fields.integrity.schema === CorepackIntegrityHash` (an
15610
+ * `optionalKey` field keeps the inner schema on `.schema`), and
15611
+ * `PackageManager.fields.integrity.value === CorepackIntegrityHash` on the
15612
+ * `@effected/package-json` side (a `Schema.Option` keeps it on `.value`). Both
15613
+ * assertions carry a control against the unrestricted brand, so they discriminate
15614
+ * rather than passing on any schema at all. That identity assertion is the only
15615
+ * thing standing between the two surfaces and a silent re-fork; do not replace
15616
+ * it with a behavioural test, which cannot fail.
15617
+ *
15618
+ * @example
15619
+ * ```ts
15620
+ * import { CorepackIntegrityHash } from "@effected/npm";
15621
+ * import { Schema } from "effect";
15622
+ *
15623
+ * const decode = Schema.decodeUnknownExit(CorepackIntegrityHash);
15624
+ *
15625
+ * decode("sha512.deadbeef"); // success
15626
+ * decode("sha512-3q2+7w=="); // failure — SRI form
15627
+ * ```
14524
15628
  *
14525
15629
  * @public
14526
15630
  */
14527
- var LockfileIntegrity = class LockfileIntegrity extends effect.Schema.Class("LockfileIntegrity")({
14528
- valid: effect.Schema.Boolean,
14529
- missingWorkspaces: effect.Schema.Array(effect.Schema.String),
14530
- extraWorkspaces: effect.Schema.Array(effect.Schema.String),
14531
- unsatisfiedConstraints: effect.Schema.Array(effect.Schema.Struct({
14532
- workspace: effect.Schema.String,
14533
- dependency: effect.Schema.String,
14534
- constraint: effect.Schema.String,
14535
- resolved: effect.Schema.String,
14536
- depType: DependencyField
14537
- }))
14538
- }) {
14539
- /**
14540
- * Check a lockfile's consistency against workspace manifests — a total,
14541
- * pure function: no Effect, no error channel, no IO.
14542
- *
14543
- * @remarks
14544
- * Constraint checking is best-effort by design: `workspace:` / `link:` /
14545
- * `file:` specifiers and rows whose range (or every resolved version) does
14546
- * not parse as SemVer are skipped, exactly as in the v3 implementation.
14547
- * A lockfile may resolve the same package at several versions; a
14548
- * constraint is satisfied when *any* resolved version matches, and an
14549
- * unsatisfied row reports every candidate in `resolved`. The
14550
- * caller reads the manifests (this package does no IO). For pnpm, apply
14551
- * `Lockfile#withImporterNames` first so workspace names align with
14552
- * manifest names.
14553
- *
14554
- * (Named `compare`, not `check`: every v4 `Schema.Class` already carries
14555
- * a `static check(...checks)` for attaching schema checks, and statics
14556
- * cannot be shadowed with an incompatible signature.)
14557
- *
14558
- * @param lockfile - The parsed lockfile.
14559
- * @param manifests - The workspace manifests to compare against.
14560
- * @returns The integrity report.
14561
- */
14562
- static compare(lockfile, manifests) {
14563
- const workspacePackages = lockfile.packages.filter((p) => p.isWorkspace && p.relativePath !== void 0);
14564
- const lockfileWsNames = new Set(workspacePackages.map((p) => p.name));
14565
- const manifestNames = new Set(manifests.map((m) => m.name));
14566
- const missingWorkspaces = [...manifestNames].filter((n) => !lockfileWsNames.has(n));
14567
- const extraWorkspaces = [...lockfileWsNames].filter((n) => !manifestNames.has(n));
14568
- const resolvedIndex = /* @__PURE__ */ new Map();
14569
- for (const p of lockfile.packages) {
14570
- const versions = resolvedIndex.get(p.name);
14571
- if (versions === void 0) resolvedIndex.set(p.name, [p.version]);
14572
- else versions.push(p.version);
14573
- }
14574
- const unsatisfiedConstraints = [];
14575
- for (const manifest of manifests) for (const depType of DEP_TYPES) {
14576
- const depMap = manifest[depType];
14577
- if (!depMap) continue;
14578
- for (const [dependency, constraint] of Object.entries(depMap)) {
14579
- if (isWorkspaceSpecifier(constraint)) continue;
14580
- const candidates = resolvedIndex.get(dependency);
14581
- if (candidates === void 0) continue;
14582
- const rangeExit = decodeRange(constraint);
14583
- if (effect.Exit.isFailure(rangeExit)) continue;
14584
- const versions = candidates.map((candidate) => decodeSemVer(candidate)).filter(effect.Exit.isSuccess);
14585
- if (versions.length === 0) continue;
14586
- if (!versions.some((v) => rangeExit.value.test(v.value))) unsatisfiedConstraints.push({
14587
- workspace: manifest.name,
14588
- dependency,
14589
- constraint,
14590
- resolved: candidates.join(", "),
14591
- depType
14592
- });
14593
- }
14594
- }
14595
- return LockfileIntegrity.make({
14596
- valid: missingWorkspaces.length === 0 && extraWorkspaces.length === 0 && unsatisfiedConstraints.length === 0,
14597
- missingWorkspaces,
14598
- extraWorkspaces,
14599
- unsatisfiedConstraints
14600
- });
14601
- }
14602
- };
15631
+ const CorepackIntegrityHash = brandedIntegrity.pipe(effect.Schema.check(effect.Schema.makeFilter((value) => isCorepack(value) ? void 0 : "Expected a corepack (<algo>.<hex>) integrity hash")));
14603
15632
  //#endregion
14604
15633
  //#region ../../node_modules/.pnpm/@effected+package-json@0.7.3_effect@4.0.0-beta.101/node_modules/@effected/package-json/Dependency.js
14605
15634
  /**
@@ -17284,7 +18313,7 @@ var Package = class Package extends effect.Schema.Class("Package")({
17284
18313
  }
17285
18314
  };
17286
18315
  //#endregion
17287
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspacePackage.js
18316
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspacePackage.js
17288
18317
  const EMPTY$1 = Object.freeze(Object.create(null));
17289
18318
  const EMPTY_MANIFEST = Object.freeze(Object.create(null));
17290
18319
  /**
@@ -17882,7 +18911,7 @@ var Walker$1 = class {
17882
18911
  static findRoot = findRoot$1;
17883
18912
  };
17884
18913
  //#endregion
17885
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspaceRoot.js
18914
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspaceRoot.js
17886
18915
  /**
17887
18916
  * The marker filenames {@link WorkspaceRoot} probes for, in priority order.
17888
18917
  *
@@ -18069,7 +19098,7 @@ var WorkspaceRoot = class WorkspaceRoot extends effect.Context.Service()("@effec
18069
19098
  static layerTest = (root) => effect.Layer.effect(WorkspaceRoot, WorkspaceRoot.makeTest(root)).pipe(effect.Layer.provide(effect.Path.layer));
18070
19099
  };
18071
19100
  //#endregion
18072
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/limits.js
19101
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/limits.js
18073
19102
  /**
18074
19103
  * Hard ceiling on directories the enumerator will visit for one pattern set.
18075
19104
  * Guards the pathological case a depth cap alone does not: a wide, shallow
@@ -18087,7 +19116,7 @@ const MAX_ENUMERATION_ENTRIES = 1e5;
18087
19116
  */
18088
19117
  const PRUNED_DIRECTORIES = /* @__PURE__ */ new Set([".git", "node_modules"]);
18089
19118
  //#endregion
18090
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/traverse.js
19119
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/traverse.js
18091
19120
  /** Directory names never descended into. */
18092
19121
  const isPruned = (entry) => PRUNED_DIRECTORIES.has(entry);
18093
19122
  /** Join root-relative POSIX segments; `""` is the root itself. */
@@ -18177,7 +19206,7 @@ var Traversal = class {
18177
19206
  }
18178
19207
  };
18179
19208
  //#endregion
18180
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/enumerate.js
19209
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/enumerate.js
18181
19210
  /** Strip a trailing slash from `GlobPattern.enumerationPrefix` to get a relative directory. */
18182
19211
  const baseOf = (pattern) => pattern.enumerationPrefix.replace(/\/$/, "");
18183
19212
  /**
@@ -18247,7 +19276,7 @@ const enumerate = (root, globs, options) => effect.Effect.gen(function* () {
18247
19276
  return results;
18248
19277
  });
18249
19278
  //#endregion
18250
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/patterns.js
19279
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/patterns.js
18251
19280
  const stringsOf = (value) => Array.isArray(value) ? value.filter((entry) => typeof entry === "string") : void 0;
18252
19281
  /** The `packages:` list of a `pnpm-workspace.yaml` document. Total on a parsed document. */
18253
19282
  const pnpmPatternsOf = (document) => {
@@ -18304,7 +19333,7 @@ const readPatterns = (root) => effect.Effect.gen(function* () {
18304
19333
  return manifestPatternsOf(manifest);
18305
19334
  });
18306
19335
  //#endregion
18307
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspaceDiscovery.js
19336
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspaceDiscovery.js
18308
19337
  /**
18309
19338
  * Raised when a workspace member's `package.json` cannot be read, parsed, or
18310
19339
  * used — it is missing, malformed, or lacks a `name` or `version`.
@@ -18557,6 +19586,15 @@ var WorkspaceDiscovery = class WorkspaceDiscovery extends effect.Context.Service
18557
19586
  for (const entry of index) if (filePath.startsWith(entry.prefix)) return effect.Option.some(entry.package);
18558
19587
  return effect.Option.none();
18559
19588
  };
19589
+ const packageIndexes = /* @__PURE__ */ new WeakMap();
19590
+ const packagesByName = (all) => {
19591
+ const cached = packageIndexes.get(all);
19592
+ if (cached !== void 0) return cached;
19593
+ const index = /* @__PURE__ */ new Map();
19594
+ for (const pkg of all) if (!index.has(pkg.name)) index.set(pkg.name, pkg);
19595
+ packageIndexes.set(all, index);
19596
+ return index;
19597
+ };
18560
19598
  return {
18561
19599
  info: effect.Effect.fn("WorkspaceDiscovery.info")(function* () {
18562
19600
  return (yield* memo).info;
@@ -18570,7 +19608,7 @@ var WorkspaceDiscovery = class WorkspaceDiscovery extends effect.Context.Service
18570
19608
  }),
18571
19609
  getPackage: effect.Effect.fn("WorkspaceDiscovery.getPackage")(function* (name) {
18572
19610
  const all = yield* packages;
18573
- const found = all.find((pkg) => pkg.name === name);
19611
+ const found = packagesByName(all).get(name);
18574
19612
  if (found !== void 0) return found;
18575
19613
  return yield* effect.Effect.fail(new PackageNotFoundError({
18576
19614
  name,
@@ -18732,9 +19770,18 @@ var WorkspaceDiscovery = class WorkspaceDiscovery extends effect.Context.Service
18732
19770
  * // `Package.resolve` now resolves `workspace:*` for real.
18733
19771
  * ```
18734
19772
  */
18735
- static workspaceResolver = effect.Layer.effect(WorkspaceResolver, effect.Effect.gen(function* () {
19773
+ static workspaceResolver = effect.Layer.effect(WorkspaceResolver$1, effect.Effect.gen(function* () {
18736
19774
  const discovery = yield* WorkspaceDiscovery;
18737
- return { versionOf: (packageName) => discovery.listPackages().pipe(effect.Effect.map((all) => effect.Option.fromUndefinedOr(all.find((pkg) => pkg.name === packageName)?.version)), effect.Effect.mapError((cause) => new DependencyResolutionError({
19775
+ const versionIndexes = /* @__PURE__ */ new WeakMap();
19776
+ const versionsByName = (all) => {
19777
+ const cached = versionIndexes.get(all);
19778
+ if (cached !== void 0) return cached;
19779
+ const index = /* @__PURE__ */ new Map();
19780
+ for (const pkg of all) if (!index.has(pkg.name)) index.set(pkg.name, pkg.version);
19781
+ versionIndexes.set(all, index);
19782
+ return index;
19783
+ };
19784
+ return { versionOf: (packageName) => discovery.listPackages().pipe(effect.Effect.map((all) => effect.Option.fromUndefinedOr(versionsByName(all).get(packageName))), effect.Effect.mapError((cause) => new DependencyResolutionError$1({
18738
19785
  specifier: `workspace:${packageName}`,
18739
19786
  cause
18740
19787
  }))) };
@@ -18742,7 +19789,7 @@ var WorkspaceDiscovery = class WorkspaceDiscovery extends effect.Context.Service
18742
19789
  };
18743
19790
  const isStringRecord$2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value) && Object.values(value).every((entry) => typeof entry === "string");
18744
19791
  //#endregion
18745
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/DependencyGraph.js
19792
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/DependencyGraph.js
18746
19793
  /**
18747
19794
  * Raised when the workspace dependency graph cannot be topologically ordered
18748
19795
  * because it contains a cycle.
@@ -20384,7 +21431,7 @@ var Git = class Git extends effect.Context.Service()("@effected/git/Git") {
20384
21431
  static layerTest = (overrides = {}) => effect.Layer.succeed(Git, Git.makeTest(overrides));
20385
21432
  };
20386
21433
  //#endregion
20387
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/ChangeDetector.js
21434
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/ChangeDetector.js
20388
21435
  /**
20389
21436
  * Which git refs to compare, and whether to fold in the working tree.
20390
21437
  *
@@ -20640,7 +21687,7 @@ function resolveFromCatalog(catalogs, wantedDependency) {
20640
21687
  };
20641
21688
  }
20642
21689
  //#endregion
20643
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/catalogs.js
21690
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/catalogs.js
20644
21691
  /** Project a pnpm-workspace manifest's `catalog` / `catalogs` fields into a `Catalogs` map. */
20645
21692
  const inlineCatalogs = (manifest) => {
20646
21693
  if (manifest.catalog === void 0 && manifest.catalogs === void 0) return {};
@@ -20704,7 +21751,7 @@ const rangeOf = (catalogs, dependency, specifier) => {
20704
21751
  });
20705
21752
  };
20706
21753
  //#endregion
20707
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/ConfigDependencyHooks.js
21754
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/ConfigDependencyHooks.js
20708
21755
  /** Whether `value` is a non-null, non-array object. */
20709
21756
  const isObject$2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
20710
21757
  /**
@@ -20797,6 +21844,137 @@ const updateConfigOf = (mod) => {
20797
21844
  }
20798
21845
  };
20799
21846
  /**
21847
+ * The subprocess replay program {@link ConfigDependencyHooks.layerSubprocess}
21848
+ * hands to `node --input-type=module -e`.
21849
+ *
21850
+ * @remarks
21851
+ * A **static** string constant, deliberately: a bundler compiles a *computed*
21852
+ * dynamic `import()` into a context module that cannot resolve a runtime path
21853
+ * (`Cannot find module 'file:///…'`), so the computed import has to run in a
21854
+ * child process whose program text carries **no interpolated runtime value** —
21855
+ * the workspace root, the seed and the dependency names all arrive via argv
21856
+ * (`process.argv.slice(1)` under `-e`), never spliced into the script.
21857
+ *
21858
+ * The script mirrors this module's in-process semantics exactly so the two
21859
+ * layers are drop-in interchangeable: `pnpmfile.mjs` before `pnpmfile.cjs`
21860
+ * (pnpm 11's loader order), the `ERR_MODULE_NOT_FOUND`-for-the-candidate-itself
21861
+ * skip discrimination (`err.url` equality), the same hook-locator shapes, the
21862
+ * same tolerant threading of returned data (`configOf` / `finiteNumberOr` /
21863
+ * `stringArrayOr` clones below), and the same synchronous hook call. Only the
21864
+ * *mechanism* failures are reported: the script prints one final line of JSON —
21865
+ * `{ ok: true, config }` on success, `{ ok: false, name, message, stack? }`
21866
+ * naming the offending dependency on a load/replay failure — and exits through
21867
+ * the write callback so the payload is flushed even if a hook left the event
21868
+ * loop occupied. The final-line framing tolerates a hook's own `console.log`
21869
+ * noise on stdout.
21870
+ */
21871
+ const REPLAY_SCRIPT = `
21872
+ const [root, seedJson, ...names] = process.argv.slice(1);
21873
+ const { pathToFileURL } = await import("node:url");
21874
+ const { join } = await import("node:path");
21875
+ const isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
21876
+ const finiteNumberOr = (value, fallback) => (typeof value === "number" && Number.isFinite(value) ? value : fallback);
21877
+ const stringArrayOr = (value, fallback) =>
21878
+ Array.isArray(value) && value.every((entry) => typeof entry === "string") ? value : fallback;
21879
+ const configOf = (value, fallback) =>
21880
+ isObject(value)
21881
+ ? {
21882
+ catalog: isObject(value.catalog) ? value.catalog : fallback.catalog,
21883
+ catalogs: isObject(value.catalogs) ? value.catalogs : fallback.catalogs,
21884
+ minimumReleaseAge: finiteNumberOr(value.minimumReleaseAge, fallback.minimumReleaseAge),
21885
+ minimumReleaseAgeExclude: stringArrayOr(value.minimumReleaseAgeExclude, fallback.minimumReleaseAgeExclude),
21886
+ }
21887
+ : fallback;
21888
+ const failure = (name, cause) => ({
21889
+ ok: false,
21890
+ name,
21891
+ message: cause instanceof Error ? cause.message : String(cause),
21892
+ ...(cause instanceof Error && typeof cause.stack === "string" ? { stack: cause.stack } : {}),
21893
+ });
21894
+ const replay = async () => {
21895
+ let catalog = {};
21896
+ const catalogs = {};
21897
+ for (const [name, entries] of Object.entries(JSON.parse(seedJson))) {
21898
+ if (name === "default") catalog = { ...entries };
21899
+ else catalogs[name] = { ...entries };
21900
+ }
21901
+ let config = { catalog, catalogs, minimumReleaseAge: undefined, minimumReleaseAgeExclude: undefined };
21902
+ for (const name of names) {
21903
+ let loaded;
21904
+ let found = false;
21905
+ for (const filename of ["pnpmfile.mjs", "pnpmfile.cjs"]) {
21906
+ const candidate = pathToFileURL(join(root, "node_modules", ".pnpm-config", name, filename)).href;
21907
+ try {
21908
+ loaded = await import(candidate);
21909
+ found = true;
21910
+ break;
21911
+ } catch (cause) {
21912
+ const url =
21913
+ isObject(cause) && cause.code === "ERR_MODULE_NOT_FOUND" && typeof cause.url === "string"
21914
+ ? cause.url
21915
+ : undefined;
21916
+ if (url === candidate) continue;
21917
+ return failure(name, cause);
21918
+ }
21919
+ }
21920
+ if (!found) continue;
21921
+ let hook;
21922
+ for (const candidate of [loaded, isObject(loaded) ? loaded.default : undefined]) {
21923
+ if (!isObject(candidate)) continue;
21924
+ if (isObject(candidate.hooks) && typeof candidate.hooks.updateConfig === "function") {
21925
+ hook = candidate.hooks.updateConfig;
21926
+ break;
21927
+ }
21928
+ if (typeof candidate.updateConfig === "function") {
21929
+ hook = candidate.updateConfig;
21930
+ break;
21931
+ }
21932
+ }
21933
+ if (hook === undefined) continue;
21934
+ try {
21935
+ config = configOf(hook(config), config);
21936
+ } catch (cause) {
21937
+ return failure(name, cause);
21938
+ }
21939
+ }
21940
+ return { ok: true, config };
21941
+ };
21942
+ const payload = await replay();
21943
+ process.stdout.write("\\n" + JSON.stringify(payload) + "\\n", () => process.exit(0));
21944
+ `;
21945
+ /**
21946
+ * The ceiling on one subprocess replay. A config dependency's `updateConfig`
21947
+ * reads and rewrites a config object — no install work, no network — so thirty
21948
+ * seconds is generous. Without a ceiling a pnpmfile that loops or awaits a
21949
+ * promise that never settles hangs `inject`, and through it the one memoized
21950
+ * {@link WorkspaceCatalogs} assemble pass every catalog read blocks on. Expiry
21951
+ * kills the child (`Run` scopes it) and surfaces as a `CommandFailedError`
21952
+ * through the same typed transport-failure path as any other mechanism failure.
21953
+ */
21954
+ const REPLAY_TIMEOUT = effect.Duration.seconds(30);
21955
+ /**
21956
+ * The subprocess protocol payload — the child's final stdout line, framed and
21957
+ * parsed by `Run.jsonLine`. The envelope is strict (a payload without a usable
21958
+ * `ok` discriminant is a mechanism failure, typed); the `config` slice inside a
21959
+ * success stays `Unknown` because a hook's returned *data* is tolerantly
21960
+ * threaded (`configOf`), never fatal.
21961
+ */
21962
+ const ReplayPayload = effect.Schema.Union([effect.Schema.Struct({
21963
+ ok: effect.Schema.Literal(true),
21964
+ config: effect.Schema.Unknown
21965
+ }), effect.Schema.Struct({
21966
+ ok: effect.Schema.Literal(false),
21967
+ name: effect.Schema.optionalKey(effect.Schema.String),
21968
+ message: effect.Schema.optionalKey(effect.Schema.String),
21969
+ stack: effect.Schema.optionalKey(effect.Schema.String)
21970
+ })]);
21971
+ /** Rebuild the subprocess's serialized failure as an `Error`, preserving the child-side stack when it carried one. */
21972
+ const replayFailureCause = (payload) => {
21973
+ const error = new Error(payload.message ?? "config dependency hook replay failed");
21974
+ if (payload.stack !== void 0) error.stack = payload.stack;
21975
+ return error;
21976
+ };
21977
+ /**
20800
21978
  * Replays a workspace's `configDependencies` `updateConfig` hooks over the inline
20801
21979
  * catalogs — the opt-in seam that lets hook-injected catalogs participate in
20802
21980
  * assembly.
@@ -20889,9 +22067,98 @@ var ConfigDependencyHooks = class ConfigDependencyHooks extends effect.Context.S
20889
22067
  releaseAge: releaseAgeOf(config)
20890
22068
  };
20891
22069
  }) });
22070
+ /**
22071
+ * The subprocess layer: replays each config dependency's pnpmfile in a `node`
22072
+ * child process instead of an in-process dynamic `import()`, with identical
22073
+ * typed semantics to {@link ConfigDependencyHooks.layerLive} — the two are
22074
+ * drop-in interchangeable.
22075
+ *
22076
+ * @remarks
22077
+ * `layerLive` computes the `import()` path at runtime, and a bundler (rspack,
22078
+ * for one) compiles a *computed* dynamic import into a context module that
22079
+ * throws `Cannot find module 'file:///…'` at runtime — so in any bundled
22080
+ * consumer, a GitHub Action above all, the in-process replay is unreachable.
22081
+ * This layer keeps every computed load out of the bundle graph: the replay
22082
+ * program is a **static** string constant passed via argv
22083
+ * (`node --input-type=module -e <script> <root> <seed> <...names>`), and the
22084
+ * child process performs the computed imports where no bundler rewrote them.
22085
+ * A subprocess also keeps config-dependency code out of the consumer's own
22086
+ * process.
22087
+ *
22088
+ * The contract's semantics are unchanged, not the downstream fail-open shape:
22089
+ * an empty `configDependencies` returns the seed without spawning anything; a
22090
+ * `..` path segment in a dependency name fails typed **before** any spawn; a
22091
+ * missing pnpmfile (neither `.mjs` nor `.cjs`) is the one legitimate skip,
22092
+ * discriminated inside the child by `err.url` equality exactly as
22093
+ * `layerLive` discriminates in process; any other load failure — a syntax
22094
+ * error, a throwing top level, an `ERR_MODULE_NOT_FOUND` for a module the
22095
+ * pnpmfile itself imports — and a hook that throws when called are serialized
22096
+ * back per-name and surface typed as a `hooks`-source `CatalogAssemblyError`
22097
+ * naming that dependency. A hook's returned *data* stays tolerantly threaded
22098
+ * (last well-formed write wins), never fatal. Spawn and transport failures —
22099
+ * `node` absent, a non-zero exit without a result payload, unparseable
22100
+ * output — fail typed too, never a defect and never a silent skip.
22101
+ *
22102
+ * Two bounds this layer imposes that `layerLive` cannot: the replay is
22103
+ * given thirty seconds (a pnpmfile that loops or awaits forever fails typed
22104
+ * instead of hanging the memoized assemble pass — a subprocess is killable,
22105
+ * while `layerLive`'s in-process synchronous hook call is not interruptible
22106
+ * by any means, so the asymmetry is inherent, not a parity violation), and
22107
+ * the child's stdout is captured under `Run.jsonLine`'s 16 MiB default
22108
+ * ceiling (a hook that logs more than that fails typed as `tooLarge`, where
22109
+ * `layerLive` — which captures nothing — would succeed).
22110
+ *
22111
+ * Catalog folding and normalization stay in the **parent** (the same
22112
+ * `@pnpm/catalogs`-derived path `layerLive` uses); the child returns only the
22113
+ * raw threaded config slice, since the script cannot import kit code.
22114
+ *
22115
+ * Requires core's `ChildProcessSpawner`, resolved when the layer is built —
22116
+ * the consumer provides it once at the edge (`@effect/platform-node`'s
22117
+ * `NodeServices.layer`), the same discharge `@effected/git` uses. Wired by
22118
+ * `WorkspaceCatalogs.layerWithConfigDependenciesSubprocess` /
22119
+ * `Workspaces.layerWithConfigDependenciesSubprocess`.
22120
+ */
22121
+ static layerSubprocess = effect.Layer.effect(ConfigDependencyHooks, effect.Effect.gen(function* () {
22122
+ const spawner = yield* effect_unstable_process.ChildProcessSpawner.ChildProcessSpawner;
22123
+ return { inject: (root, configDependencies, seed) => effect.Effect.gen(function* () {
22124
+ const names = Object.keys(configDependencies);
22125
+ if (names.length === 0) return {
22126
+ catalogs: seed,
22127
+ releaseAge: {}
22128
+ };
22129
+ for (const name of names) if (hasTraversalSegment(name)) return yield* effect.Effect.fail(new CatalogAssemblyError({
22130
+ source: "hooks",
22131
+ path: name,
22132
+ cause: /* @__PURE__ */ new Error(`config dependency name has a '..' path segment: ${name}`)
22133
+ }));
22134
+ const command = effect_unstable_process.ChildProcess.make("node", [
22135
+ "--input-type=module",
22136
+ "-e",
22137
+ REPLAY_SCRIPT,
22138
+ root,
22139
+ JSON.stringify(seed),
22140
+ ...names
22141
+ ]);
22142
+ const payload = yield* Run.jsonLine(command, ReplayPayload, { timeout: REPLAY_TIMEOUT }).pipe(effect.Effect.provideService(effect_unstable_process.ChildProcessSpawner.ChildProcessSpawner, spawner), effect.Effect.catch((cause) => effect.Effect.fail(new CatalogAssemblyError({
22143
+ source: "hooks",
22144
+ path: root,
22145
+ cause
22146
+ }))));
22147
+ if (payload.ok === false) return yield* effect.Effect.fail(new CatalogAssemblyError({
22148
+ source: "hooks",
22149
+ path: payload.name ?? root,
22150
+ cause: replayFailureCause(payload)
22151
+ }));
22152
+ const config = configOf(payload.config, seedToConfig(seed));
22153
+ return {
22154
+ catalogs: configToEntries(config),
22155
+ releaseAge: releaseAgeOf(config)
22156
+ };
22157
+ }) };
22158
+ }));
20892
22159
  };
20893
22160
  //#endregion
20894
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/PackageManagerName.js
22161
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/PackageManagerName.js
20895
22162
  /**
20896
22163
  * The four package managers this package understands.
20897
22164
  *
@@ -21219,7 +22486,7 @@ var PackageManagerDetector = class PackageManagerDetector extends effect.Context
21219
22486
  static layerTest = (overrides = {}) => effect.Layer.succeed(PackageManagerDetector, PackageManagerDetector.makeTest(overrides));
21220
22487
  };
21221
22488
  //#endregion
21222
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/LockfileReader.js
22489
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/LockfileReader.js
21223
22490
  /**
21224
22491
  * Raised when the workspace's lockfile cannot be read off disk.
21225
22492
  *
@@ -21399,7 +22666,7 @@ var LockfileReader = class LockfileReader extends effect.Context.Service()("@eff
21399
22666
  static layerTest = (overrides = {}) => effect.Layer.succeed(LockfileReader, LockfileReader.makeTest(overrides));
21400
22667
  };
21401
22668
  //#endregion
21402
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/Publishability.js
22669
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/Publishability.js
21403
22670
  /** The public npm registry, used when `publishConfig.registry` says nothing. */
21404
22671
  const DEFAULT_REGISTRY = "https://registry.npmjs.org/";
21405
22672
  /**
@@ -21558,7 +22825,7 @@ var PublishabilityDetector = class extends effect.Context.Service()("@effected/w
21558
22825
  static layerNone = effect.Layer.succeed(this, this.none);
21559
22826
  };
21560
22827
  //#endregion
21561
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/importerVersions.js
22828
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/importerVersions.js
21562
22829
  /**
21563
22830
  * Strip pnpm's peer-disambiguation suffix from a recorded importer version.
21564
22831
  *
@@ -21644,7 +22911,7 @@ const unanimousVersionOf = (index, dependency) => {
21644
22911
  return agreed;
21645
22912
  };
21646
22913
  //#endregion
21647
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspaceCatalogs.js
22914
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspaceCatalogs.js
21648
22915
  /**
21649
22916
  * An immutable, fully-normalized catalog collection — the one catalog
21650
22917
  * resolution semantic in the package.
@@ -22065,6 +23332,24 @@ var WorkspaceCatalogs = class WorkspaceCatalogs extends effect.Context.Service()
22065
23332
  */
22066
23333
  static layerWithConfigDependencies = (options) => effect.Layer.effect(WorkspaceCatalogs, WorkspaceCatalogs.make(options)).pipe(effect.Layer.provide(ConfigDependencyHooks.layerLive));
22067
23334
  /**
23335
+ * The opt-in layer that replays config-dependency `pnpmfile` hooks in a
23336
+ * `node` **child process**: it wires
23337
+ * {@link ConfigDependencyHooks.layerSubprocess} in place of the in-process
23338
+ * `layerLive`.
23339
+ *
23340
+ * @remarks
23341
+ * Same typed semantics as {@link WorkspaceCatalogs.layerWithConfigDependencies}
23342
+ * — the two hook layers are drop-in interchangeable — but the replay's
23343
+ * computed dynamic `import()` runs in the subprocess, so it survives bundling
23344
+ * (a bundler compiles a computed in-process `import()` into a context module
23345
+ * that cannot resolve at runtime — every bundled GitHub Action hits this).
23346
+ * The cost is one extra requirement: core's `ChildProcessSpawner`, provided
23347
+ * once at the edge (`@effect/platform-node`'s `NodeServices.layer`) — the
23348
+ * same sanctioned R-widening as `Workspaces.layerWithGit`. Parameterized, so
23349
+ * bind it to a `const` and reuse it.
23350
+ */
23351
+ static layerWithConfigDependenciesSubprocess = (options) => effect.Layer.effect(WorkspaceCatalogs, WorkspaceCatalogs.make(options)).pipe(effect.Layer.provide(ConfigDependencyHooks.layerSubprocess));
23352
+ /**
22068
23353
  * A test double satisfying the full {@link WorkspaceCatalogsShape} with no
22069
23354
  * filesystem, lockfile read, or hook replay.
22070
23355
  *
@@ -22141,9 +23426,9 @@ var WorkspaceCatalogs = class WorkspaceCatalogs extends effect.Context.Service()
22141
23426
  * consumers to `_tag`-sniff `unknown`); only the remaining mechanism failure,
22142
23427
  * an unfindable workspace root, is wrapped as `DependencyResolutionError`.
22143
23428
  */
22144
- static catalogResolver = effect.Layer.effect(CatalogResolver, effect.Effect.gen(function* () {
23429
+ static catalogResolver = effect.Layer.effect(CatalogResolver$1, effect.Effect.gen(function* () {
22145
23430
  const catalogs = yield* WorkspaceCatalogs;
22146
- return { rangeOf: (packageName, catalog) => catalogs.set().pipe(effect.Effect.map((set) => set.rangeOf(packageName, catalog)), effect.Effect.catchTag("WorkspaceRootNotFoundError", (cause) => effect.Effect.fail(new DependencyResolutionError({
23431
+ return { rangeOf: (packageName, catalog) => catalogs.set().pipe(effect.Effect.map((set) => set.rangeOf(packageName, catalog)), effect.Effect.catchTag("WorkspaceRootNotFoundError", (cause) => effect.Effect.fail(new DependencyResolutionError$1({
22147
23432
  specifier: effect.Option.match(catalog, {
22148
23433
  onNone: () => "catalog:",
22149
23434
  onSome: (name) => `catalog:${name}`
@@ -22153,7 +23438,7 @@ var WorkspaceCatalogs = class WorkspaceCatalogs extends effect.Context.Service()
22153
23438
  }));
22154
23439
  };
22155
23440
  //#endregion
22156
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspaceStateSnapshot.js
23441
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspaceStateSnapshot.js
22157
23442
  const EMPTY = Object.freeze(Object.create(null));
22158
23443
  const DependencyMap = effect.Schema.Record(effect.Schema.String, effect.Schema.String).pipe(effect.Schema.withDecodingDefaultKey(effect.Effect.succeed(EMPTY)), effect.Schema.withConstructorDefault(effect.Effect.succeed(EMPTY)));
22159
23444
  /**
@@ -22332,7 +23617,7 @@ var WorkspaceStateSnapshot = class extends effect.Schema.Class("WorkspaceStateSn
22332
23617
  * resolving to `Option.none()` so the caller falls back to the raw string.
22333
23618
  */
22334
23619
  #resolveWith(dependency, specifier, onUnresolvedCatalog) {
22335
- const exit = effect.Schema.decodeUnknownExit(DependencySpecifier.FromString)(specifier);
23620
+ const exit = effect.Schema.decodeUnknownExit(DependencySpecifier$1.FromString)(specifier);
22336
23621
  if (!effect.Exit.isSuccess(exit)) return effect.Option.none();
22337
23622
  const classified = exit.value;
22338
23623
  switch (classified._tag) {
@@ -22357,7 +23642,7 @@ var WorkspaceStateSnapshot = class extends effect.Schema.Class("WorkspaceStateSn
22357
23642
  * `rangeOf` never fails.
22358
23643
  */
22359
23644
  get catalogResolver() {
22360
- if (this.#catalogResolver === void 0) this.#catalogResolver = effect.Layer.succeed(CatalogResolver, { rangeOf: (packageName, catalog) => effect.Effect.succeed(this.catalogs.rangeOf(packageName, catalog)) });
23645
+ if (this.#catalogResolver === void 0) this.#catalogResolver = effect.Layer.succeed(CatalogResolver$1, { rangeOf: (packageName, catalog) => effect.Effect.succeed(this.catalogs.rangeOf(packageName, catalog)) });
22361
23646
  return this.#catalogResolver;
22362
23647
  }
22363
23648
  /**
@@ -22366,7 +23651,7 @@ var WorkspaceStateSnapshot = class extends effect.Schema.Class("WorkspaceStateSn
22366
23651
  * `workspace:` specifiers as of this ref. Built once per instance and cached.
22367
23652
  */
22368
23653
  get workspaceResolver() {
22369
- if (this.#workspaceResolver === void 0) this.#workspaceResolver = effect.Layer.succeed(WorkspaceResolver, { versionOf: (packageName) => effect.Effect.succeed(effect.Option.fromUndefinedOr(this.#versions().get(packageName))) });
23654
+ if (this.#workspaceResolver === void 0) this.#workspaceResolver = effect.Layer.succeed(WorkspaceResolver$1, { versionOf: (packageName) => effect.Effect.succeed(effect.Option.fromUndefinedOr(this.#versions().get(packageName))) });
22370
23655
  return this.#workspaceResolver;
22371
23656
  }
22372
23657
  /** Both snapshot-scoped resolver layers merged. Built once per instance and cached. */
@@ -22376,7 +23661,7 @@ var WorkspaceStateSnapshot = class extends effect.Schema.Class("WorkspaceStateSn
22376
23661
  }
22377
23662
  };
22378
23663
  //#endregion
22379
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspaceSnapshots.js
23664
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspaceSnapshots.js
22380
23665
  /** Whether `value` is a non-null, non-array object. */
22381
23666
  const isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
22382
23667
  /** Whether every value in a record is a string — a usable dependency map. */
@@ -22653,7 +23938,7 @@ var WorkspaceSnapshots = class WorkspaceSnapshots extends effect.Context.Service
22653
23938
  static layerTest = (overrides = {}) => effect.Layer.succeed(WorkspaceSnapshots, WorkspaceSnapshots.makeTest(overrides));
22654
23939
  };
22655
23940
  //#endregion
22656
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/Workspaces.js
23941
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/Workspaces.js
22657
23942
  const compose = (options, catalogsFactory) => {
22658
23943
  const roots = WorkspaceRoot.layer;
22659
23944
  const detector = PackageManagerDetector.layer;
@@ -22670,6 +23955,7 @@ const layerWithGit = (options) => {
22670
23955
  };
22671
23956
  const resolvers = effect.Layer.mergeAll(WorkspaceCatalogs.catalogResolver, WorkspaceDiscovery.workspaceResolver);
22672
23957
  const layerWithConfigDependencies = (options) => compose(options, WorkspaceCatalogs.layerWithConfigDependencies);
23958
+ const layerWithConfigDependenciesSubprocess = (options) => compose(options, WorkspaceCatalogs.layerWithConfigDependenciesSubprocess);
22673
23959
  const resolverLayer = (options) => resolvers.pipe(effect.Layer.provide(layerWithConfigDependencies(options)));
22674
23960
  const resolveManifest = effect.Effect.fn("Workspaces.resolveManifest")(function* (manifest, options) {
22675
23961
  return yield* manifest.resolve().pipe(effect.Effect.provide(resolverLayer(options)));
@@ -22751,6 +24037,32 @@ var Workspaces = class {
22751
24037
  */
22752
24038
  static layerWithConfigDependencies = layerWithConfigDependencies;
22753
24039
  /**
24040
+ * The git-free composite with config-dependency hook replay in a `node`
24041
+ * **child process** —
24042
+ * {@link WorkspaceCatalogs.layerWithConfigDependenciesSubprocess} in place of
24043
+ * the in-process replay.
24044
+ *
24045
+ * @remarks
24046
+ * Same typed semantics as {@link Workspaces.layerWithConfigDependencies}; the
24047
+ * difference is mechanism, and it matters in exactly one environment class: a
24048
+ * **bundled** consumer. The in-process replay's computed dynamic `import()`
24049
+ * is compiled by bundlers (rspack among them) into a context module that
24050
+ * throws `Cannot find module 'file:///…'` at runtime, which makes
24051
+ * `WorkspaceCatalogs.releaseAgeGate()` unreachable from any bundled GitHub
24052
+ * Action. Here the computed import runs inside a `node` child process whose
24053
+ * program text is a static string handed over argv, so nothing computed
24054
+ * enters the bundle graph.
24055
+ *
24056
+ * The extra requirement is core's `ChildProcessSpawner`, provided once at
24057
+ * the edge (`@effect/platform-node`'s `NodeServices.layer`) — the same
24058
+ * sanctioned R-widening as {@link Workspaces.layerWithGit}, and the reason
24059
+ * this is a separate composite rather than a flag: a consumer that keeps the
24060
+ * in-process replay should not have to be able to spawn a subprocess.
24061
+ *
24062
+ * **Bind the result to a `const`.**
24063
+ */
24064
+ static layerWithConfigDependenciesSubprocess = layerWithConfigDependenciesSubprocess;
24065
+ /**
22754
24066
  * The git-free composite plus {@link ChangeDetector} and
22755
24067
  * {@link WorkspaceSnapshots}, over `@effected/git`'s `Git` service.
22756
24068
  *