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