@savvy-web/silk 3.2.2 → 3.2.4

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.
@@ -176,27 +176,6 @@ const SilkChangesetConfigFile = effect.Schema.Struct({
176
176
  ...ChangesetConfigFile.fields,
177
177
  _isSilk: effect.Schema.Boolean.pipe(effect.Schema.withDecodingDefaultType(effect.Effect.succeed(true)), effect.Schema.withConstructorDefault(effect.Effect.succeed(true)))
178
178
  });
179
- /**
180
- * Versioning strategy classification for a workspace.
181
- *
182
- * @remarks
183
- * - `"single"` — one publishable package; a single version tag is used.
184
- * - `"fixed-group"` — all publishable packages are in the same changesets fixed group.
185
- * - `"independent"` — multiple publishable packages with independent version bumps.
186
- *
187
- * @since 0.1.0
188
- * @public
189
- */
190
- const VersioningStrategyType = effect.Schema.Literals([
191
- "single",
192
- "fixed-group",
193
- "independent"
194
- ]);
195
- effect.Schema.Struct({
196
- type: VersioningStrategyType,
197
- fixedGroups: effect.Schema.Array(effect.Schema.Array(effect.Schema.String)),
198
- publishablePackages: effect.Schema.Array(effect.Schema.String)
199
- });
200
179
  //#endregion
201
180
  //#region ../silk-effects/dist/dev/pkg/services/ChangesetConfigReader.js
202
181
  /**
@@ -2357,7 +2336,7 @@ var GlobSet = class GlobSet extends effect.Schema.Class("GlobSet")(effect.Schema
2357
2336
  }
2358
2337
  };
2359
2338
  //#endregion
2360
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.1.10_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__@effected+npm@0_baf93f2c33d0504f713f685ac5710e50/node_modules/@effected/lockfiles/BunExtension.js
2339
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.2.1_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__@effected+npm@0._44d8f67a8ab767df898f59f0e01343be/node_modules/@effected/lockfiles/BunExtension.js
2361
2340
  /**
2362
2341
  * Extension data specific to bun lockfiles, attached to `Lockfile.extension`
2363
2342
  * when the format is `"bun"`.
@@ -2378,7 +2357,7 @@ var BunExtension = class extends effect.Schema.Class("BunExtension")({
2378
2357
  trustedDependencies: effect.Schema.optionalKey(effect.Schema.Array(effect.Schema.String))
2379
2358
  }) {};
2380
2359
  //#endregion
2381
- //#region ../../node_modules/.pnpm/@effected+npm@0.3.1_@effected+semver@0.2.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/CatalogResolver.js
2360
+ //#region ../../node_modules/.pnpm/@effected+npm@0.5.0_@effected+semver@0.2.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/CatalogResolver.js
2382
2361
  /**
2383
2362
  * Contract for resolving pnpm `catalog:` dependency specifiers to concrete
2384
2363
  * version ranges.
@@ -2424,7 +2403,7 @@ var CatalogResolver = class CatalogResolver extends effect.Context.Service()("@e
2424
2403
  static noop = effect.Layer.succeed(CatalogResolver, { rangeOf: () => effect.Effect.succeed(effect.Option.none()) });
2425
2404
  };
2426
2405
  //#endregion
2427
- //#region ../../node_modules/.pnpm/@effected+npm@0.3.1_@effected+semver@0.2.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/WorkspaceResolver.js
2406
+ //#region ../../node_modules/.pnpm/@effected+npm@0.5.0_@effected+semver@0.2.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/WorkspaceResolver.js
2428
2407
  /**
2429
2408
  * Raised when a `catalog:` or `workspace:` specifier cannot be resolved
2430
2409
  * because the resolution mechanism itself failed — not for an ordinary
@@ -2485,7 +2464,7 @@ var WorkspaceResolver = class WorkspaceResolver extends effect.Context.Service()
2485
2464
  static noop = effect.Layer.succeed(WorkspaceResolver, { versionOf: () => effect.Effect.succeed(effect.Option.none()) });
2486
2465
  };
2487
2466
  //#endregion
2488
- //#region ../../node_modules/.pnpm/@effected+npm@0.3.1_@effected+semver@0.2.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/CatalogAssemblyError.js
2467
+ //#region ../../node_modules/.pnpm/@effected+npm@0.5.0_@effected+semver@0.2.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/CatalogAssemblyError.js
2489
2468
  /**
2490
2469
  * Raised when a workspace's catalogs cannot be assembled — a `pnpm-workspace.yaml`
2491
2470
  * that is unreadable or not valid YAML, a root `package.json` `workspaces` field
@@ -2529,7 +2508,7 @@ var CatalogAssemblyError = class extends effect.Schema.TaggedErrorClass()("Catal
2529
2508
  }
2530
2509
  };
2531
2510
  //#endregion
2532
- //#region ../../node_modules/.pnpm/@effected+npm@0.3.1_@effected+semver@0.2.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/DependencySection.js
2511
+ //#region ../../node_modules/.pnpm/@effected+npm@0.5.0_@effected+semver@0.2.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/DependencySection.js
2533
2512
  /**
2534
2513
  * The short dependency kind: which dependency map an entry came from, named the
2535
2514
  * way consumers branch on it.
@@ -4030,7 +4009,7 @@ const isComparatorSetSubset = (sub, sup) => {
4030
4009
  return true;
4031
4010
  };
4032
4011
  //#endregion
4033
- //#region ../../node_modules/.pnpm/@effected+npm@0.3.1_@effected+semver@0.2.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/DependencySpecifier.js
4012
+ //#region ../../node_modules/.pnpm/@effected+npm@0.5.0_@effected+semver@0.2.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/DependencySpecifier.js
4034
4013
  /**
4035
4014
  * Indicates that a string could not be parsed as a valid dependency specifier.
4036
4015
  *
@@ -4237,7 +4216,7 @@ const DependencySpecifier = Object.assign(brandedSpecifier, {
4237
4216
  FromString: fromString
4238
4217
  });
4239
4218
  //#endregion
4240
- //#region ../../node_modules/.pnpm/@effected+npm@0.3.1_@effected+semver@0.2.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/IntegrityHash.js
4219
+ //#region ../../node_modules/.pnpm/@effected+npm@0.5.0_@effected+semver@0.2.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/IntegrityHash.js
4241
4220
  const SRI_RE = /^(sha1|sha256|sha384|sha512)-[A-Za-z0-9+/]+={0,2}$/;
4242
4221
  const COREPACK_RE = /^(sha1|sha256|sha384|sha512)\.[0-9a-f]+$/;
4243
4222
  const YARN_RE = /^[0-9]+(c[0-9]+)?\/[0-9a-f]+$/;
@@ -4289,8 +4268,166 @@ const IntegrityHash = Object.assign(brandedIntegrity, {
4289
4268
  algorithmOf,
4290
4269
  decode: decode$2
4291
4270
  });
4271
+ effect.Schema.Literals([
4272
+ "npm",
4273
+ "pnpm",
4274
+ "yarn",
4275
+ "bun"
4276
+ ]);
4277
+ /** The argv prefixes for each launcher. The one place this knowledge lives. */
4278
+ const PREFIXES = {
4279
+ npm: {
4280
+ prefix: [
4281
+ "npx",
4282
+ "--no",
4283
+ "--"
4284
+ ],
4285
+ dlxPrefix: ["npx"]
4286
+ },
4287
+ pnpm: {
4288
+ prefix: ["pnpm", "exec"],
4289
+ dlxPrefix: ["pnpm", "dlx"]
4290
+ },
4291
+ yarn: {
4292
+ prefix: ["yarn", "exec"],
4293
+ dlxPrefix: ["yarn", "dlx"]
4294
+ },
4295
+ bun: {
4296
+ prefix: [
4297
+ "bun",
4298
+ "x",
4299
+ "--no-install"
4300
+ ],
4301
+ dlxPrefix: ["bun", "x"]
4302
+ }
4303
+ };
4304
+ /**
4305
+ * How to run a project-local binary here.
4306
+ *
4307
+ * @remarks
4308
+ * This is the whole of what tool discovery needs from a workspace: an argv
4309
+ * prefix and a directory to run it in. It deliberately carries no workspace
4310
+ * root, no manifest and no package-manager semantics — `label` is for
4311
+ * reporting only, and nothing in this package branches on it.
4312
+ *
4313
+ * @public
4314
+ */
4315
+ var ExecContext = class extends effect.Schema.Class("ExecContext")({
4316
+ /** Human label of the launcher, e.g. `"pnpm"`. Reporting only. */
4317
+ label: effect.Schema.String,
4318
+ /** argv prefix that runs a project-local binary, e.g. `["pnpm", "exec"]`. */
4319
+ prefix: effect.Schema.Array(effect.Schema.String),
4320
+ /** argv prefix that fetch-and-runs a package binary, e.g. `["pnpm", "dlx"]`. */
4321
+ dlxPrefix: effect.Schema.Array(effect.Schema.String),
4322
+ /** Directory the prefix must run in. Omitted means "wherever the caller is". */
4323
+ directory: effect.Schema.optionalKey(effect.Schema.String)
4324
+ }) {
4325
+ /** Prefixes `command` with `prefix` and applies `directory`, returning a core `Command`. */
4326
+ apply(command) {
4327
+ return this.withPrefix(command, this.prefix);
4328
+ }
4329
+ /** As {@link ExecContext.apply}, using `dlxPrefix` — the fetch-and-run launcher. */
4330
+ applyDlx(command) {
4331
+ return this.withPrefix(command, this.dlxPrefix);
4332
+ }
4333
+ /**
4334
+ * Core's `prefix` and `setCwd` both return NEW commands, so the caller's
4335
+ * value is never mutated.
4336
+ */
4337
+ withPrefix(command, prefix) {
4338
+ const [head, ...rest] = prefix;
4339
+ const prefixed = head === void 0 ? command : effect_unstable_process.ChildProcess.prefix(command, head, rest);
4340
+ return this.directory === void 0 ? prefixed : effect_unstable_process.ChildProcess.setCwd(prefixed, this.directory);
4341
+ }
4342
+ };
4343
+ /**
4344
+ * The project-local execution context could not be determined.
4345
+ *
4346
+ * @remarks
4347
+ * A *mechanism* failure — an unreadable manifest, a detection error. "There is
4348
+ * no project-local way to run tools here" is `Option.none()`, never this error:
4349
+ * the same `None`-is-success convention `@effected/npm`'s resolver contracts
4350
+ * use, so an implementation never has to decide whether absence is exceptional.
4351
+ *
4352
+ * @public
4353
+ */
4354
+ var LocalExecError = class extends effect.Schema.TaggedErrorClass()("LocalExecError", {
4355
+ /** The directory whose context could not be determined, when one is known. */
4356
+ directory: effect.Schema.optionalKey(effect.Schema.String),
4357
+ /** The underlying failure. */
4358
+ cause: effect.Schema.optionalKey(effect.Schema.Defect())
4359
+ }) {
4360
+ get message() {
4361
+ return this.directory === void 0 ? "Could not determine the project-local execution context" : `Could not determine the project-local execution context for ${this.directory}`;
4362
+ }
4363
+ };
4364
+ /**
4365
+ * Contract: how to run a project-local binary in this project.
4366
+ *
4367
+ * @remarks
4368
+ * **This is an inverted contract.** Tool discovery needs package-manager
4369
+ * detection and workspace-root resolution, both of which live in the
4370
+ * integrated-tier `@effected/workspaces`. Depending on it directly would make
4371
+ * this package integrated too — and, through the planned `@effected/npm` edge,
4372
+ * would drag `npm`, `lockfiles` and `package-json` up a tier with it. So this
4373
+ * package declares the narrow contract and `@effected/workspaces` ships the
4374
+ * layer that implements it, exactly as `@effected/npm` owns `CatalogResolver`
4375
+ * and workspaces implements that.
4376
+ *
4377
+ * A consumer with no monorepo never needs that implementation:
4378
+ * {@link LocalExec.layerNone} (global-only) and {@link LocalExec.layerFor}
4379
+ * (a known package manager) are one-liners.
4380
+ *
4381
+ * @public
4382
+ */
4383
+ var LocalExec = class LocalExec extends effect.Context.Service()("@effected/commands/LocalExec") {
4384
+ /** The exec and dlx argv prefixes for a launcher — the single home of that knowledge. */
4385
+ static prefixes = (launcher) => PREFIXES[launcher];
4386
+ /**
4387
+ * No project-local execution context: every tool resolves globally.
4388
+ *
4389
+ * @remarks
4390
+ * The right wiring for a GitHub Action or any single-package checkout, and
4391
+ * the reason such a consumer never installs `@effected/workspaces`.
4392
+ */
4393
+ static layerNone = effect.Layer.succeed(this, { context: effect.Effect.succeed(effect.Option.none()) });
4394
+ /** A context for a known package manager, from the static prefix table. */
4395
+ static layerFor = (launcher, options) => {
4396
+ const { prefix, dlxPrefix } = PREFIXES[launcher];
4397
+ return LocalExec.layerContext(ExecContext.make({
4398
+ label: launcher,
4399
+ prefix,
4400
+ dlxPrefix,
4401
+ ...options?.directory === void 0 ? {} : { directory: options.directory }
4402
+ }));
4403
+ };
4404
+ /** A caller-supplied context, answered verbatim. */
4405
+ static layerContext = (context) => effect.Layer.succeed(LocalExec, { context: effect.Effect.succeed(effect.Option.some(context)) });
4406
+ /**
4407
+ * An in-memory test double.
4408
+ *
4409
+ * @remarks
4410
+ * Unlike most `makeTest` doubles in the kit, the unstubbed default here is
4411
+ * **honest rather than loud**: `Option.none()` is a real, correct answer
4412
+ * ("no project-local context"), so a test that does not care about local
4413
+ * resolution gets the global-only behavior instead of a defect.
4414
+ */
4415
+ static makeTest = (overrides = {}) => ({
4416
+ context: effect.Effect.succeed(effect.Option.none()),
4417
+ ...overrides
4418
+ });
4419
+ /**
4420
+ * {@link LocalExec.makeTest} behind `Layer.succeed`.
4421
+ *
4422
+ * @remarks
4423
+ * A parameterized layer factory mints a fresh reference per call and layers
4424
+ * memoize by reference — bind the result to a `const` rather than calling it
4425
+ * at each composition site.
4426
+ */
4427
+ static layerTest = (overrides = {}) => effect.Layer.succeed(LocalExec, LocalExec.makeTest(overrides));
4428
+ };
4292
4429
  //#endregion
4293
- //#region ../../node_modules/.pnpm/@effected+npm@0.3.1_@effected+semver@0.2.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/ReleaseAgeGate.js
4430
+ //#region ../../node_modules/.pnpm/@effected+npm@0.5.0_@effected+semver@0.2.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/ReleaseAgeGate.js
4294
4431
  const MS_PER_MINUTE = 6e4;
4295
4432
  /**
4296
4433
  * A source's partial contribution to a {@link ReleaseAgeGate}: the effective
@@ -4378,7 +4515,9 @@ var ReleaseAgeGate = class ReleaseAgeGate extends effect.Schema.Class("ReleaseAg
4378
4515
  * Combine partial contributions from multiple sources into one effective
4379
4516
  * gate: **strictest age wins** (the maximum of the contributed ages,
4380
4517
  * clamped to be non-negative) and the exclude sets **union** (deduplicated,
4381
- * insertion order preserved). A contribution's absent field adds nothing; a
4518
+ * lexicographically sorted a canonical wire form, so the combined gate is
4519
+ * deterministic regardless of the order contributions arrive in). A
4520
+ * contribution's absent field adds nothing; a
4382
4521
  * negative or non-finite contributed age is ignored by the clamp. With no
4383
4522
  * contributions (or only empty ones) the result is the inert zero gate
4384
4523
  * (`ageMinutes: 0`, `exclude: []`).
@@ -4392,7 +4531,7 @@ var ReleaseAgeGate = class ReleaseAgeGate extends effect.Schema.Class("ReleaseAg
4392
4531
  static combine(...contributions) {
4393
4532
  const ages = contributions.map((contribution) => contribution.ageMinutes).filter((age) => typeof age === "number" && Number.isFinite(age));
4394
4533
  const ageMinutes = ages.length > 0 ? Math.max(0, ...ages) : 0;
4395
- const exclude = [...new Set(contributions.flatMap((contribution) => contribution.exclude ?? []))];
4534
+ const exclude = [...new Set(contributions.flatMap((contribution) => contribution.exclude ?? []))].sort();
4396
4535
  return ReleaseAgeGate.make({
4397
4536
  ageMinutes,
4398
4537
  exclude
@@ -4458,7 +4597,7 @@ var ReleaseAgeGate = class ReleaseAgeGate extends effect.Schema.Class("ReleaseAg
4458
4597
  }
4459
4598
  };
4460
4599
  //#endregion
4461
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.1.10_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__@effected+npm@0_baf93f2c33d0504f713f685ac5710e50/node_modules/@effected/lockfiles/ImporterDependency.js
4600
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.2.1_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__@effected+npm@0._44d8f67a8ab767df898f59f0e01343be/node_modules/@effected/lockfiles/ImporterDependency.js
4462
4601
  /**
4463
4602
  * One declared dependency of one workspace importer, as the lockfile records it.
4464
4603
  *
@@ -4469,11 +4608,20 @@ var ReleaseAgeGate = class ReleaseAgeGate extends effect.Schema.Class("ReleaseAg
4469
4608
  * `ClassifiedSpecifier` (`catalog:` / `workspace:` / range / dist-tag / raw),
4470
4609
  * while encoding round-trips the **exact original string byte-for-byte** — the
4471
4610
  * guarantee a before/after lockfile diff relies on.
4472
- * - `version` — the concrete resolved version, **populated by pnpm only**. pnpm
4473
- * records `{ specifier, version }` per importer dependency; bun and npm record
4474
- * resolved versions on their package entries instead, so for those formats
4475
- * `version` is absent and a consumer joins by `name` against
4476
- * `Lockfile.packages`.
4611
+ * - `version` — the concrete resolved version, **populated by pnpm only**:
4612
+ * comparable across refs and printable. pnpm records `{ specifier, version }`
4613
+ * per importer dependency, and the parser splits pnpm's peer-disambiguation
4614
+ * suffix off into `peerSuffix`, so `version` is always the plain version or
4615
+ * a non-registry resolution (`link:../utils`, `file:...`), passed through
4616
+ * verbatim. bun and npm record resolved versions on their package entries
4617
+ * instead, so for those formats `version` is absent and a consumer joins by
4618
+ * `name` against `Lockfile.packages`.
4619
+ * - `peerSuffix` — pnpm's peer-disambiguation context: the raw parenthesized
4620
+ * chain the lockfile recorded after the version, e.g.
4621
+ * `(effect@4.0.0-beta.101)(ioredis@5.11.1(supports-color@8.1.1))`. Present
4622
+ * only when the lockfile recorded one — never for suffix-free pnpm entries,
4623
+ * and never for the other formats, which do not record peer context per
4624
+ * importer dependency.
4477
4625
  * - `depType` — which dependency map declared it, spelled with `@effected/npm`'s
4478
4626
  * kit-wide `DependencyField` vocabulary.
4479
4627
  *
@@ -4483,10 +4631,11 @@ var ImporterDependency = class extends effect.Schema.Class("ImporterDependency")
4483
4631
  name: effect.Schema.NonEmptyString,
4484
4632
  specifier: DependencySpecifier.FromString,
4485
4633
  version: effect.Schema.optionalKey(effect.Schema.String),
4634
+ peerSuffix: effect.Schema.optionalKey(effect.Schema.String),
4486
4635
  depType: DependencyField
4487
4636
  }) {};
4488
4637
  //#endregion
4489
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.1.10_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__@effected+npm@0_baf93f2c33d0504f713f685ac5710e50/node_modules/@effected/lockfiles/LockfileImporter.js
4638
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.2.1_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__@effected+npm@0._44d8f67a8ab767df898f59f0e01343be/node_modules/@effected/lockfiles/LockfileImporter.js
4490
4639
  /**
4491
4640
  * One workspace importer's declared dependencies, as the lockfile records them.
4492
4641
  *
@@ -4510,7 +4659,7 @@ var LockfileImporter = class extends effect.Schema.Class("LockfileImporter")({
4510
4659
  dependencies: effect.Schema.Array(ImporterDependency)
4511
4660
  }) {};
4512
4661
  //#endregion
4513
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.1.10_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__@effected+npm@0_baf93f2c33d0504f713f685ac5710e50/node_modules/@effected/lockfiles/ResolvedPackage.js
4662
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.2.1_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__@effected+npm@0._44d8f67a8ab767df898f59f0e01343be/node_modules/@effected/lockfiles/ResolvedPackage.js
4514
4663
  const EMPTY_DEPENDENCIES = {};
4515
4664
  /**
4516
4665
  * A package resolved from a lockfile.
@@ -4545,7 +4694,7 @@ var ResolvedPackage = class extends effect.Schema.Class("ResolvedPackage")({
4545
4694
  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)))
4546
4695
  }) {};
4547
4696
  //#endregion
4548
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.1.10_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__@effected+npm@0_baf93f2c33d0504f713f685ac5710e50/node_modules/@effected/lockfiles/WorkspaceDependency.js
4697
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.2.1_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__@effected+npm@0._44d8f67a8ab767df898f59f0e01343be/node_modules/@effected/lockfiles/WorkspaceDependency.js
4549
4698
  /**
4550
4699
  * A directed dependency edge between two workspace packages as recorded in
4551
4700
  * the lockfile.
@@ -4567,7 +4716,7 @@ var WorkspaceDependency = class extends effect.Schema.Class("WorkspaceDependency
4567
4716
  constraint: effect.Schema.String
4568
4717
  }) {};
4569
4718
  //#endregion
4570
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.1.10_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__@effected+npm@0_baf93f2c33d0504f713f685ac5710e50/node_modules/@effected/lockfiles/PnpmExtension.js
4719
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.2.1_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__@effected+npm@0._44d8f67a8ab767df898f59f0e01343be/node_modules/@effected/lockfiles/PnpmExtension.js
4571
4720
  /**
4572
4721
  * Extension data specific to pnpm lockfiles, attached to `Lockfile.extension`
4573
4722
  * when the format is `"pnpm"`.
@@ -4592,7 +4741,7 @@ var PnpmExtension = class extends effect.Schema.Class("PnpmExtension")({
4592
4741
  }))
4593
4742
  }) {};
4594
4743
  //#endregion
4595
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.1.10_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__@effected+npm@0_baf93f2c33d0504f713f685ac5710e50/node_modules/@effected/lockfiles/LockfileFormat.js
4744
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.2.1_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__@effected+npm@0._44d8f67a8ab767df898f59f0e01343be/node_modules/@effected/lockfiles/LockfileFormat.js
4596
4745
  /**
4597
4746
  * The lockfile formats this package parses: bun's `bun.lock` (JSONC), npm's
4598
4747
  * `package-lock.json` (v2/v3 JSON), pnpm's `pnpm-lock.yaml` and yarn Berry's
@@ -4626,7 +4775,7 @@ const FILENAMES = {
4626
4775
  */
4627
4776
  const filenameFor = (format) => FILENAMES[format];
4628
4777
  //#endregion
4629
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.1.10_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__@effected+npm@0_baf93f2c33d0504f713f685ac5710e50/node_modules/@effected/lockfiles/internal/shared.js
4778
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.2.1_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__@effected+npm@0._44d8f67a8ab767df898f59f0e01343be/node_modules/@effected/lockfiles/internal/shared.js
4630
4779
  /**
4631
4780
  * The four dependency sections of a manifest, in a stable order — the shared
4632
4781
  * dependency-sections table (v3's `DEP_SECTIONS`). Each entry is both the
@@ -4665,22 +4814,54 @@ const toIntegrityHash = (raw) => {
4665
4814
  };
4666
4815
  const decodeSpecifier = effect.Schema.decodeUnknownExit(DependencySpecifier.FromString);
4667
4816
  /**
4817
+ * Split pnpm's peer-disambiguation suffix off a recorded string: everything
4818
+ * from the first `(` on is suffix, since package names and versions never
4819
+ * contain `(`. Handles both shapes pnpm records — a bare version
4820
+ * (`"1.0.0(effect@4.0.0)"`, importer entries) and a `name@version` snapshot key
4821
+ * (`"fdir@6.5.0(picomatch@4.0.4)"`). A string with no `(` — including
4822
+ * `link:...` / `file:...` resolutions — passes through untouched. So does a
4823
+ * protocol-bearing string (a `:` ahead of the first `(`), where a parenthesis
4824
+ * is path or URL text rather than a peer suffix: pnpm attaches suffixes to
4825
+ * registry versions only. This is the single stripping implementation — do not
4826
+ * hand-roll an `indexOf("(")` split elsewhere.
4827
+ *
4828
+ * @internal
4829
+ */
4830
+ const splitPeerSuffix = (raw) => {
4831
+ const parenIndex = raw.indexOf("(");
4832
+ if (parenIndex === -1) return { plain: raw };
4833
+ if (raw.lastIndexOf(":", parenIndex) !== -1) return { plain: raw };
4834
+ return {
4835
+ plain: raw.slice(0, parenIndex),
4836
+ peerSuffix: raw.slice(parenIndex)
4837
+ };
4838
+ };
4839
+ /**
4668
4840
  * Build one {@link ImporterDependency}, decoding the raw specifier string into
4669
4841
  * the `@effected/npm` `ClassifiedSpecifier` tagged union. Returns `undefined`
4670
4842
  * — a skip, never a throw — when the name is empty or the specifier does not
4671
4843
  * classify (e.g. an empty specifier), per the total-string-surgery discipline.
4672
4844
  *
4845
+ * A pnpm-recorded version is normalized through {@link splitPeerSuffix}: the
4846
+ * `version` field carries the plain version and the split-off peer chain lands
4847
+ * in `peerSuffix`. A version that is *only* a peer chain (empty plain part) is
4848
+ * treated as no concrete version — a skip of both fields, never a throw.
4849
+ *
4673
4850
  * @internal
4674
4851
  */
4675
4852
  const buildImporterDependency = (name, specifier, depType, version) => {
4676
4853
  if (name === "") return void 0;
4677
4854
  const exit = decodeSpecifier(specifier);
4678
4855
  if (effect.Exit.isFailure(exit)) return void 0;
4856
+ const resolved = version !== void 0 && version !== "" ? splitPeerSuffix(version) : void 0;
4679
4857
  return ImporterDependency.make({
4680
4858
  name,
4681
4859
  specifier: exit.value,
4682
4860
  depType,
4683
- ...version !== void 0 && version !== "" ? { version } : {}
4861
+ ...resolved !== void 0 && resolved.plain !== "" ? {
4862
+ version: resolved.plain,
4863
+ ...resolved.peerSuffix !== void 0 ? { peerSuffix: resolved.peerSuffix } : {}
4864
+ } : {}
4684
4865
  });
4685
4866
  };
4686
4867
  /**
@@ -6525,7 +6706,7 @@ var JsoncModifier = class {
6525
6706
  });
6526
6707
  };
6527
6708
  //#endregion
6528
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.1.10_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__@effected+npm@0_baf93f2c33d0504f713f685ac5710e50/node_modules/@effected/lockfiles/internal/bun.js
6709
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.2.1_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__@effected+npm@0._44d8f67a8ab767df898f59f0e01343be/node_modules/@effected/lockfiles/internal/bun.js
6529
6710
  const DepRecord$2 = effect.Schema.optionalKey(effect.Schema.Record(effect.Schema.String, effect.Schema.String));
6530
6711
  const BunWorkspaceEntry = effect.Schema.Struct({
6531
6712
  name: effect.Schema.optionalKey(effect.Schema.String),
@@ -6618,7 +6799,7 @@ const toFields$3 = (raw) => effect.Effect.gen(function* () {
6618
6799
  };
6619
6800
  });
6620
6801
  //#endregion
6621
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.1.10_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__@effected+npm@0_baf93f2c33d0504f713f685ac5710e50/node_modules/@effected/lockfiles/internal/npm.js
6802
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.2.1_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__@effected+npm@0._44d8f67a8ab767df898f59f0e01343be/node_modules/@effected/lockfiles/internal/npm.js
6622
6803
  const DepRecord$1 = effect.Schema.optionalKey(effect.Schema.Record(effect.Schema.String, effect.Schema.String));
6623
6804
  const NpmPackageEntry = effect.Schema.Struct({
6624
6805
  name: effect.Schema.optionalKey(effect.Schema.String),
@@ -6716,7 +6897,7 @@ const toFields$2 = (raw) => effect.Effect.gen(function* () {
6716
6897
  };
6717
6898
  });
6718
6899
  //#endregion
6719
- //#region ../../node_modules/.pnpm/@effected+yaml@0.5.1_effect@4.0.0-beta.101/node_modules/@effected/yaml/YamlNode.js
6900
+ //#region ../../node_modules/.pnpm/@effected+yaml@0.6.0_effect@4.0.0-beta.101/node_modules/@effected/yaml/YamlNode.js
6720
6901
  /**
6721
6902
  * YAML scalar presentation styles.
6722
6903
  *
@@ -7118,7 +7299,7 @@ function nodeToValue(node, anchors, budget, counting = false) {
7118
7299
  return null;
7119
7300
  }
7120
7301
  //#endregion
7121
- //#region ../../node_modules/.pnpm/@effected+yaml@0.5.1_effect@4.0.0-beta.101/node_modules/@effected/yaml/internal/diagnostics.js
7302
+ //#region ../../node_modules/.pnpm/@effected+yaml@0.6.0_effect@4.0.0-beta.101/node_modules/@effected/yaml/internal/diagnostics.js
7122
7303
  /** Error codes emitted by the lexer stage. */
7123
7304
  const YAML_LEX_ERROR_CODES = [
7124
7305
  "UnexpectedCharacter",
@@ -7196,7 +7377,7 @@ function isFatalCode(code) {
7196
7377
  return FATAL_CODES.has(code);
7197
7378
  }
7198
7379
  //#endregion
7199
- //#region ../../node_modules/.pnpm/@effected+yaml@0.5.1_effect@4.0.0-beta.101/node_modules/@effected/yaml/YamlDiagnostic.js
7380
+ //#region ../../node_modules/.pnpm/@effected+yaml@0.6.0_effect@4.0.0-beta.101/node_modules/@effected/yaml/YamlDiagnostic.js
7200
7381
  /**
7201
7382
  * Error codes emitted by the lexer stage.
7202
7383
  *
@@ -7317,7 +7498,7 @@ function lineChar(text, offset) {
7317
7498
  };
7318
7499
  }
7319
7500
  //#endregion
7320
- //#region ../../node_modules/.pnpm/@effected+yaml@0.5.1_effect@4.0.0-beta.101/node_modules/@effected/yaml/internal/composer/anchors.js
7501
+ //#region ../../node_modules/.pnpm/@effected+yaml@0.6.0_effect@4.0.0-beta.101/node_modules/@effected/yaml/internal/composer/anchors.js
7321
7502
  /**
7322
7503
  * Check if a pending anchor is being applied to an alias node (invalid in YAML 1.2 §3.2.2).
7323
7504
  * Aliases represent references to existing anchored nodes and cannot have their own anchors.
@@ -7410,7 +7591,7 @@ function collectAnchors(node, anchors) {
7410
7591
  }
7411
7592
  }
7412
7593
  //#endregion
7413
- //#region ../../node_modules/.pnpm/@effected+yaml@0.5.1_effect@4.0.0-beta.101/node_modules/@effected/yaml/internal/lexer.js
7594
+ //#region ../../node_modules/.pnpm/@effected+yaml@0.6.0_effect@4.0.0-beta.101/node_modules/@effected/yaml/internal/lexer.js
7414
7595
  /**
7415
7596
  * Create a new YAML scanner for the given source text.
7416
7597
  *
@@ -8367,7 +8548,7 @@ function lexAll(text) {
8367
8548
  return tokens;
8368
8549
  }
8369
8550
  //#endregion
8370
- //#region ../../node_modules/.pnpm/@effected+yaml@0.5.1_effect@4.0.0-beta.101/node_modules/@effected/yaml/internal/cst-parser.js
8551
+ //#region ../../node_modules/.pnpm/@effected+yaml@0.6.0_effect@4.0.0-beta.101/node_modules/@effected/yaml/internal/cst-parser.js
8371
8552
  /**
8372
8553
  * Hardening: cap CST nesting so hostile inputs cannot overflow the stack
8373
8554
  * while the tree is being BUILT. Set slightly above the composer's
@@ -9079,7 +9260,7 @@ function parseCSTAll(text) {
9079
9260
  return parseDocuments(lexAll(text), text);
9080
9261
  }
9081
9262
  //#endregion
9082
- //#region ../../node_modules/.pnpm/@effected+yaml@0.5.1_effect@4.0.0-beta.101/node_modules/@effected/yaml/internal/composer/state.js
9263
+ //#region ../../node_modules/.pnpm/@effected+yaml@0.6.0_effect@4.0.0-beta.101/node_modules/@effected/yaml/internal/composer/state.js
9083
9264
  let lineStartsText;
9084
9265
  let lineStartsCache = [];
9085
9266
  function getLineStarts(text) {
@@ -9185,7 +9366,7 @@ function exitNesting(state) {
9185
9366
  state.depth--;
9186
9367
  }
9187
9368
  //#endregion
9188
- //#region ../../node_modules/.pnpm/@effected+yaml@0.5.1_effect@4.0.0-beta.101/node_modules/@effected/yaml/internal/composer/tags.js
9369
+ //#region ../../node_modules/.pnpm/@effected+yaml@0.6.0_effect@4.0.0-beta.101/node_modules/@effected/yaml/internal/composer/tags.js
9189
9370
  /**
9190
9371
  * Resolve a tag shorthand using the document's %TAG directives.
9191
9372
  * For example, with `%TAG !! tag:example.com,2000:app/`, the tag `!!int`
@@ -9271,7 +9452,7 @@ function validateTagHandlesInDocument(docCst, state) {
9271
9452
  }
9272
9453
  }
9273
9454
  //#endregion
9274
- //#region ../../node_modules/.pnpm/@effected+yaml@0.5.1_effect@4.0.0-beta.101/node_modules/@effected/yaml/internal/composer/scalars.js
9455
+ //#region ../../node_modules/.pnpm/@effected+yaml@0.6.0_effect@4.0.0-beta.101/node_modules/@effected/yaml/internal/composer/scalars.js
9275
9456
  const NULL_RE$1 = /^(?:null|Null|NULL|~)$/;
9276
9457
  const TRUE_RE$1 = /^(?:true|True|TRUE)$/;
9277
9458
  const FALSE_RE$1 = /^(?:false|False|FALSE)$/;
@@ -10149,7 +10330,7 @@ function shouldPreserveRaw(rawValue, value) {
10149
10330
  return false;
10150
10331
  }
10151
10332
  //#endregion
10152
- //#region ../../node_modules/.pnpm/@effected+yaml@0.5.1_effect@4.0.0-beta.101/node_modules/@effected/yaml/internal/composer/block.js
10333
+ //#region ../../node_modules/.pnpm/@effected+yaml@0.6.0_effect@4.0.0-beta.101/node_modules/@effected/yaml/internal/composer/block.js
10153
10334
  /**
10154
10335
  * Compose a block map from its CST children, with an optional external first key.
10155
10336
  *
@@ -11297,7 +11478,7 @@ function composeFlatBlockMap(children, startIdx, parentCst, state, externalFirst
11297
11478
  return map;
11298
11479
  }
11299
11480
  //#endregion
11300
- //#region ../../node_modules/.pnpm/@effected+yaml@0.5.1_effect@4.0.0-beta.101/node_modules/@effected/yaml/internal/composer/flow.js
11481
+ //#region ../../node_modules/.pnpm/@effected+yaml@0.6.0_effect@4.0.0-beta.101/node_modules/@effected/yaml/internal/composer/flow.js
11301
11482
  /**
11302
11483
  * Validate that flow collection entries are separated by commas.
11303
11484
  *
@@ -11689,7 +11870,7 @@ function composeFlowSeqInner(cst, state, meta, parentBlockColumn) {
11689
11870
  return seq;
11690
11871
  }
11691
11872
  //#endregion
11692
- //#region ../../node_modules/.pnpm/@effected+yaml@0.5.1_effect@4.0.0-beta.101/node_modules/@effected/yaml/internal/composer/document.js
11873
+ //#region ../../node_modules/.pnpm/@effected+yaml@0.6.0_effect@4.0.0-beta.101/node_modules/@effected/yaml/internal/composer/document.js
11693
11874
  /** The flow-composer dispatch wired into every state this module creates. */
11694
11875
  const FLOW = {
11695
11876
  composeFlowMap,
@@ -12355,7 +12536,7 @@ function composeAllDocuments(text, options) {
12355
12536
  };
12356
12537
  }
12357
12538
  //#endregion
12358
- //#region ../../node_modules/.pnpm/@effected+yaml@0.5.1_effect@4.0.0-beta.101/node_modules/@effected/yaml/internal/fold.js
12539
+ //#region ../../node_modules/.pnpm/@effected+yaml@0.6.0_effect@4.0.0-beta.101/node_modules/@effected/yaml/internal/fold.js
12359
12540
  /**
12360
12541
  * Column-based line folding for a single logical scalar line (YAML 1.2 flow
12361
12542
  * folding, §7.3 / §8.2.1). Breaks the content at "safe" single-space
@@ -12591,7 +12772,7 @@ function renderBlockFolded(s, indent) {
12591
12772
  return `>${indentIndicator}${chomp}\n${outputLines.join("\n")}`;
12592
12773
  }
12593
12774
  //#endregion
12594
- //#region ../../node_modules/.pnpm/@effected+yaml@0.5.1_effect@4.0.0-beta.101/node_modules/@effected/yaml/internal/stringifier.js
12775
+ //#region ../../node_modules/.pnpm/@effected+yaml@0.6.0_effect@4.0.0-beta.101/node_modules/@effected/yaml/internal/stringifier.js
12595
12776
  /**
12596
12777
  * Thrown by the stringifier on its failure paths (circular references). The
12597
12778
  * facade catches this and materializes the public stringify error.
@@ -13540,7 +13721,7 @@ function deepEqualValues(a, b) {
13540
13721
  return false;
13541
13722
  }
13542
13723
  //#endregion
13543
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.1.10_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__@effected+npm@0_baf93f2c33d0504f713f685ac5710e50/node_modules/@effected/lockfiles/internal/documents.js
13724
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.2.1_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__@effected+npm@0._44d8f67a8ab767df898f59f0e01343be/node_modules/@effected/lockfiles/internal/documents.js
13544
13725
  /**
13545
13726
  * An empty YAML document composes to `null` (`Yaml.parseAll("")` is `[null]`,
13546
13727
  * and the trailing document of an env-only `pnpm-lock.yaml` is `null` too).
@@ -13610,7 +13791,7 @@ const selectSoleDocument = (content) => effect.Effect.gen(function* () {
13610
13791
  };
13611
13792
  });
13612
13793
  //#endregion
13613
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.1.10_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__@effected+npm@0_baf93f2c33d0504f713f685ac5710e50/node_modules/@effected/lockfiles/internal/pnpm.js
13794
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.2.1_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__@effected+npm@0._44d8f67a8ab767df898f59f0e01343be/node_modules/@effected/lockfiles/internal/pnpm.js
13614
13795
  const PnpmImporterDeps = effect.Schema.optionalKey(effect.Schema.Record(effect.Schema.String, effect.Schema.Struct({
13615
13796
  specifier: effect.Schema.String,
13616
13797
  version: effect.Schema.String
@@ -13707,8 +13888,7 @@ const toFields$1 = (raw) => effect.Effect.gen(function* () {
13707
13888
  }));
13708
13889
  }
13709
13890
  if (raw.packages) for (const [key, pkg] of Object.entries(raw.packages)) {
13710
- const parenIndex = key.indexOf("(");
13711
- const bare = parenIndex === -1 ? key : key.slice(0, parenIndex);
13891
+ const { plain: bare } = splitPeerSuffix(key);
13712
13892
  const atIndex = bare.lastIndexOf("@");
13713
13893
  if (atIndex <= 0) continue;
13714
13894
  const name = bare.slice(0, atIndex);
@@ -13736,7 +13916,7 @@ const toFields$1 = (raw) => effect.Effect.gen(function* () {
13736
13916
  };
13737
13917
  });
13738
13918
  //#endregion
13739
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.1.10_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__@effected+npm@0_baf93f2c33d0504f713f685ac5710e50/node_modules/@effected/lockfiles/internal/yarn.js
13919
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.2.1_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__@effected+npm@0._44d8f67a8ab767df898f59f0e01343be/node_modules/@effected/lockfiles/internal/yarn.js
13740
13920
  const YarnLockfileRaw = effect.Schema.Record(effect.Schema.String, effect.Schema.Unknown);
13741
13921
  const DepRecord = effect.Schema.optionalKey(effect.Schema.Record(effect.Schema.String, effect.Schema.String));
13742
13922
  const YarnEntry = effect.Schema.Struct({
@@ -13859,7 +14039,7 @@ const cleanYarnDeps = (deps) => {
13859
14039
  return Object.fromEntries(Object.entries(deps).map(([name, value]) => [name, value.startsWith("npm:") ? value.slice(4) : value]));
13860
14040
  };
13861
14041
  //#endregion
13862
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.1.10_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__@effected+npm@0_baf93f2c33d0504f713f685ac5710e50/node_modules/@effected/lockfiles/Lockfile.js
14042
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.2.1_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__@effected+npm@0._44d8f67a8ab767df898f59f0e01343be/node_modules/@effected/lockfiles/Lockfile.js
13863
14043
  const EMPTY_IMPORTERS = [];
13864
14044
  /**
13865
14045
  * Failure of `Lockfile.parse`: the given content is not a valid lockfile of
@@ -14103,7 +14283,7 @@ var Lockfile = class Lockfile extends effect.Schema.Class("Lockfile")({
14103
14283
  }
14104
14284
  };
14105
14285
  //#endregion
14106
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.1.10_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__@effected+npm@0_baf93f2c33d0504f713f685ac5710e50/node_modules/@effected/lockfiles/LockfileIntegrity.js
14286
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.2.1_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__@effected+npm@0._44d8f67a8ab767df898f59f0e01343be/node_modules/@effected/lockfiles/LockfileIntegrity.js
14107
14287
  /**
14108
14288
  * The minimal manifest shape {@link LockfileIntegrity.compare} checks a
14109
14289
  * lockfile against: a package name plus the four optional dependency maps.
@@ -14219,7 +14399,7 @@ var LockfileIntegrity = class LockfileIntegrity extends effect.Schema.Class("Loc
14219
14399
  }
14220
14400
  };
14221
14401
  //#endregion
14222
- //#region ../../node_modules/.pnpm/@effected+package-json@0.5.1_effect@4.0.0-beta.101/node_modules/@effected/package-json/Dependency.js
14402
+ //#region ../../node_modules/.pnpm/@effected+package-json@0.6.0_effect@4.0.0-beta.101/node_modules/@effected/package-json/Dependency.js
14223
14403
  /**
14224
14404
  * A resolved dependency entry pairing a package name with its version
14225
14405
  * specifier and the `kind` of map it came from (`@effected/npm`'s
@@ -14283,7 +14463,7 @@ var Dependency = class extends effect.Schema.Class("Dependency")({
14283
14463
  }
14284
14464
  };
14285
14465
  //#endregion
14286
- //#region ../../node_modules/.pnpm/@effected+package-json@0.5.1_effect@4.0.0-beta.101/node_modules/@effected/package-json/DevEngines.js
14466
+ //#region ../../node_modules/.pnpm/@effected+package-json@0.6.0_effect@4.0.0-beta.101/node_modules/@effected/package-json/DevEngines.js
14287
14467
  /**
14288
14468
  * A single `devEngines` constraint with a name and optional `version` / `onFail`.
14289
14469
  *
@@ -15838,7 +16018,7 @@ effect.Schema.String.pipe(effect.Schema.decodeTo(SpdxExpressionUnion, effect.Sch
15838
16018
  encode: (expression) => effect.Effect.succeed(serialize$1(expression))
15839
16019
  })));
15840
16020
  //#endregion
15841
- //#region ../../node_modules/.pnpm/@effected+package-json@0.5.1_effect@4.0.0-beta.101/node_modules/@effected/package-json/License.js
16021
+ //#region ../../node_modules/.pnpm/@effected+package-json@0.6.0_effect@4.0.0-beta.101/node_modules/@effected/package-json/License.js
15842
16022
  /**
15843
16023
  * Indicates that a string is not a valid SPDX license identifier or expression.
15844
16024
  *
@@ -15873,7 +16053,7 @@ const isValidSpdx = (value) => {
15873
16053
  */
15874
16054
  const SpdxLicense = effect.Schema.String.pipe(effect.Schema.check(effect.Schema.makeFilter((value) => isValidSpdx(value) ? void 0 : "Expected a valid SPDX license expression")), effect.Schema.brand("SpdxLicense"));
15875
16055
  //#endregion
15876
- //#region ../../node_modules/.pnpm/@effected+package-json@0.5.1_effect@4.0.0-beta.101/node_modules/@effected/package-json/PackageManager.js
16056
+ //#region ../../node_modules/.pnpm/@effected+package-json@0.6.0_effect@4.0.0-beta.101/node_modules/@effected/package-json/PackageManager.js
15877
16057
  const PACKAGE_MANAGER_RE = /^([a-z]+)@(\d+\.\d+\.\d+(?:-[a-zA-Z0-9._-]+)?)(?:\+(.+))?$/;
15878
16058
  /**
15879
16059
  * The `packageManager` field only ever carries corepack's `<algo>.<hex>`
@@ -15931,7 +16111,7 @@ var PackageManager = class PackageManager extends effect.Schema.Class("PackageMa
15931
16111
  }
15932
16112
  };
15933
16113
  //#endregion
15934
- //#region ../../node_modules/.pnpm/@effected+package-json@0.5.1_effect@4.0.0-beta.101/node_modules/@effected/package-json/PackageName.js
16114
+ //#region ../../node_modules/.pnpm/@effected+package-json@0.6.0_effect@4.0.0-beta.101/node_modules/@effected/package-json/PackageName.js
15935
16115
  /**
15936
16116
  * Indicates that a string could not be used as a valid npm package name.
15937
16117
  *
@@ -15989,7 +16169,7 @@ const PackageName = Object.assign(effect.Schema.Union([ScopedPackageName, Unscop
15989
16169
  isScoped
15990
16170
  });
15991
16171
  //#endregion
15992
- //#region ../../node_modules/.pnpm/@effected+package-json@0.5.1_effect@4.0.0-beta.101/node_modules/@effected/package-json/Person.js
16172
+ //#region ../../node_modules/.pnpm/@effected+package-json@0.6.0_effect@4.0.0-beta.101/node_modules/@effected/package-json/Person.js
15993
16173
  const parsePersonString = (input) => {
15994
16174
  const emailMatch = input.match(/<([^>]+)>/);
15995
16175
  const urlMatch = input.match(/\(([^)]+)\)/);
@@ -16020,10 +16200,11 @@ const KNOWN_KEYS = /* @__PURE__ */ new Set([
16020
16200
  "url"
16021
16201
  ]);
16022
16202
  const sameRest = (a, b) => JSON.stringify(a ?? {}) === JSON.stringify(b ?? {});
16203
+ const isShorthandExpressible = (person) => person.rest === void 0 || Object.keys(person.rest).length === 0;
16023
16204
  const isFaithful = (wire, person) => {
16024
16205
  if (typeof wire === "string") {
16025
16206
  const parsed = parsePersonString(wire);
16026
- return parsed.name === person.name && parsed.email === person.email && parsed.url === person.url;
16207
+ return parsed.name === person.name && parsed.email === person.email && parsed.url === person.url && isShorthandExpressible(person);
16027
16208
  }
16028
16209
  const rest = restOf(wire);
16029
16210
  return wire.name === person.name && wire.email === person.email && wire.url === person.url && sameRest(rest, person.rest);
@@ -16112,7 +16293,9 @@ var Person = class Person extends effect.Schema.Class("Person")({
16112
16293
  decode: (input) => typeof input === "string" ? rememberWire(parsePersonString(input), input) : input,
16113
16294
  encode: (person) => {
16114
16295
  const wire = wireForms.get(person);
16115
- return typeof wire === "string" && isFaithful(wire, person) ? wire : person;
16296
+ if (typeof wire !== "string") return person;
16297
+ if (isFaithful(wire, person)) return wire;
16298
+ return isShorthandExpressible(person) ? serializePerson(person) : person;
16116
16299
  }
16117
16300
  })));
16118
16301
  /**
@@ -16132,7 +16315,182 @@ var Person = class Person extends effect.Schema.Class("Person")({
16132
16315
  }
16133
16316
  };
16134
16317
  //#endregion
16135
- //#region ../../node_modules/.pnpm/@effected+package-json@0.5.1_effect@4.0.0-beta.101/node_modules/@effected/package-json/internal/format.js
16318
+ //#region ../../node_modules/.pnpm/@effected+package-json@0.6.0_effect@4.0.0-beta.101/node_modules/@effected/package-json/Repository.js
16319
+ /** The shorthand hosts npm resolves without a scheme. */
16320
+ const SHORTHAND_HOSTS = /* @__PURE__ */ new Map([
16321
+ ["github", "https://github.com"],
16322
+ ["gitlab", "https://gitlab.com"],
16323
+ ["bitbucket", "https://bitbucket.org"]
16324
+ ]);
16325
+ /** `owner/name`, the bare GitHub shorthand. Deliberately strict about segment shape. */
16326
+ const BARE_SHORTHAND = /^[\w.-]+\/[\w.-]+$/;
16327
+ /** `github:owner/name`, `gist:id`, … */
16328
+ const PREFIXED_SHORTHAND = /^([a-z]+):(.+)$/;
16329
+ /** The scp-like form git accepts: `git@host:owner/name.git`. */
16330
+ const SCP_LIKE = /^(?:([\w.-]+)@)?([\w.-]+):(.+)$/;
16331
+ const stripGitSuffix = (value) => value.endsWith(".git") ? value.slice(0, -4) : value;
16332
+ /**
16333
+ * The browsable `https://host/path` form of a repository reference, or none
16334
+ * when the value is not one this model recognizes.
16335
+ *
16336
+ * Total by construction: `repository` is caller data, and a value we cannot
16337
+ * interpret is a missing answer rather than a failure.
16338
+ */
16339
+ const browseUrlOf = (raw) => {
16340
+ const url = raw.trim();
16341
+ if (url === "") return effect.Option.none();
16342
+ if (BARE_SHORTHAND.test(url)) return effect.Option.some(`https://github.com/${url}`);
16343
+ const prefixed = PREFIXED_SHORTHAND.exec(url);
16344
+ if (prefixed !== null) {
16345
+ const [, scheme, rest] = prefixed;
16346
+ if (scheme === "gist") return effect.Option.some(`https://gist.github.com/${stripGitSuffix(rest ?? "")}`);
16347
+ const host = SHORTHAND_HOSTS.get(scheme ?? "");
16348
+ if (host !== void 0) return effect.Option.some(`${host}/${stripGitSuffix(rest ?? "")}`);
16349
+ }
16350
+ const withoutGitPlus = url.startsWith("git+") ? url.slice(4) : url;
16351
+ const schemeMatch = /^([a-z][a-z0-9+.-]*):\/\/(.*)$/i.exec(withoutGitPlus);
16352
+ if (schemeMatch !== null) {
16353
+ const withoutCredentials = (schemeMatch[2] ?? "").replace(/^[^/@]+@/, "");
16354
+ return withoutCredentials === "" ? effect.Option.none() : effect.Option.some(`https://${stripGitSuffix(withoutCredentials)}`);
16355
+ }
16356
+ const scp = SCP_LIKE.exec(withoutGitPlus);
16357
+ if (scp !== null) {
16358
+ const [, , host, path] = scp;
16359
+ if (host !== void 0 && path !== void 0 && path !== "") return effect.Option.some(`https://${host}/${stripGitSuffix(path)}`);
16360
+ }
16361
+ return effect.Option.none();
16362
+ };
16363
+ const repositoryWires = /* @__PURE__ */ new WeakMap();
16364
+ const bugsWires = /* @__PURE__ */ new WeakMap();
16365
+ const KNOWN_REPOSITORY_KEYS = /* @__PURE__ */ new Set([
16366
+ "type",
16367
+ "url",
16368
+ "directory"
16369
+ ]);
16370
+ const KNOWN_BUGS_KEYS = /* @__PURE__ */ new Set(["url", "email"]);
16371
+ /**
16372
+ * Where a package's source lives.
16373
+ *
16374
+ * @remarks
16375
+ * `url` is **verbatim** — exactly the string the manifest carried, shorthand
16376
+ * and all. Normalization is offered through {@link Repository.browseUrl} and
16377
+ * {@link Repository.gitUrl}, so reading a manifest never rewrites it and a
16378
+ * caller that wants the original still has it.
16379
+ *
16380
+ * @example
16381
+ * ```ts
16382
+ * // "effected/kit" → https://github.com/effected/kit
16383
+ * // "git@github.com:effected/kit.git" → https://github.com/effected/kit
16384
+ * ```
16385
+ *
16386
+ * @public
16387
+ */
16388
+ var Repository = class Repository extends effect.Schema.Class("Repository")({
16389
+ /** The `type` field, when the object form carried one (`"git"`, …). */
16390
+ type: effect.Schema.optionalKey(effect.Schema.String),
16391
+ /** The reference exactly as written: a shorthand, a git URL, or an https URL. */
16392
+ url: effect.Schema.String,
16393
+ /** The subdirectory within the repository, for a monorepo member. */
16394
+ directory: effect.Schema.optionalKey(effect.Schema.String),
16395
+ /** Keys outside the documented set, preserved so encoding does not drop them. */
16396
+ rest: effect.Schema.optionalKey(effect.Schema.Record(effect.Schema.String, effect.Schema.Unknown))
16397
+ }) {
16398
+ /**
16399
+ * The browsable `https://` URL, or `Option.none()` when `url` is not a form
16400
+ * this model recognizes.
16401
+ */
16402
+ get browseUrl() {
16403
+ return browseUrlOf(this.url);
16404
+ }
16405
+ /** The canonical https clone URL, or none when it cannot be derived. */
16406
+ get gitUrl() {
16407
+ return effect.Option.map(this.browseUrl, (url) => `${url}.git`);
16408
+ }
16409
+ /**
16410
+ * The `repository` field: the shorthand string or the object form, always
16411
+ * decoded to a {@link Repository}, and always re-encoded in the form it was
16412
+ * read from.
16413
+ */
16414
+ static FromValue = effect.Schema.Union([effect.Schema.Record(effect.Schema.String, effect.Schema.Unknown), effect.Schema.String]).pipe(effect.Schema.decodeTo(effect.Schema.instanceOf(Repository), effect.SchemaTransformation.transform({
16415
+ decode: (input) => {
16416
+ if (typeof input === "string") {
16417
+ const repository = Repository.make({ url: input });
16418
+ repositoryWires.set(repository, input);
16419
+ return repository;
16420
+ }
16421
+ const rest = {};
16422
+ for (const [key, value] of Object.entries(input)) if (!KNOWN_REPOSITORY_KEYS.has(key)) rest[key] = value;
16423
+ const repository = Repository.make({
16424
+ url: typeof input.url === "string" ? input.url : "",
16425
+ ...typeof input.type === "string" && { type: input.type },
16426
+ ...typeof input.directory === "string" && { directory: input.directory },
16427
+ ...Object.keys(rest).length > 0 && { rest }
16428
+ });
16429
+ repositoryWires.set(repository, input);
16430
+ return repository;
16431
+ },
16432
+ encode: (repository) => {
16433
+ const wire = repositoryWires.get(repository);
16434
+ if (typeof wire === "string" && wire === repository.url) return wire;
16435
+ if (wire !== void 0 && typeof wire !== "string") return wire;
16436
+ return {
16437
+ ...repository.type !== void 0 && { type: repository.type },
16438
+ url: repository.url,
16439
+ ...repository.directory !== void 0 && { directory: repository.directory },
16440
+ ...repository.rest
16441
+ };
16442
+ }
16443
+ })));
16444
+ };
16445
+ /**
16446
+ * Where to report problems with a package.
16447
+ *
16448
+ * @remarks
16449
+ * npm permits a bare URL string, or an object with `url`, `email`, or both —
16450
+ * an email-only entry is legal, which is why `url` is optional.
16451
+ *
16452
+ * @public
16453
+ */
16454
+ var Bugs = class Bugs extends effect.Schema.Class("Bugs")({
16455
+ /** The issue-tracker URL. */
16456
+ url: effect.Schema.optionalKey(effect.Schema.String),
16457
+ /** The address to mail instead of, or alongside, filing an issue. */
16458
+ email: effect.Schema.optionalKey(effect.Schema.String),
16459
+ /** Keys outside the documented set, preserved so encoding does not drop them. */
16460
+ rest: effect.Schema.optionalKey(effect.Schema.Record(effect.Schema.String, effect.Schema.Unknown))
16461
+ }) {
16462
+ /** The `bugs` field: a URL string or the object form. */
16463
+ static FromValue = effect.Schema.Union([effect.Schema.Record(effect.Schema.String, effect.Schema.Unknown), effect.Schema.String]).pipe(effect.Schema.decodeTo(effect.Schema.instanceOf(Bugs), effect.SchemaTransformation.transform({
16464
+ decode: (input) => {
16465
+ if (typeof input === "string") {
16466
+ const bugs = Bugs.make({ url: input });
16467
+ bugsWires.set(bugs, input);
16468
+ return bugs;
16469
+ }
16470
+ const rest = {};
16471
+ for (const [key, value] of Object.entries(input)) if (!KNOWN_BUGS_KEYS.has(key)) rest[key] = value;
16472
+ const bugs = Bugs.make({
16473
+ ...typeof input.url === "string" && { url: input.url },
16474
+ ...typeof input.email === "string" && { email: input.email },
16475
+ ...Object.keys(rest).length > 0 && { rest }
16476
+ });
16477
+ bugsWires.set(bugs, input);
16478
+ return bugs;
16479
+ },
16480
+ encode: (bugs) => {
16481
+ const wire = bugsWires.get(bugs);
16482
+ if (typeof wire === "string" && wire === bugs.url && bugs.email === void 0) return wire;
16483
+ if (wire !== void 0 && typeof wire !== "string") return wire;
16484
+ return {
16485
+ ...bugs.url !== void 0 && { url: bugs.url },
16486
+ ...bugs.email !== void 0 && { email: bugs.email },
16487
+ ...bugs.rest
16488
+ };
16489
+ }
16490
+ })));
16491
+ };
16492
+ //#endregion
16493
+ //#region ../../node_modules/.pnpm/@effected+package-json@0.6.0_effect@4.0.0-beta.101/node_modules/@effected/package-json/internal/format.js
16136
16494
  const KEY_INDEX = new Map([
16137
16495
  "$schema",
16138
16496
  "name",
@@ -16355,7 +16713,7 @@ const renderJson = (raw, options) => {
16355
16713
  return options.newline ? `${json}\n` : json;
16356
16714
  };
16357
16715
  //#endregion
16358
- //#region ../../node_modules/.pnpm/@effected+package-json@0.5.1_effect@4.0.0-beta.101/node_modules/@effected/package-json/Package.js
16716
+ //#region ../../node_modules/.pnpm/@effected+package-json@0.6.0_effect@4.0.0-beta.101/node_modules/@effected/package-json/Package.js
16359
16717
  const toHashMap = effect.SchemaTransformation.transform({
16360
16718
  decode: (record) => effect.HashMap.fromIterable(Object.entries(record)),
16361
16719
  encode: (map) => Object.fromEntries(effect.HashMap.toEntries(map))
@@ -16405,14 +16763,7 @@ const PublishConfigField = effect.Schema.Record(effect.Schema.String, effect.Sch
16405
16763
  * @public
16406
16764
  */
16407
16765
  const PeerDependenciesMetaField = effect.Schema.Record(effect.Schema.String, effect.Schema.Struct({ optional: effect.Schema.optionalKey(effect.Schema.Boolean) }));
16408
- /**
16409
- * The `repository` field: a shorthand string or an object (with `type` / `url` /
16410
- * `directory` and any extensions preserved). Not meant to be referenced
16411
- * directly.
16412
- *
16413
- * @public
16414
- */
16415
- const RepositoryField = effect.Schema.Union([effect.Schema.String, effect.Schema.Record(effect.Schema.String, effect.Schema.Unknown)]);
16766
+ effect.Schema.Union([effect.Schema.String, effect.Schema.Record(effect.Schema.String, effect.Schema.Unknown)]);
16416
16767
  /**
16417
16768
  * Indicates that a JSON value could not be decoded into a valid {@link Package}.
16418
16769
  *
@@ -16487,7 +16838,11 @@ var Package = class Package extends effect.Schema.Class("Package")({
16487
16838
  license: effect.Schema.optionalKey(SpdxLicense),
16488
16839
  author: effect.Schema.optionalKey(Person.FromValue),
16489
16840
  contributors: effect.Schema.optionalKey(effect.Schema.Array(Person.FromValue)),
16490
- repository: effect.Schema.optionalKey(RepositoryField),
16841
+ maintainers: effect.Schema.optionalKey(effect.Schema.Array(Person.FromValue)),
16842
+ keywords: effect.Schema.optionalKey(effect.Schema.Array(effect.Schema.String)),
16843
+ repository: effect.Schema.optionalKey(Repository.FromValue),
16844
+ bugs: effect.Schema.optionalKey(Bugs.FromValue),
16845
+ homepage: effect.Schema.optionalKey(effect.Schema.String),
16491
16846
  dependencies: DependencyMapField,
16492
16847
  devDependencies: DependencyMapField,
16493
16848
  peerDependencies: DependencyMapField,
@@ -16673,7 +17028,7 @@ var Package = class Package extends effect.Schema.Class("Package")({
16673
17028
  }
16674
17029
  };
16675
17030
  //#endregion
16676
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.7.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspacePackage.js
17031
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspacePackage.js
16677
17032
  const EMPTY$1 = Object.freeze(Object.create(null));
16678
17033
  const EMPTY_MANIFEST = Object.freeze(Object.create(null));
16679
17034
  /**
@@ -16952,7 +17307,7 @@ var WorkspacePackage = class WorkspacePackage extends effect.Schema.Class("Works
16952
17307
  }
16953
17308
  };
16954
17309
  //#endregion
16955
- //#region ../../node_modules/.pnpm/@effected+walker@0.3.2_@effected+glob@0.2.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/walker/Descend.js
17310
+ //#region ../../node_modules/.pnpm/@effected+walker@0.3.3_@effected+glob@0.2.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/walker/Descend.js
16956
17311
  /**
16957
17312
  * Typed failure raised by {@link descend}: a directory mid-walk was unreadable
16958
17313
  * (under `onUnreadable: "fail"`), or the walk descended past `maxDepth`. Depth
@@ -17087,7 +17442,7 @@ const descend = effect.Effect.fn("Walker.descend")(function* (pattern, options)
17087
17442
  return results;
17088
17443
  });
17089
17444
  //#endregion
17090
- //#region ../../node_modules/.pnpm/@effected+walker@0.3.2_@effected+glob@0.2.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/walker/Expand.js
17445
+ //#region ../../node_modules/.pnpm/@effected+walker@0.3.3_@effected+glob@0.2.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/walker/Expand.js
17091
17446
  /**
17092
17447
  * Typed failure raised by {@link compileAndExpand}: the single error the
17093
17448
  * compile+expand recipe fails with, so a caller catches one tag rather than
@@ -17177,31 +17532,7 @@ const compileAndExpand = effect.Effect.fn("Walker.compileAndExpand")(function* (
17177
17532
  })));
17178
17533
  });
17179
17534
  //#endregion
17180
- //#region ../../node_modules/.pnpm/@effected+walker@0.3.2_@effected+glob@0.2.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/walker/Walker.js
17181
- /**
17182
- * Ascend from `start` toward the filesystem root, yielding each directory,
17183
- * nearest first.
17184
- *
17185
- * @remarks
17186
- * Lexical, not physical: `Path.dirname` does not resolve symlinks, so ascending
17187
- * out of a symlinked directory follows the path you were given rather than the
17188
- * real filesystem parent. That is deliberate — config discovery wants the file
17189
- * nearest the path the user named.
17190
- *
17191
- * Bounded twice over: `dirname` is a fixpoint at the root, and `maxDepth` guards
17192
- * a pathological `Path` implementation that never reaches one.
17193
- *
17194
- * `stopAt` is compared in normalized form — see {@link AscendOptions.stopAt}.
17195
- * Raw string equality made the ceiling fail OPEN: an unnormalized ceiling
17196
- * matched nothing and the ascent ran silently to the filesystem root, which is
17197
- * the unbounded walk the option exists to prevent, with no error to notice it
17198
- * by. A relative ceiling **dies** for the same reason — resolving one against
17199
- * `process.cwd()` would reintroduce the silent-wrong-walk failure through a
17200
- * different door. See {@link AscendOptions.stopAt} for why that is a defect
17201
- * rather than a typed error; the error channel stays `never`.
17202
- *
17203
- * @public
17204
- */
17535
+ //#region ../../node_modules/.pnpm/@effected+walker@0.3.3_@effected+glob@0.2.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/walker/Walker.js
17205
17536
  const ascend = (start, options) => effect.Effect.gen(function* () {
17206
17537
  const path = yield* effect.Path.Path;
17207
17538
  const maxDepth = options?.maxDepth ?? 256;
@@ -17219,66 +17550,83 @@ const ascend = (start, options) => effect.Effect.gen(function* () {
17219
17550
  }
17220
17551
  return dirs;
17221
17552
  });
17222
- /**
17223
- * The first candidate whose `predicate` reports true, or `Option.none()`.
17224
- *
17225
- * @remarks
17226
- * Each predicate is absorbed **individually**: a failure on one candidate is
17227
- * treated as "this candidate did not match" and the scan continues. One
17228
- * unreadable ancestor must never abort the walk, or a permission error deep in
17229
- * the tree would hide a valid root above it. Not-found and cannot-look are
17230
- * therefore indistinguishable to the caller; discovery is best-effort.
17231
- *
17232
- * `Effect.catch` catches failures, **not defects**. A predicate that throws is
17233
- * programmer error and surfaces as a defect. Do not change this to
17234
- * `Effect.catchCause` — the distinction is load-bearing.
17235
- *
17236
- * @public
17237
- */
17238
17553
  const firstMatch = (candidates, predicate) => effect.Effect.gen(function* () {
17239
17554
  for (const candidate of candidates) if (yield* effect.Effect.catch(predicate(candidate), () => effect.Effect.succeed(false))) return effect.Option.some(candidate);
17240
17555
  return effect.Option.none();
17241
17556
  });
17242
- /**
17243
- * The first existing path among the candidates `candidatesFor` produces for each
17244
- * directory in `dirs`, scanned in order. Nearer directories win.
17245
- *
17246
- * @remarks
17247
- * Candidates materialize up front, bounded by `dirs.length × candidatesFor`'s
17248
- * output — a few hundred strings under the default `maxDepth`.
17249
- *
17250
- * @public
17251
- */
17252
17557
  const findUpward = (dirs, candidatesFor) => effect.Effect.gen(function* () {
17253
17558
  const fs = yield* effect.FileSystem.FileSystem;
17254
17559
  const candidates = [];
17255
17560
  for (const dir of dirs) candidates.push(...candidatesFor(dir));
17256
17561
  return yield* firstMatch(candidates, (candidate) => fs.exists(candidate));
17257
17562
  });
17258
- /**
17259
- * The first directory in `dirs` that `isRoot` accepts.
17260
- *
17261
- * @remarks
17262
- * `firstMatch` over the directories themselves — the candidate expansion is the
17263
- * identity. `isRoot` is a caller-supplied marker test (a `.git` entry, a
17264
- * `pnpm-workspace.yaml`), and its failures are absorbed per directory.
17265
- *
17266
- * @public
17267
- */
17268
17563
  const findRoot$1 = (dirs, isRoot) => firstMatch(dirs, isRoot);
17269
17564
  /**
17270
17565
  * Upward path traversal primitives.
17271
17566
  *
17272
17567
  * @public
17273
17568
  */
17274
- const Walker$1 = {
17275
- ascend,
17276
- firstMatch,
17277
- findUpward,
17278
- findRoot: findRoot$1
17569
+ var Walker$1 = class {
17570
+ constructor() {}
17571
+ /**
17572
+ * Ascend from `start` toward the filesystem root, yielding each directory,
17573
+ * nearest first.
17574
+ *
17575
+ * @remarks
17576
+ * Lexical, not physical: `Path.dirname` does not resolve symlinks, so ascending
17577
+ * out of a symlinked directory follows the path you were given rather than the
17578
+ * real filesystem parent. That is deliberate — config discovery wants the file
17579
+ * nearest the path the user named.
17580
+ *
17581
+ * Bounded twice over: `dirname` is a fixpoint at the root, and `maxDepth` guards
17582
+ * a pathological `Path` implementation that never reaches one.
17583
+ *
17584
+ * `stopAt` is compared in normalized form — see {@link AscendOptions.stopAt}.
17585
+ * Raw string equality made the ceiling fail OPEN: an unnormalized ceiling
17586
+ * matched nothing and the ascent ran silently to the filesystem root, which is
17587
+ * the unbounded walk the option exists to prevent, with no error to notice it
17588
+ * by. A relative ceiling **dies** for the same reason — resolving one against
17589
+ * `process.cwd()` would reintroduce the silent-wrong-walk failure through a
17590
+ * different door. See {@link AscendOptions.stopAt} for why that is a defect
17591
+ * rather than a typed error; the error channel stays `never`.
17592
+ */
17593
+ static ascend = ascend;
17594
+ /**
17595
+ * The first candidate whose `predicate` reports true, or `Option.none()`.
17596
+ *
17597
+ * @remarks
17598
+ * Each predicate is absorbed **individually**: a failure on one candidate is
17599
+ * treated as "this candidate did not match" and the scan continues. One
17600
+ * unreadable ancestor must never abort the walk, or a permission error deep in
17601
+ * the tree would hide a valid root above it. Not-found and cannot-look are
17602
+ * therefore indistinguishable to the caller; discovery is best-effort.
17603
+ *
17604
+ * `Effect.catch` catches failures, **not defects**. A predicate that throws is
17605
+ * programmer error and surfaces as a defect. Do not change this to
17606
+ * `Effect.catchCause` — the distinction is load-bearing.
17607
+ */
17608
+ static firstMatch = firstMatch;
17609
+ /**
17610
+ * The first existing path among the candidates `candidatesFor` produces for each
17611
+ * directory in `dirs`, scanned in order. Nearer directories win.
17612
+ *
17613
+ * @remarks
17614
+ * Candidates materialize up front, bounded by `dirs.length × candidatesFor`'s
17615
+ * output — a few hundred strings under the default `maxDepth`.
17616
+ */
17617
+ static findUpward = findUpward;
17618
+ /**
17619
+ * The first directory in `dirs` that `isRoot` accepts.
17620
+ *
17621
+ * @remarks
17622
+ * `firstMatch` over the directories themselves — the candidate expansion is the
17623
+ * identity. `isRoot` is a caller-supplied marker test (a `.git` entry, a
17624
+ * `pnpm-workspace.yaml`), and its failures are absorbed per directory.
17625
+ */
17626
+ static findRoot = findRoot$1;
17279
17627
  };
17280
17628
  //#endregion
17281
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.7.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspaceRoot.js
17629
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspaceRoot.js
17282
17630
  /**
17283
17631
  * The marker filenames {@link WorkspaceRoot} probes for, in priority order.
17284
17632
  *
@@ -17465,7 +17813,7 @@ var WorkspaceRoot = class WorkspaceRoot extends effect.Context.Service()("@effec
17465
17813
  static layerTest = (root) => effect.Layer.effect(WorkspaceRoot, WorkspaceRoot.makeTest(root)).pipe(effect.Layer.provide(effect.Path.layer));
17466
17814
  };
17467
17815
  //#endregion
17468
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.7.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/limits.js
17816
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/limits.js
17469
17817
  /**
17470
17818
  * Hard ceiling on directories the enumerator will visit for one pattern set.
17471
17819
  * Guards the pathological case a depth cap alone does not: a wide, shallow
@@ -17483,7 +17831,7 @@ const MAX_ENUMERATION_ENTRIES = 1e5;
17483
17831
  */
17484
17832
  const PRUNED_DIRECTORIES = /* @__PURE__ */ new Set([".git", "node_modules"]);
17485
17833
  //#endregion
17486
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.7.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/traverse.js
17834
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/traverse.js
17487
17835
  /** Directory names never descended into. */
17488
17836
  const isPruned = (entry) => PRUNED_DIRECTORIES.has(entry);
17489
17837
  /** Join root-relative POSIX segments; `""` is the root itself. */
@@ -17573,7 +17921,7 @@ var Traversal = class {
17573
17921
  }
17574
17922
  };
17575
17923
  //#endregion
17576
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.7.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/enumerate.js
17924
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/enumerate.js
17577
17925
  /** Strip a trailing slash from `GlobPattern.enumerationPrefix` to get a relative directory. */
17578
17926
  const baseOf = (pattern) => pattern.enumerationPrefix.replace(/\/$/, "");
17579
17927
  /**
@@ -17643,7 +17991,7 @@ const enumerate = (root, globs, options) => effect.Effect.gen(function* () {
17643
17991
  return results;
17644
17992
  });
17645
17993
  //#endregion
17646
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.7.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/patterns.js
17994
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/patterns.js
17647
17995
  const stringsOf = (value) => Array.isArray(value) ? value.filter((entry) => typeof entry === "string") : void 0;
17648
17996
  /** The `packages:` list of a `pnpm-workspace.yaml` document. Total on a parsed document. */
17649
17997
  const pnpmPatternsOf = (document) => {
@@ -17700,7 +18048,7 @@ const readPatterns = (root) => effect.Effect.gen(function* () {
17700
18048
  return manifestPatternsOf(manifest);
17701
18049
  });
17702
18050
  //#endregion
17703
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.7.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspaceDiscovery.js
18051
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspaceDiscovery.js
17704
18052
  /**
17705
18053
  * Raised when a workspace member's `package.json` cannot be read, parsed, or
17706
18054
  * used — it is missing, malformed, or lacks a `name` or `version`.
@@ -18134,7 +18482,7 @@ var WorkspaceDiscovery = class WorkspaceDiscovery extends effect.Context.Service
18134
18482
  };
18135
18483
  const isStringRecord$2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value) && Object.values(value).every((entry) => typeof entry === "string");
18136
18484
  //#endregion
18137
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.7.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/DependencyGraph.js
18485
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/DependencyGraph.js
18138
18486
  /**
18139
18487
  * Raised when the workspace dependency graph cannot be topologically ordered
18140
18488
  * because it contains a cycle.
@@ -18369,7 +18717,7 @@ const kahn = (edges) => {
18369
18717
  };
18370
18718
  };
18371
18719
  //#endregion
18372
- //#region ../../node_modules/.pnpm/@effected+git@0.4.2_effect@4.0.0-beta.101/node_modules/@effected/git/GitCommand.js
18720
+ //#region ../../node_modules/.pnpm/@effected+git@0.5.1_effect@4.0.0-beta.101/node_modules/@effected/git/GitCommand.js
18373
18721
  /**
18374
18722
  * Builds a `git` `ChildProcess.StandardCommand` with the argv this package
18375
18723
  * classifies against.
@@ -18392,25 +18740,7 @@ const git = (args) => effect_unstable_process.ChildProcess.make("git", args, {
18392
18740
  env: { LC_ALL: "C" },
18393
18741
  extendEnv: true
18394
18742
  });
18395
- /**
18396
- * `git show <ref>:<path>` — the contents of `path` as it existed at `ref`,
18397
- * without checking anything out.
18398
- *
18399
- * @public
18400
- */
18401
18743
  const show = (ref, path) => git(["show", `${ref}:${path}`]);
18402
- /**
18403
- * `git ls-tree -r -z <ref> [-- <pathspec>...]` — every path in the tree at
18404
- * `ref`, recursively, NUL-terminated, optionally scoped to `pathspec`.
18405
- *
18406
- * @remarks
18407
- * `-z` is load-bearing: git paths may themselves contain newlines, so the
18408
- * caller must split on `"\0"`, never on `"\n"`. When `pathspec` is provided,
18409
- * a literal `--` separator is inserted before the pathspec entries to prevent
18410
- * git from interpreting pathspec values as options.
18411
- *
18412
- * @public
18413
- */
18414
18744
  const lsTree = (ref, pathspec = []) => git([
18415
18745
  "ls-tree",
18416
18746
  "-r",
@@ -18418,48 +18748,16 @@ const lsTree = (ref, pathspec = []) => git([
18418
18748
  ref,
18419
18749
  ...pathspec.length > 0 ? ["--", ...pathspec] : []
18420
18750
  ]);
18421
- /**
18422
- * `git cat-file -e <ref>` — checks whether `ref` resolves to an existing
18423
- * object, without printing it. A non-zero exit means the ref does not exist.
18424
- *
18425
- * @public
18426
- */
18427
18751
  const refExists = (ref) => git([
18428
18752
  "cat-file",
18429
18753
  "-e",
18430
18754
  ref
18431
18755
  ]);
18432
- /**
18433
- * `git merge-base <a> <b>` — the best common ancestor commit of `a` and `b`.
18434
- *
18435
- * @public
18436
- */
18437
18756
  const mergeBase = (a, b) => git([
18438
18757
  "merge-base",
18439
18758
  a,
18440
18759
  b
18441
18760
  ]);
18442
- /**
18443
- * `git diff --name-only -z [--relative] <base>...<head>` — the paths that
18444
- * differ between the merge base of `base` and `head`, and `head` itself,
18445
- * NUL-terminated.
18446
- *
18447
- * @remarks
18448
- * `-z` is load-bearing here too, for the same reason as {@link GitCommand.lsTree}: split
18449
- * the output on `"\0"`, never on `"\n"`.
18450
- *
18451
- * The relative flag is **explicit in both branches** — `--relative` when
18452
- * `relative` is true, `--no-relative` when false — never omitted. git honors a
18453
- * configured `diff.relative=true` when no flag is passed, so an omitted flag
18454
- * would silently yield cwd-relative paths on such a machine even for
18455
- * `relative: false`, misaligning with {@link GitCommand.untrackedFiles}'s
18456
- * repo-root base and breaking `Git.workingChanges`' dedup in a nested workspace.
18457
- * `--relative` scopes the report to `cwd` (a workspace nested inside a larger
18458
- * repository); `--no-relative` overrides any `diff.relative` config and reports
18459
- * paths from the repository top-level.
18460
- *
18461
- * @public
18462
- */
18463
18761
  const changedFiles = (base, head, relative = false) => git([
18464
18762
  "diff",
18465
18763
  "--name-only",
@@ -18467,35 +18765,12 @@ const changedFiles = (base, head, relative = false) => git([
18467
18765
  relative ? "--relative" : "--no-relative",
18468
18766
  `${base}...${head}`
18469
18767
  ]);
18470
- /**
18471
- * `git diff --name-only -z (--relative | --no-relative)` — the paths with
18472
- * unstaged working-tree changes (the working tree against the index),
18473
- * NUL-terminated.
18474
- *
18475
- * @remarks
18476
- * `relative` behaves as it does for {@link GitCommand.changedFiles}, including the
18477
- * explicit-flag-in-both-branches rule: `--no-relative` is passed for
18478
- * `relative: false` so a configured `diff.relative=true` cannot silently make the
18479
- * output cwd-relative.
18480
- *
18481
- * @public
18482
- */
18483
18768
  const unstagedChanges = (relative = false) => git([
18484
18769
  "diff",
18485
18770
  "--name-only",
18486
18771
  "-z",
18487
18772
  relative ? "--relative" : "--no-relative"
18488
18773
  ]);
18489
- /**
18490
- * `git diff --name-only -z (--relative | --no-relative) --cached` — the paths
18491
- * staged for the next commit (the index against `HEAD`), NUL-terminated.
18492
- *
18493
- * @remarks
18494
- * `relative` behaves as it does for {@link GitCommand.changedFiles}, including the
18495
- * explicit `--no-relative` on the `relative: false` branch.
18496
- *
18497
- * @public
18498
- */
18499
18774
  const stagedChanges = (relative = false) => git([
18500
18775
  "diff",
18501
18776
  "--name-only",
@@ -18503,19 +18778,6 @@ const stagedChanges = (relative = false) => git([
18503
18778
  relative ? "--relative" : "--no-relative",
18504
18779
  "--cached"
18505
18780
  ]);
18506
- /**
18507
- * `git ls-files --others --exclude-standard -z [--full-name]` — the untracked
18508
- * paths git is not ignoring, NUL-terminated.
18509
- *
18510
- * @remarks
18511
- * `ls-files` reports paths relative to `cwd` by default, matching the
18512
- * `--relative` diffs. When `relative` is `false`, `--full-name` makes it emit
18513
- * repo-root-relative paths instead, so the untracked half shares a base with the
18514
- * un-`--relative` diffs — otherwise `Git.workingChanges`'s union would dedup two
18515
- * spellings of one file from a nested `cwd`.
18516
- *
18517
- * @public
18518
- */
18519
18781
  const untrackedFiles = (relative = false) => git([
18520
18782
  "ls-files",
18521
18783
  "--others",
@@ -18523,35 +18785,16 @@ const untrackedFiles = (relative = false) => git([
18523
18785
  "-z",
18524
18786
  ...relative ? [] : ["--full-name"]
18525
18787
  ]);
18526
- /**
18527
- * `git rev-parse --verify <ref>` — resolves `ref` to its full object id, or
18528
- * fails if `ref` does not resolve.
18529
- *
18530
- * @public
18531
- */
18532
18788
  const revParse = (ref) => git([
18533
18789
  "rev-parse",
18534
18790
  "--verify",
18535
18791
  ref
18536
18792
  ]);
18537
- /**
18538
- * Mutating: `git checkout [--detach] <ref>` — moves the working tree (and, for
18539
- * a branch ref, `HEAD`) to `ref`. When `detach` is true, checks out the ref in
18540
- * detached-HEAD state.
18541
- *
18542
- * @public
18543
- */
18544
18793
  const checkout = (ref, detach = false) => git([
18545
18794
  "checkout",
18546
18795
  ...detach ? ["--detach"] : [],
18547
18796
  ref
18548
18797
  ]);
18549
- /**
18550
- * Mutating: `git fetch [--depth <n>] <remote> [tag] <ref>` — fetches the given
18551
- * ref from a remote, optionally with a depth limit and the `tag` keyword.
18552
- *
18553
- * @public
18554
- */
18555
18798
  const fetch$1 = (remote, ref, depth, tag = false) => git([
18556
18799
  "fetch",
18557
18800
  ...depth !== void 0 ? ["--depth", String(depth)] : [],
@@ -18559,14 +18802,6 @@ const fetch$1 = (remote, ref, depth, tag = false) => git([
18559
18802
  ...tag ? ["tag"] : [],
18560
18803
  ref
18561
18804
  ]);
18562
- /**
18563
- * Mutating: `git submodule update [--init] [--depth <n>] [-- <paths>...]` — updates
18564
- * registered submodules, optionally initializing them, with an optional depth limit,
18565
- * and scoped to specific paths. The literal `--` separator makes the pathspec
18566
- * injection-safe by construction.
18567
- *
18568
- * @public
18569
- */
18570
18805
  const submoduleUpdate = (init = false, depth, paths = []) => git([
18571
18806
  "submodule",
18572
18807
  "update",
@@ -18574,13 +18809,6 @@ const submoduleUpdate = (init = false, depth, paths = []) => git([
18574
18809
  ...depth !== void 0 ? ["--depth", String(depth)] : [],
18575
18810
  ...paths.length > 0 ? ["--", ...paths] : []
18576
18811
  ]);
18577
- /**
18578
- * Mutating: `git submodule add [--depth <n>] -- <url> <path>` — registers and
18579
- * initializes a new submodule. The literal `--` separator makes the url and path
18580
- * injection-safe by construction.
18581
- *
18582
- * @public
18583
- */
18584
18812
  const submoduleAdd = (url, path, depth) => git([
18585
18813
  "submodule",
18586
18814
  "add",
@@ -18589,57 +18817,23 @@ const submoduleAdd = (url, path, depth) => git([
18589
18817
  url,
18590
18818
  path
18591
18819
  ]);
18592
- /**
18593
- * Mutating: `git sparse-checkout set (--cone | --no-cone) <patterns...>` — configures
18594
- * which paths are checked out in a sparse repository. The cone flag is explicit in both
18595
- * branches — `--cone` when `cone` is true, `--no-cone` when false — to prevent git's
18596
- * default from silently changing the behavior.
18597
- *
18598
- * @public
18599
- */
18600
18820
  const sparseCheckoutSet = (patterns, cone) => git([
18601
18821
  "sparse-checkout",
18602
18822
  "set",
18603
18823
  cone ? "--cone" : "--no-cone",
18604
18824
  ...patterns
18605
18825
  ]);
18606
- /**
18607
- * Mutating: `git config [-f <file>] <key> <value>` — writes a configuration value,
18608
- * optionally into an explicit configuration file (e.g., `.gitmodules`).
18609
- *
18610
- * @public
18611
- */
18612
18826
  const configSet = (key, value, file) => git([
18613
18827
  "config",
18614
18828
  ...file !== void 0 ? ["-f", file] : [],
18615
18829
  key,
18616
18830
  value
18617
18831
  ]);
18618
- /**
18619
- * Mutating: `git add -- <paths...>` — stages the given paths for commit. The literal
18620
- * `--` separator makes the pathspec injection-safe by construction.
18621
- *
18622
- * @public
18623
- */
18624
18832
  const add = (paths) => git([
18625
18833
  "add",
18626
18834
  "--",
18627
18835
  ...paths
18628
18836
  ]);
18629
- /**
18630
- * `git diff --name-status -z (--relative | --no-relative) [<base> | <base>...<head>]`
18631
- * — the changed paths WITH their one-letter status codes, NUL-terminated.
18632
- *
18633
- * @remarks
18634
- * With `head` omitted this is the single-argument diff form: the working tree
18635
- * (staged + unstaged) against `base` — NOT a two-ref range. With `head`
18636
- * present it is the familiar `base...head` merge-base form, matching
18637
- * {@link GitCommand.changedFiles}. `-z` and the explicit relative flag follow
18638
- * the same rules as {@link GitCommand.changedFiles}. In `-z` mode a rename or
18639
- * copy entry is THREE NUL tokens: `R<score>`, the old path, the new path.
18640
- *
18641
- * @public
18642
- */
18643
18837
  const nameStatus = (base, head, relative = false) => git([
18644
18838
  "diff",
18645
18839
  "--name-status",
@@ -18647,103 +18841,34 @@ const nameStatus = (base, head, relative = false) => git([
18647
18841
  relative ? "--relative" : "--no-relative",
18648
18842
  head === void 0 ? base : `${base}...${head}`
18649
18843
  ]);
18650
- /**
18651
- * `git symbolic-ref --quiet --short refs/remotes/<remote>/HEAD` — the name of
18652
- * the default branch on the given remote, or empty string / exit 1 if unset.
18653
- *
18654
- * @remarks
18655
- * `--quiet` suppresses error messages; the exit code alone signals success
18656
- * (0) or "symbolic-ref does not exist" (1). The contract is "does the remote
18657
- * have a HEAD?" — an unset symbolic ref exits 1 silently, which `Git.defaultBranch`
18658
- * degrades to `Option.none()` rather than a typed error. `symbolic-ref` is a
18659
- * purely local ref lookup; it never touches the network.
18660
- *
18661
- * @public
18662
- */
18663
18844
  const defaultBranch = (remote = "origin") => git([
18664
18845
  "symbolic-ref",
18665
18846
  "--quiet",
18666
18847
  "--short",
18667
18848
  `refs/remotes/${remote}/HEAD`
18668
18849
  ]);
18669
- /**
18670
- * `git rev-parse --abbrev-ref HEAD` — the name of the branch `HEAD` is
18671
- * pointing to.
18672
- *
18673
- * @remarks
18674
- * Returns `"HEAD"` (detached state), `"<branch>"` (an attached branch), or
18675
- * fails if the repository has no commits.
18676
- *
18677
- * @public
18678
- */
18679
18850
  const currentBranch = () => git([
18680
18851
  "rev-parse",
18681
18852
  "--abbrev-ref",
18682
18853
  "HEAD"
18683
18854
  ]);
18684
- /**
18685
- * `git rev-parse --show-toplevel` — the filesystem path to the root of the
18686
- * enclosing git repository.
18687
- *
18688
- * @public
18689
- */
18690
18855
  const repoRoot = () => git(["rev-parse", "--show-toplevel"]);
18691
- /**
18692
- * `git log -1 --format=%H%x00%G?%x00%B <ref>` — a NUL-separated triple: the
18693
- * full commit hash, the GPG trust level, and the full commit body (message),
18694
- * all untrimmed.
18695
- *
18696
- * @remarks
18697
- * `%H` is the full object id (40-char sha1, or sha256 if configured).
18698
- * `%x00` is a literal NUL byte (the separator). `%G?` is the GPG trust level
18699
- * (`G` = good signature, `B` = bad, `U` = untrusted, `X` = expired, `Y` =
18700
- * expired key, `R` = revoked key, `E` = error, or `N` = not signed).
18701
- * `%B` is the full body, **untrimmed** — it includes leading/trailing
18702
- * whitespace — so the caller must decide whether to trim it. Splits on the
18703
- * two `\x00` bytes to extract all three values.
18704
- *
18705
- * @public
18706
- */
18707
18856
  const commitInfo = (ref = "HEAD") => git([
18708
18857
  "log",
18709
18858
  "-1",
18710
18859
  "--format=%H%x00%G?%x00%B",
18711
18860
  ref
18712
18861
  ]);
18713
- /**
18714
- * `git config --get <key>` — the value of the given git config key, or empty
18715
- * string / exit 1 if unset.
18716
- *
18717
- * @public
18718
- */
18719
18862
  const configGet = (key) => git([
18720
18863
  "config",
18721
18864
  "--get",
18722
18865
  key
18723
18866
  ]);
18724
- /**
18725
- * `git remote get-url <remote>` — the fetch URL of the given remote. A
18726
- * missing remote exits non-zero with a "No such remote" stderr shape, which
18727
- * the `Git` service degrades to `Option.none`, never a typed error.
18728
- *
18729
- * @public
18730
- */
18731
18867
  const remoteUrl = (remote = "origin") => git([
18732
18868
  "remote",
18733
18869
  "get-url",
18734
18870
  remote
18735
18871
  ]);
18736
- /**
18737
- * `git status --porcelain -z` — the porcelain (stable, machine-readable) short
18738
- * status of every modified file in the working tree, NUL-terminated.
18739
- *
18740
- * @remarks
18741
- * `-z` is load-bearing here too, for the same reason as
18742
- * {@link GitCommand.lsTree}: split the output on `"\0"`, never on `"\n"`.
18743
- * Each entry is a pair of status codes followed by a space and the path.
18744
- *
18745
- * @public
18746
- */
18747
18872
  const status = () => git([
18748
18873
  "status",
18749
18874
  "--porcelain",
@@ -18761,34 +18886,210 @@ const status = () => git([
18761
18886
  *
18762
18887
  * @public
18763
18888
  */
18764
- const GitCommand = {
18765
- show,
18766
- lsTree,
18767
- refExists,
18768
- mergeBase,
18769
- changedFiles,
18770
- unstagedChanges,
18771
- stagedChanges,
18772
- untrackedFiles,
18773
- revParse,
18774
- checkout,
18775
- fetch: fetch$1,
18776
- submoduleUpdate,
18777
- submoduleAdd,
18778
- sparseCheckoutSet,
18779
- configSet,
18780
- add,
18781
- nameStatus,
18782
- defaultBranch,
18783
- currentBranch,
18784
- repoRoot,
18785
- commitInfo,
18786
- configGet,
18787
- remoteUrl,
18788
- status
18889
+ var GitCommand = class {
18890
+ constructor() {}
18891
+ /**
18892
+ * `git show <ref>:<path>` — the contents of `path` as it existed at `ref`,
18893
+ * without checking anything out.
18894
+ */
18895
+ static show = show;
18896
+ /**
18897
+ * `git ls-tree -r -z <ref> [-- <pathspec>...]` — every path in the tree at
18898
+ * `ref`, recursively, NUL-terminated, optionally scoped to `pathspec`.
18899
+ *
18900
+ * @remarks
18901
+ * `-z` is load-bearing: git paths may themselves contain newlines, so the
18902
+ * caller must split on `"\0"`, never on `"\n"`. When `pathspec` is provided,
18903
+ * a literal `--` separator is inserted before the pathspec entries to prevent
18904
+ * git from interpreting pathspec values as options.
18905
+ */
18906
+ static lsTree = lsTree;
18907
+ /**
18908
+ * `git cat-file -e <ref>` — checks whether `ref` resolves to an existing
18909
+ * object, without printing it. A non-zero exit means the ref does not exist.
18910
+ */
18911
+ static refExists = refExists;
18912
+ /**
18913
+ * `git merge-base <a> <b>` — the best common ancestor commit of `a` and `b`.
18914
+ */
18915
+ static mergeBase = mergeBase;
18916
+ /**
18917
+ * `git diff --name-only -z [--relative] <base>...<head>` — the paths that
18918
+ * differ between the merge base of `base` and `head`, and `head` itself,
18919
+ * NUL-terminated.
18920
+ *
18921
+ * @remarks
18922
+ * `-z` is load-bearing here too, for the same reason as {@link GitCommand.lsTree}: split
18923
+ * the output on `"\0"`, never on `"\n"`.
18924
+ *
18925
+ * The relative flag is **explicit in both branches** — `--relative` when
18926
+ * `relative` is true, `--no-relative` when false — never omitted. git honors a
18927
+ * configured `diff.relative=true` when no flag is passed, so an omitted flag
18928
+ * would silently yield cwd-relative paths on such a machine even for
18929
+ * `relative: false`, misaligning with {@link GitCommand.untrackedFiles}'s
18930
+ * repo-root base and breaking `Git.workingChanges`' dedup in a nested workspace.
18931
+ * `--relative` scopes the report to `cwd` (a workspace nested inside a larger
18932
+ * repository); `--no-relative` overrides any `diff.relative` config and reports
18933
+ * paths from the repository top-level.
18934
+ */
18935
+ static changedFiles = changedFiles;
18936
+ /**
18937
+ * `git diff --name-only -z (--relative | --no-relative)` — the paths with
18938
+ * unstaged working-tree changes (the working tree against the index),
18939
+ * NUL-terminated.
18940
+ *
18941
+ * @remarks
18942
+ * `relative` behaves as it does for {@link GitCommand.changedFiles}, including the
18943
+ * explicit-flag-in-both-branches rule: `--no-relative` is passed for
18944
+ * `relative: false` so a configured `diff.relative=true` cannot silently make the
18945
+ * output cwd-relative.
18946
+ */
18947
+ static unstagedChanges = unstagedChanges;
18948
+ /**
18949
+ * `git diff --name-only -z (--relative | --no-relative) --cached` — the paths
18950
+ * staged for the next commit (the index against `HEAD`), NUL-terminated.
18951
+ *
18952
+ * @remarks
18953
+ * `relative` behaves as it does for {@link GitCommand.changedFiles}, including the
18954
+ * explicit `--no-relative` on the `relative: false` branch.
18955
+ */
18956
+ static stagedChanges = stagedChanges;
18957
+ /**
18958
+ * `git ls-files --others --exclude-standard -z [--full-name]` — the untracked
18959
+ * paths git is not ignoring, NUL-terminated.
18960
+ *
18961
+ * @remarks
18962
+ * `ls-files` reports paths relative to `cwd` by default, matching the
18963
+ * `--relative` diffs. When `relative` is `false`, `--full-name` makes it emit
18964
+ * repo-root-relative paths instead, so the untracked half shares a base with the
18965
+ * un-`--relative` diffs — otherwise `Git.workingChanges`'s union would dedup two
18966
+ * spellings of one file from a nested `cwd`.
18967
+ */
18968
+ static untrackedFiles = untrackedFiles;
18969
+ /**
18970
+ * `git rev-parse --verify <ref>` — resolves `ref` to its full object id, or
18971
+ * fails if `ref` does not resolve.
18972
+ */
18973
+ static revParse = revParse;
18974
+ /**
18975
+ * Mutating: `git checkout [--detach] <ref>` — moves the working tree (and, for
18976
+ * a branch ref, `HEAD`) to `ref`. When `detach` is true, checks out the ref in
18977
+ * detached-HEAD state.
18978
+ */
18979
+ static checkout = checkout;
18980
+ /**
18981
+ * Mutating: `git fetch [--depth <n>] <remote> [tag] <ref>` — fetches the given
18982
+ * ref from a remote, optionally with a depth limit and the `tag` keyword.
18983
+ */
18984
+ static fetch = fetch$1;
18985
+ /**
18986
+ * Mutating: `git submodule update [--init] [--depth <n>] [-- <paths>...]` — updates
18987
+ * registered submodules, optionally initializing them, with an optional depth limit,
18988
+ * and scoped to specific paths. The literal `--` separator makes the pathspec
18989
+ * injection-safe by construction.
18990
+ */
18991
+ static submoduleUpdate = submoduleUpdate;
18992
+ /**
18993
+ * Mutating: `git submodule add [--depth <n>] -- <url> <path>` — registers and
18994
+ * initializes a new submodule. The literal `--` separator makes the url and path
18995
+ * injection-safe by construction.
18996
+ */
18997
+ static submoduleAdd = submoduleAdd;
18998
+ /**
18999
+ * Mutating: `git sparse-checkout set (--cone | --no-cone) <patterns...>` — configures
19000
+ * which paths are checked out in a sparse repository. The cone flag is explicit in both
19001
+ * branches — `--cone` when `cone` is true, `--no-cone` when false — to prevent git's
19002
+ * default from silently changing the behavior.
19003
+ */
19004
+ static sparseCheckoutSet = sparseCheckoutSet;
19005
+ /**
19006
+ * Mutating: `git config [-f <file>] <key> <value>` — writes a configuration value,
19007
+ * optionally into an explicit configuration file (e.g., `.gitmodules`).
19008
+ */
19009
+ static configSet = configSet;
19010
+ /**
19011
+ * Mutating: `git add -- <paths...>` — stages the given paths for commit. The literal
19012
+ * `--` separator makes the pathspec injection-safe by construction.
19013
+ */
19014
+ static add = add;
19015
+ /**
19016
+ * `git diff --name-status -z (--relative | --no-relative) [<base> | <base>...<head>]`
19017
+ * — the changed paths WITH their one-letter status codes, NUL-terminated.
19018
+ *
19019
+ * @remarks
19020
+ * With `head` omitted this is the single-argument diff form: the working tree
19021
+ * (staged + unstaged) against `base` — NOT a two-ref range. With `head`
19022
+ * present it is the familiar `base...head` merge-base form, matching
19023
+ * {@link GitCommand.changedFiles}. `-z` and the explicit relative flag follow
19024
+ * the same rules as {@link GitCommand.changedFiles}. In `-z` mode a rename or
19025
+ * copy entry is THREE NUL tokens: `R<score>`, the old path, the new path.
19026
+ */
19027
+ static nameStatus = nameStatus;
19028
+ /**
19029
+ * `git symbolic-ref --quiet --short refs/remotes/<remote>/HEAD` — the name of
19030
+ * the default branch on the given remote, or empty string / exit 1 if unset.
19031
+ *
19032
+ * @remarks
19033
+ * `--quiet` suppresses error messages; the exit code alone signals success
19034
+ * (0) or "symbolic-ref does not exist" (1). The contract is "does the remote
19035
+ * have a HEAD?" — an unset symbolic ref exits 1 silently, which `Git.defaultBranch`
19036
+ * degrades to `Option.none()` rather than a typed error. `symbolic-ref` is a
19037
+ * purely local ref lookup; it never touches the network.
19038
+ */
19039
+ static defaultBranch = defaultBranch;
19040
+ /**
19041
+ * `git rev-parse --abbrev-ref HEAD` — the name of the branch `HEAD` is
19042
+ * pointing to.
19043
+ *
19044
+ * @remarks
19045
+ * Returns `"HEAD"` (detached state), `"<branch>"` (an attached branch), or
19046
+ * fails if the repository has no commits.
19047
+ */
19048
+ static currentBranch = currentBranch;
19049
+ /**
19050
+ * `git rev-parse --show-toplevel` — the filesystem path to the root of the
19051
+ * enclosing git repository.
19052
+ */
19053
+ static repoRoot = repoRoot;
19054
+ /**
19055
+ * `git log -1 --format=%H%x00%G?%x00%B <ref>` — a NUL-separated triple: the
19056
+ * full commit hash, the GPG trust level, and the full commit body (message),
19057
+ * all untrimmed.
19058
+ *
19059
+ * @remarks
19060
+ * `%H` is the full object id (40-char sha1, or sha256 if configured).
19061
+ * `%x00` is a literal NUL byte (the separator). `%G?` is the GPG trust level
19062
+ * (`G` = good signature, `B` = bad, `U` = untrusted, `X` = expired, `Y` =
19063
+ * expired key, `R` = revoked key, `E` = error, or `N` = not signed).
19064
+ * `%B` is the full body, **untrimmed** — it includes leading/trailing
19065
+ * whitespace — so the caller must decide whether to trim it. Splits on the
19066
+ * two `\x00` bytes to extract all three values.
19067
+ */
19068
+ static commitInfo = commitInfo;
19069
+ /**
19070
+ * `git config --get <key>` — the value of the given git config key, or empty
19071
+ * string / exit 1 if unset.
19072
+ */
19073
+ static configGet = configGet;
19074
+ /**
19075
+ * `git remote get-url <remote>` — the fetch URL of the given remote. A
19076
+ * missing remote exits non-zero with a "No such remote" stderr shape, which
19077
+ * the `Git` service degrades to `Option.none`, never a typed error.
19078
+ */
19079
+ static remoteUrl = remoteUrl;
19080
+ /**
19081
+ * `git status --porcelain -z` — the porcelain (stable, machine-readable) short
19082
+ * status of every modified file in the working tree, NUL-terminated.
19083
+ *
19084
+ * @remarks
19085
+ * `-z` is load-bearing here too, for the same reason as
19086
+ * {@link GitCommand.lsTree}: split the output on `"\0"`, never on `"\n"`.
19087
+ * Each entry is a pair of status codes followed by a space and the path.
19088
+ */
19089
+ static status = status;
18789
19090
  };
18790
19091
  //#endregion
18791
- //#region ../../node_modules/.pnpm/@effected+git@0.4.2_effect@4.0.0-beta.101/node_modules/@effected/git/internal/run.js
19092
+ //#region ../../node_modules/.pnpm/@effected+git@0.5.1_effect@4.0.0-beta.101/node_modules/@effected/git/internal/run.js
18792
19093
  /**
18793
19094
  * Spawns `command` and collects its stdout, stderr, and exit code as a single
18794
19095
  * triple.
@@ -18815,7 +19116,7 @@ const runCollected = (command) => effect.Effect.scoped(effect.Effect.gen(functio
18815
19116
  };
18816
19117
  }));
18817
19118
  //#endregion
18818
- //#region ../../node_modules/.pnpm/@effected+git@0.4.2_effect@4.0.0-beta.101/node_modules/@effected/git/Git.js
19119
+ //#region ../../node_modules/.pnpm/@effected+git@0.5.1_effect@4.0.0-beta.101/node_modules/@effected/git/Git.js
18819
19120
  /** git's own ceiling: a run that has not answered in 30s is not going to. */
18820
19121
  const GIT_TIMEOUT = effect.Duration.seconds(30);
18821
19122
  /**
@@ -19702,6 +20003,12 @@ const make = (spawner) => {
19702
20003
  };
19703
20004
  };
19704
20005
  /**
20006
+ * The default for every {@link Git.makeTest} method a test did not stub: a
20007
+ * defect naming the method, so an unexercised call fails loudly instead of
20008
+ * succeeding with a lie or failing with a dishonest typed error.
20009
+ */
20010
+ const notStubbed = (method) => () => effect.Effect.die(/* @__PURE__ */ new Error(`Git.makeTest: ${method}() was called but not stubbed — no honest default exists for a test double; pass a \`${method}\` override.`));
20011
+ /**
19705
20012
  * Typed git introspection over core's `ChildProcessSpawner`: read a
19706
20013
  * repository's state at any ref without checking it out, plus the mutating
19707
20014
  * tier (`checkout`, `fetch`, `fetchAny`, `submoduleUpdate`, `submoduleAdd`,
@@ -19724,15 +20031,102 @@ const make = (spawner) => {
19724
20031
  *
19725
20032
  * @public
19726
20033
  */
19727
- var Git = class extends effect.Context.Service()("@effected/git/Git") {
20034
+ var Git = class Git extends effect.Context.Service()("@effected/git/Git") {
19728
20035
  /** Resolves `ChildProcessSpawner` once, at construction — every method's `R` is `never`. */
19729
20036
  static layer = effect.Layer.effect(this, effect.Effect.gen(function* () {
19730
20037
  const spawner = yield* effect_unstable_process.ChildProcessSpawner.ChildProcessSpawner;
19731
20038
  return make(spawner);
19732
20039
  }));
20040
+ /**
20041
+ * An in-memory test double of the service shape: stub only the methods the
20042
+ * test exercises, every other method **dies** with a defect naming itself.
20043
+ *
20044
+ * @remarks
20045
+ * Unlike `WorkspaceDiscovery.makeTest`, **no method here has an honest
20046
+ * default** — the shape is twenty-six unrelated git operations, and a
20047
+ * fabricated answer for any of them (an empty tree, a made-up sha, a silent
20048
+ * no-op `checkout`) would leak into consumer logic as fact. So every
20049
+ * unstubbed method fails loudly as a defect
20050
+ * (`Git.makeTest: <name>() was called but not stubbed`) rather than
20051
+ * succeeding with a lie or failing with a dishonest typed error — which is
20052
+ * also what makes the double a proof that a test touches *nothing but* the
20053
+ * methods it stubbed.
20054
+ *
20055
+ * The double deliberately models **none** of the live service's semantics:
20056
+ * no stderr classification, no option-injection guard (an option-like ref a
20057
+ * stub accepts would be refused live), no `LC_ALL=C` pinning, no timeout,
20058
+ * and no `./`-vs-bare path resolution on `show` — a stub answers exactly
20059
+ * what it is told and nothing else. A suite exercising any of those wants
20060
+ * `Git.layer` over a mocked `ChildProcessSpawner` (or real git) instead.
20061
+ *
20062
+ * @example
20063
+ * ```ts
20064
+ * import { Git } from "@effected/git";
20065
+ * import { Effect, Option } from "effect";
20066
+ *
20067
+ * const double = Git.makeTest({
20068
+ * show: (_cwd, _ref, path) =>
20069
+ * Effect.succeed(path === "./package.json" ? Option.some("{}") : Option.none()),
20070
+ * });
20071
+ * // `double.show(...)` answers; `double.status(...)` dies, named.
20072
+ * ```
20073
+ */
20074
+ static makeTest = (overrides = {}) => ({
20075
+ show: notStubbed("show"),
20076
+ lsTree: notStubbed("lsTree"),
20077
+ refExists: notStubbed("refExists"),
20078
+ mergeBase: notStubbed("mergeBase"),
20079
+ changedFiles: notStubbed("changedFiles"),
20080
+ workingChanges: notStubbed("workingChanges"),
20081
+ revParse: notStubbed("revParse"),
20082
+ checkout: notStubbed("checkout"),
20083
+ fetch: notStubbed("fetch"),
20084
+ fetchAny: notStubbed("fetchAny"),
20085
+ submoduleUpdate: notStubbed("submoduleUpdate"),
20086
+ submoduleAdd: notStubbed("submoduleAdd"),
20087
+ sparseCheckoutSet: notStubbed("sparseCheckoutSet"),
20088
+ configSet: notStubbed("configSet"),
20089
+ add: notStubbed("add"),
20090
+ nameStatus: notStubbed("nameStatus"),
20091
+ unstagedChanges: notStubbed("unstagedChanges"),
20092
+ stagedChanges: notStubbed("stagedChanges"),
20093
+ untrackedFiles: notStubbed("untrackedFiles"),
20094
+ defaultBranch: notStubbed("defaultBranch"),
20095
+ currentBranch: notStubbed("currentBranch"),
20096
+ repoRoot: notStubbed("repoRoot"),
20097
+ configGet: notStubbed("configGet"),
20098
+ remoteUrl: notStubbed("remoteUrl"),
20099
+ commitInfo: notStubbed("commitInfo"),
20100
+ status: notStubbed("status"),
20101
+ ...overrides
20102
+ });
20103
+ /**
20104
+ * The test layer: {@link Git.makeTest} behind `Layer.succeed`, so a suite
20105
+ * provides only the methods it exercises.
20106
+ *
20107
+ * @remarks
20108
+ * A parameterized layer factory mints a **fresh reference per call**, and
20109
+ * layers memoize by reference — bind the result to a `const` and reuse it
20110
+ * rather than calling `layerTest(...)` at each composition site.
20111
+ *
20112
+ * @example
20113
+ * ```ts
20114
+ * import { Git, LsTreeEntry } from "@effected/git";
20115
+ * import { Effect } from "effect";
20116
+ *
20117
+ * const TestGit = Git.layerTest({
20118
+ * lsTree: () =>
20119
+ * Effect.succeed([
20120
+ * LsTreeEntry.make({ mode: "100644", type: "blob", oid: "0".repeat(40), path: "package.json" }),
20121
+ * ]),
20122
+ * });
20123
+ * // program.pipe(Effect.provide(TestGit))
20124
+ * ```
20125
+ */
20126
+ static layerTest = (overrides = {}) => effect.Layer.succeed(Git, Git.makeTest(overrides));
19733
20127
  };
19734
20128
  //#endregion
19735
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.7.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/ChangeDetector.js
20129
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/ChangeDetector.js
19736
20130
  /**
19737
20131
  * Which git refs to compare, and whether to fold in the working tree.
19738
20132
  *
@@ -19984,7 +20378,7 @@ function resolveFromCatalog(catalogs, wantedDependency) {
19984
20378
  };
19985
20379
  }
19986
20380
  //#endregion
19987
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.7.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/catalogs.js
20381
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/catalogs.js
19988
20382
  /** Project a pnpm-workspace manifest's `catalog` / `catalogs` fields into a `Catalogs` map. */
19989
20383
  const inlineCatalogs = (manifest) => {
19990
20384
  if (manifest.catalog === void 0 && manifest.catalogs === void 0) return {};
@@ -20048,7 +20442,7 @@ const rangeOf = (catalogs, dependency, specifier) => {
20048
20442
  });
20049
20443
  };
20050
20444
  //#endregion
20051
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.7.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/ConfigDependencyHooks.js
20445
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/ConfigDependencyHooks.js
20052
20446
  /** Whether `value` is a non-null, non-array object. */
20053
20447
  const isObject$2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
20054
20448
  /**
@@ -20234,7 +20628,7 @@ var ConfigDependencyHooks = class ConfigDependencyHooks extends effect.Context.S
20234
20628
  }) });
20235
20629
  };
20236
20630
  //#endregion
20237
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.7.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/PackageManagerName.js
20631
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/PackageManagerName.js
20238
20632
  /**
20239
20633
  * The four package managers this package understands.
20240
20634
  *
@@ -20335,7 +20729,11 @@ const CHECKED = [
20335
20729
  "bun.lock",
20336
20730
  "bun.lockb",
20337
20731
  "yarn.lock",
20338
- "package.json#workspaces"
20732
+ "package.json#workspaces",
20733
+ "pnpm-lock.yaml",
20734
+ "package-lock.json",
20735
+ "package.json#packageManager",
20736
+ "package.json#devEngines.packageManager"
20339
20737
  ];
20340
20738
  /**
20341
20739
  * Detects which package manager owns a workspace root.
@@ -20449,7 +20847,8 @@ var PackageManagerDetector = class PackageManagerDetector extends effect.Context
20449
20847
  version: versionFor(hints, "pnpm"),
20450
20848
  runtime: "node"
20451
20849
  });
20452
- if (((yield* has(root, "bun.lock")) || (yield* has(root, "bun.lockb"))) && namesManager(hints, "bun")) return DetectedPackageManager.make({
20850
+ const bunLock = (yield* has(root, "bun.lock")) || (yield* has(root, "bun.lockb"));
20851
+ if (bunLock && namesManager(hints, "bun")) return DetectedPackageManager.make({
20453
20852
  name: "bun",
20454
20853
  version: versionFor(hints, "bun"),
20455
20854
  runtime: "bun"
@@ -20465,6 +20864,35 @@ var PackageManagerDetector = class PackageManagerDetector extends effect.Context
20465
20864
  version: versionFor(hints, "npm"),
20466
20865
  runtime: "node"
20467
20866
  });
20867
+ if (yield* has(root, "pnpm-lock.yaml")) return DetectedPackageManager.make({
20868
+ name: "pnpm",
20869
+ version: versionFor(hints, "pnpm"),
20870
+ runtime: "node"
20871
+ });
20872
+ if (bunLock && namesManager(hints, "bun")) return DetectedPackageManager.make({
20873
+ name: "bun",
20874
+ version: versionFor(hints, "bun"),
20875
+ runtime: "bun"
20876
+ });
20877
+ if ((yield* has(root, "yarn.lock")) && namesManager(hints, "yarn")) return DetectedPackageManager.make({
20878
+ name: "yarn",
20879
+ version: versionFor(hints, "yarn"),
20880
+ runtime: "node"
20881
+ });
20882
+ if (yield* has(root, "package-lock.json")) return DetectedPackageManager.make({
20883
+ name: "npm",
20884
+ version: versionFor(hints, "npm"),
20885
+ runtime: "node"
20886
+ });
20887
+ const declared = declaredName(hints);
20888
+ if (effect.Option.isSome(declared)) {
20889
+ const name = declared.value;
20890
+ if (name === "pnpm" || name === "npm" || name === "yarn" || name === "bun") return DetectedPackageManager.make({
20891
+ name,
20892
+ version: versionFor(hints, name),
20893
+ runtime: name === "bun" ? "bun" : "node"
20894
+ });
20895
+ }
20468
20896
  return yield* effect.Effect.fail(new PackageManagerDetectionError({
20469
20897
  root,
20470
20898
  checked: CHECKED
@@ -20474,9 +20902,56 @@ var PackageManagerDetector = class PackageManagerDetector extends effect.Context
20474
20902
  });
20475
20903
  /** The live layer. */
20476
20904
  static layer = effect.Layer.effect(PackageManagerDetector, PackageManagerDetector.make);
20905
+ /**
20906
+ * The sanctioned in-memory double.
20907
+ *
20908
+ * @remarks
20909
+ * **`detect` has no honest default, so an unstubbed call dies** — the
20910
+ * `WorkspaceDiscovery.info` posture, for the same reason. A stand-in that
20911
+ * answered `"pnpm"` would hand a consumer a fact nothing established, and it
20912
+ * would contradict the very service it stands in for: the live detector's
20913
+ * defining property is that it [refuses to
20914
+ * guess](https://github.com/spencerbeggs/effected) when no evidence matches.
20915
+ * A double that guesses is worse than no double.
20916
+ *
20917
+ * Failing typed would be the subtler mistake: `PackageManagerDetectionError`
20918
+ * reads as a legitimate "no manager here" answer, so a consumer would branch
20919
+ * on it and proceed, never learning that the test simply forgot to stub.
20920
+ *
20921
+ * @param overrides - Members to supply; anything omitted dies on use.
20922
+ *
20923
+ * @example
20924
+ * ```ts
20925
+ * import { DetectedPackageManager, PackageManagerDetector } from "@effected/workspaces";
20926
+ * import { Effect, Option } from "effect";
20927
+ *
20928
+ * const TestDetector = PackageManagerDetector.layerTest({
20929
+ * detect: () =>
20930
+ * Effect.succeed(
20931
+ * DetectedPackageManager.make({ name: "pnpm", version: Option.none(), runtime: "node" }),
20932
+ * ),
20933
+ * });
20934
+ * ```
20935
+ */
20936
+ static makeTest = (overrides = {}) => ({
20937
+ detect: () => effect.Effect.die(/* @__PURE__ */ new Error("PackageManagerDetector.makeTest: detect() was called but not stubbed — no honest default DetectedPackageManager exists for a test double; pass a `detect` override.")),
20938
+ ...overrides
20939
+ });
20940
+ /**
20941
+ * {@link PackageManagerDetector.makeTest} behind `Layer.succeed`.
20942
+ *
20943
+ * @remarks
20944
+ * A parameterized layer factory mints a **fresh reference per call**, and
20945
+ * layers memoize by reference — bind the result to a `const` and reuse it
20946
+ * rather than calling `layerTest(...)` at each composition site.
20947
+ *
20948
+ * Pairs with `WorkspaceRoot.layerTest` and `WorkspaceDiscovery.layerTest` to
20949
+ * stand up the whole discovery path with no filesystem at all.
20950
+ */
20951
+ static layerTest = (overrides = {}) => effect.Layer.succeed(PackageManagerDetector, PackageManagerDetector.makeTest(overrides));
20477
20952
  };
20478
20953
  //#endregion
20479
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.7.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/LockfileReader.js
20954
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/LockfileReader.js
20480
20955
  /**
20481
20956
  * Raised when the workspace's lockfile cannot be read off disk.
20482
20957
  *
@@ -20499,6 +20974,8 @@ var LockfileReadError = class extends effect.Schema.TaggedErrorClass()("Lockfile
20499
20974
  return `Cannot read ${this.format} lockfile at ${this.lockfilePath}`;
20500
20975
  }
20501
20976
  };
20977
+ /** A defect naming the unstubbed test-double method — a test-wiring mistake, not a typed failure. */
20978
+ const unstubbed$2 = (method) => effect.Effect.die(/* @__PURE__ */ new Error(`LockfileReader.makeTest: ${method}() was called but not stubbed — pass a \`${method}\` override.`));
20502
20979
  /**
20503
20980
  * Reads and parses the workspace's lockfile.
20504
20981
  *
@@ -20584,9 +21061,77 @@ var LockfileReader = class LockfileReader extends effect.Context.Service()("@eff
20584
21061
  * `const` and reuse it.
20585
21062
  */
20586
21063
  static layer = (options) => effect.Layer.effect(LockfileReader, LockfileReader.make(options));
21064
+ /**
21065
+ * A test double satisfying the full {@link LockfileReaderShape} with no
21066
+ * filesystem, root walk, or package-manager detection.
21067
+ *
21068
+ * @remarks
21069
+ * There is **no honest default lockfile**: an empty one that looks like a
21070
+ * legitimate answer is indistinguishable from "this workspace resolves
21071
+ * nothing" — the silent-empty failure class this package documents on the
21072
+ * live paths — so `read` **dies** with an instructive defect until stubbed.
21073
+ *
21074
+ * The one derivation mirrors `WorkspaceDiscovery.makeTest`'s
21075
+ * derived-from-the-primary rule: when a `read` override is supplied,
21076
+ * `resolvedVersion` answers as the live service does — the **first** entry
21077
+ * of `lockfile.packagesNamed(name)` in lockfile order, `Option.none()` on a
21078
+ * miss — so the two stay consistent by construction. `integrity` is **not**
21079
+ * derivable: the live method compares the lockfile against the workspace
21080
+ * manifests discovery enumerates, and the double has no discovery to ask, so
21081
+ * it dies unless stubbed.
21082
+ *
21083
+ * `refresh` defaults to `Effect.void` honestly: the live contract is "drop
21084
+ * the memoized read so the next call re-reads", and this double memoizes
21085
+ * nothing — every `read()` call re-invokes the override — so there is
21086
+ * nothing to drop and the no-op is truthful, the same reasoning as
21087
+ * `WorkspaceDiscovery.makeTest`'s `refresh`.
21088
+ *
21089
+ * @example
21090
+ * ```ts
21091
+ * import { Lockfile } from "@effected/lockfiles";
21092
+ * import { LockfileReader } from "@effected/workspaces";
21093
+ * import { Effect } from "effect";
21094
+ *
21095
+ * const double = LockfileReader.makeTest({
21096
+ * read: () =>
21097
+ * Effect.succeed(
21098
+ * Lockfile.make({ format: "pnpm", lockfileVersion: "9.0", packages: [], workspaceDependencies: [] }),
21099
+ * ),
21100
+ * });
21101
+ * // `resolvedVersion` now answers consistently from that lockfile.
21102
+ * ```
21103
+ */
21104
+ static makeTest = (overrides = {}) => {
21105
+ const read = overrides.read;
21106
+ return {
21107
+ read: () => unstubbed$2("read"),
21108
+ resolvedVersion: read !== void 0 ? (packageName) => effect.Effect.map(read(), (lockfile) => effect.Option.fromUndefinedOr(lockfile.packagesNamed(packageName)[0])) : () => unstubbed$2("resolvedVersion"),
21109
+ integrity: () => unstubbed$2("integrity"),
21110
+ refresh: () => effect.Effect.void,
21111
+ ...overrides
21112
+ };
21113
+ };
21114
+ /**
21115
+ * The test layer: {@link LockfileReader.makeTest} behind `Layer.succeed`, so
21116
+ * a suite provides only the methods it exercises.
21117
+ *
21118
+ * @remarks
21119
+ * A parameterized layer factory mints a **fresh reference per call**, and
21120
+ * layers memoize by reference — bind the result to a `const` and reuse it
21121
+ * rather than calling `layerTest(...)` at each composition site.
21122
+ *
21123
+ * @example
21124
+ * ```ts
21125
+ * import { LockfileReader } from "@effected/workspaces";
21126
+ *
21127
+ * const TestLockfiles = LockfileReader.layerTest();
21128
+ * // program.pipe(Effect.provide(TestLockfiles)) — dies loudly if touched.
21129
+ * ```
21130
+ */
21131
+ static layerTest = (overrides = {}) => effect.Layer.succeed(LockfileReader, LockfileReader.makeTest(overrides));
20587
21132
  };
20588
21133
  //#endregion
20589
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.7.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/Publishability.js
21134
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/Publishability.js
20590
21135
  /** The public npm registry, used when `publishConfig.registry` says nothing. */
20591
21136
  const DEFAULT_REGISTRY = "https://registry.npmjs.org/";
20592
21137
  /**
@@ -20670,9 +21215,35 @@ var PublishTarget = class extends effect.Schema.Class("PublishTarget")({
20670
21215
  *
20671
21216
  * @public
20672
21217
  */
20673
- var PublishabilityDetector = class PublishabilityDetector extends effect.Context.Service()("@effected/workspaces/PublishabilityDetector") {
20674
- /** Standard npm publishing semantics. Pure — no filesystem, no platform services. */
20675
- static layer = effect.Layer.succeed(PublishabilityDetector, { detect: (pkg) => effect.Effect.sync(() => {
21218
+ var PublishabilityDetector = class extends effect.Context.Service()("@effected/workspaces/PublishabilityDetector") {
21219
+ /**
21220
+ * Standard npm publishing semantics, **as a value**. Pure no filesystem,
21221
+ * no platform services.
21222
+ *
21223
+ * @remarks
21224
+ * Exposed as a shape and not only as a layer, because a consumer composing
21225
+ * *around* these rules cannot reach them through a layer without re-entering
21226
+ * the very tag it is replacing. `@savvy-web/silk-effects` had to write
21227
+ * `Effect.provide(PublishabilityDetector, PublishabilityDetector.layer)`
21228
+ * **inside its own implementation of that tag** to get at this function for
21229
+ * its pass-through branch; with the value exposed that becomes
21230
+ * `PublishabilityDetector.npm.detect(pkg)`.
21231
+ *
21232
+ * @example
21233
+ * ```ts
21234
+ * import { PublishabilityDetector } from "@effected/workspaces";
21235
+ * import { Effect, Layer } from "effect";
21236
+ *
21237
+ * // A policy that defers to npm semantics for everything it does not veto.
21238
+ * const withVeto = Layer.succeed(PublishabilityDetector, {
21239
+ * detect: (pkg) =>
21240
+ * pkg.name.endsWith("-private")
21241
+ * ? Effect.succeed([])
21242
+ * : PublishabilityDetector.npm.detect(pkg),
21243
+ * });
21244
+ * ```
21245
+ */
21246
+ static npm = { detect: (pkg) => effect.Effect.sync(() => {
20676
21247
  const config = pkg.publishConfig;
20677
21248
  const access = config?.access;
20678
21249
  if (pkg.private && access === void 0) return [];
@@ -20683,10 +21254,36 @@ var PublishabilityDetector = class PublishabilityDetector extends effect.Context
20683
21254
  access: access ?? "public",
20684
21255
  provenance: false
20685
21256
  })];
20686
- }) });
21257
+ }) };
21258
+ /** Nothing publishes. */
21259
+ static none = { detect: () => effect.Effect.succeed([]) };
21260
+ /**
21261
+ * {@link PublishabilityDetector.npm} as a layer.
21262
+ *
21263
+ * @remarks
21264
+ * Named for its policy rather than called `layer`, deliberately. **No
21265
+ * composite in this package provides a publishability detector**: a
21266
+ * `Workspaces.layer()` that quietly supplied npm semantics made the choice
21267
+ * invisible, and worse, made a naively-ordered override lose to it in
21268
+ * silence — `Layer.mergeAll(myDetector, Workspaces.layer())` resolved to the
21269
+ * default, because `mergeAll` is last-wins. For a service that decides
21270
+ * whether a package publishes and to which registry, that silent revert was
21271
+ * the worst available failure. The requirement now sits in `R`, so the
21272
+ * choice is made once, explicitly, and unmade wiring does not compile.
21273
+ */
21274
+ static layerNpm = effect.Layer.succeed(this, this.npm);
21275
+ /**
21276
+ * {@link PublishabilityDetector.none} as a layer: a workspace where nothing
21277
+ * publishes.
21278
+ *
21279
+ * @remarks
21280
+ * For dry runs, and for a release tool whose configuration disables
21281
+ * publishing wholesale — silk's changeset `mode: "none"` is exactly this.
21282
+ */
21283
+ static layerNone = effect.Layer.succeed(this, this.none);
20687
21284
  };
20688
21285
  //#endregion
20689
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.7.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/importerVersions.js
21286
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/importerVersions.js
20690
21287
  /**
20691
21288
  * Strip pnpm's peer-disambiguation suffix from a recorded importer version.
20692
21289
  *
@@ -20772,7 +21369,7 @@ const unanimousVersionOf = (index, dependency) => {
20772
21369
  return agreed;
20773
21370
  };
20774
21371
  //#endregion
20775
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.7.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspaceCatalogs.js
21372
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspaceCatalogs.js
20776
21373
  /**
20777
21374
  * An immutable, fully-normalized catalog collection — the one catalog
20778
21375
  * resolution semantic in the package.
@@ -21048,6 +21645,8 @@ const validatePnpmWorkspaceCatalogs = (document) => {
21048
21645
  catalogs: "catalogs"
21049
21646
  }));
21050
21647
  };
21648
+ /** A defect naming the unstubbed test-double method — a test-wiring mistake, not a typed failure. */
21649
+ const unstubbed$1 = (method) => effect.Effect.die(/* @__PURE__ */ new Error(`WorkspaceCatalogs.makeTest: ${method}() was called but not stubbed — pass a \`${method}\` override.`));
21051
21650
  /**
21052
21651
  * Assembles a workspace's catalogs, package-manager-aware.
21053
21652
  *
@@ -21191,6 +21790,70 @@ var WorkspaceCatalogs = class WorkspaceCatalogs extends effect.Context.Service()
21191
21790
  */
21192
21791
  static layerWithConfigDependencies = (options) => effect.Layer.effect(WorkspaceCatalogs, WorkspaceCatalogs.make(options)).pipe(effect.Layer.provide(ConfigDependencyHooks.layerLive));
21193
21792
  /**
21793
+ * A test double satisfying the full {@link WorkspaceCatalogsShape} with no
21794
+ * filesystem, lockfile read, or hook replay.
21795
+ *
21796
+ * @remarks
21797
+ * There is **no honest default catalog set**: an empty `CatalogSet` that
21798
+ * looks like a legitimate answer is the "every dependency looks newly added"
21799
+ * failure class the live assembler hard-fails to prevent, so every method
21800
+ * **dies** with an instructive defect until stubbed — a test-wiring mistake
21801
+ * fails loudly as a defect rather than succeeding with a lie or failing with
21802
+ * a dishonest typed error.
21803
+ *
21804
+ * The one derivation mirrors `WorkspaceDiscovery.makeTest`'s
21805
+ * derived-from-the-primary rule: when a `set` override is supplied,
21806
+ * `resolveSpecifier` answers from that `CatalogSet`'s own
21807
+ * {@link CatalogSet.resolveSpecifier} — exactly what the live service runs
21808
+ * over its assembled set — so the two stay consistent by construction.
21809
+ * `releaseAgeGate` and `importerVersions` are **not** derivable from a
21810
+ * catalog set (the gate comes from release-age keys and hook contributions,
21811
+ * the importer index from the lockfile's importer blocks — neither is in a
21812
+ * `CatalogSet`) and always die unless stubbed.
21813
+ *
21814
+ * @example
21815
+ * ```ts
21816
+ * import { CatalogSet, WorkspaceCatalogs } from "@effected/workspaces";
21817
+ * import { Effect } from "effect";
21818
+ *
21819
+ * const double = WorkspaceCatalogs.makeTest({
21820
+ * set: () => Effect.succeed(CatalogSet.fromCatalogs({ default: { effect: "4.0.0" } })),
21821
+ * });
21822
+ * // `resolveSpecifier` now answers consistently from that set.
21823
+ * ```
21824
+ */
21825
+ static makeTest = (overrides = {}) => {
21826
+ const set = overrides.set;
21827
+ return {
21828
+ set: () => unstubbed$1("set"),
21829
+ resolveSpecifier: set !== void 0 ? (dependency, specifier) => effect.Effect.map(set(), (catalogs) => catalogs.resolveSpecifier(dependency, specifier)) : () => unstubbed$1("resolveSpecifier"),
21830
+ releaseAgeGate: () => unstubbed$1("releaseAgeGate"),
21831
+ importerVersions: () => unstubbed$1("importerVersions"),
21832
+ ...overrides
21833
+ };
21834
+ };
21835
+ /**
21836
+ * The test layer: {@link WorkspaceCatalogs.makeTest} behind `Layer.succeed`,
21837
+ * so a suite provides only the methods it exercises.
21838
+ *
21839
+ * @remarks
21840
+ * A parameterized layer factory mints a **fresh reference per call**, and
21841
+ * layers memoize by reference — bind the result to a `const` and reuse it
21842
+ * rather than calling `layerTest(...)` at each composition site.
21843
+ *
21844
+ * @example
21845
+ * ```ts
21846
+ * import { CatalogSet, WorkspaceCatalogs } from "@effected/workspaces";
21847
+ * import { Effect } from "effect";
21848
+ *
21849
+ * const TestCatalogs = WorkspaceCatalogs.layerTest({
21850
+ * set: () => Effect.succeed(CatalogSet.empty()),
21851
+ * });
21852
+ * // program.pipe(Effect.provide(TestCatalogs))
21853
+ * ```
21854
+ */
21855
+ static layerTest = (overrides = {}) => effect.Layer.succeed(WorkspaceCatalogs, WorkspaceCatalogs.makeTest(overrides));
21856
+ /**
21194
21857
  * The real implementation of `@effected/npm`'s `CatalogResolver` contract —
21195
21858
  * the one `@effected/package-json` declares but cannot fill.
21196
21859
  *
@@ -21215,7 +21878,7 @@ var WorkspaceCatalogs = class WorkspaceCatalogs extends effect.Context.Service()
21215
21878
  }));
21216
21879
  };
21217
21880
  //#endregion
21218
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.7.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspaceStateSnapshot.js
21881
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspaceStateSnapshot.js
21219
21882
  const EMPTY = Object.freeze(Object.create(null));
21220
21883
  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)));
21221
21884
  /**
@@ -21438,7 +22101,7 @@ var WorkspaceStateSnapshot = class extends effect.Schema.Class("WorkspaceStateSn
21438
22101
  }
21439
22102
  };
21440
22103
  //#endregion
21441
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.7.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspaceSnapshots.js
22104
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspaceSnapshots.js
21442
22105
  /** Whether `value` is a non-null, non-array object. */
21443
22106
  const isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
21444
22107
  /** Whether every value in a record is a string — a usable dependency map. */
@@ -21497,6 +22160,8 @@ const EMPTY_LOCKFILE_RECORD = {
21497
22160
  catalogs: CatalogSet.empty(),
21498
22161
  importerVersions: {}
21499
22162
  };
22163
+ /** A defect naming the unstubbed test-double method — a test-wiring mistake, not a typed failure. */
22164
+ const unstubbed = (method) => effect.Effect.die(/* @__PURE__ */ new Error(`WorkspaceSnapshots.makeTest: ${method}() was called but not stubbed — pass a \`${method}\` override.`));
21500
22165
  /**
21501
22166
  * Reads workspace state at a git ref with no checkout, and the live worktree.
21502
22167
  *
@@ -21643,144 +22308,306 @@ var WorkspaceSnapshots = class WorkspaceSnapshots extends effect.Context.Service
21643
22308
  * `const` and reuse it, or layer memoization does not apply.
21644
22309
  */
21645
22310
  static layer = (options) => effect.Layer.effect(WorkspaceSnapshots, WorkspaceSnapshots.make(options));
22311
+ /**
22312
+ * A test double satisfying the full {@link WorkspaceSnapshotsShape} with no
22313
+ * git, filesystem, discovery, or catalog assembly.
22314
+ *
22315
+ * @remarks
22316
+ * There are **no honest defaults and no derivations** here: `at(ref)` and
22317
+ * `worktree()` are two independent reads of two different sources (a git ref
22318
+ * vs. the live tree), so neither can be honestly derived from the other, and
22319
+ * a fabricated empty {@link WorkspaceStateSnapshot} on either side of a
22320
+ * before/after diff reads as every dependency newly added or removed — the
22321
+ * exact silent-empty failure class this package documents on the live paths.
22322
+ * Both methods therefore **die** with an instructive defect until stubbed; a
22323
+ * test-wiring mistake fails loudly as a defect rather than succeeding with a
22324
+ * lie.
22325
+ *
22326
+ * @example
22327
+ * ```ts
22328
+ * import { CatalogSet, WorkspaceSnapshots, WorkspaceStateSnapshot } from "@effected/workspaces";
22329
+ * import { Effect } from "effect";
22330
+ *
22331
+ * const empty = WorkspaceStateSnapshot.make({
22332
+ * packages: [],
22333
+ * catalogs: CatalogSet.empty(),
22334
+ * importerVersions: {},
22335
+ * });
22336
+ * const double = WorkspaceSnapshots.makeTest({
22337
+ * at: () => Effect.succeed(empty),
22338
+ * worktree: () => Effect.succeed(empty),
22339
+ * });
22340
+ * ```
22341
+ */
22342
+ static makeTest = (overrides = {}) => ({
22343
+ at: () => unstubbed("at"),
22344
+ worktree: () => unstubbed("worktree"),
22345
+ ...overrides
22346
+ });
22347
+ /**
22348
+ * The test layer: {@link WorkspaceSnapshots.makeTest} behind `Layer.succeed`,
22349
+ * so a suite provides only the methods it exercises.
22350
+ *
22351
+ * @remarks
22352
+ * A parameterized layer factory mints a **fresh reference per call**, and
22353
+ * layers memoize by reference — bind the result to a `const` and reuse it
22354
+ * rather than calling `layerTest(...)` at each composition site.
22355
+ *
22356
+ * @example
22357
+ * ```ts
22358
+ * import { CatalogSet, WorkspaceSnapshots, WorkspaceStateSnapshot } from "@effected/workspaces";
22359
+ * import { Effect } from "effect";
22360
+ *
22361
+ * const TestSnapshots = WorkspaceSnapshots.layerTest({
22362
+ * worktree: () =>
22363
+ * Effect.succeed(
22364
+ * WorkspaceStateSnapshot.make({ packages: [], catalogs: CatalogSet.empty(), importerVersions: {} }),
22365
+ * ),
22366
+ * });
22367
+ * // program.pipe(Effect.provide(TestSnapshots))
22368
+ * ```
22369
+ */
22370
+ static layerTest = (overrides = {}) => effect.Layer.succeed(WorkspaceSnapshots, WorkspaceSnapshots.makeTest(overrides));
21646
22371
  };
21647
22372
  //#endregion
21648
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.7.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/Workspaces.js
21649
- /**
21650
- * Every service that needs only a filesystem: root, package-manager detection,
21651
- * discovery, lockfile reading, catalogs and publishability.
21652
- *
21653
- * @remarks
21654
- * Requires core `FileSystem` and `Path`, which the consumer provides at the
21655
- * edge (`@effect/platform-node`, `@effect/platform-bun`, or a test's
21656
- * `FileSystem.layerNoop`).
21657
- *
21658
- * **Bind the result to a `const`.** This is a parameterized factory and layers
21659
- * memoize by reference, so calling it twice builds everything twice.
21660
- *
21661
- * @example
21662
- * ```ts
21663
- * import { Workspaces } from "@effected/workspaces";
21664
- * import { Layer } from "effect";
21665
- *
21666
- * const WorkspacesLayer = Workspaces.layer();
21667
- * const AppLayer = Layer.provide(WorkspacesLayer, PlatformLayer);
21668
- * ```
21669
- *
21670
- * @public
21671
- */
22373
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.0_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/Workspaces.js
21672
22374
  const compose = (options, catalogsFactory) => {
21673
22375
  const roots = WorkspaceRoot.layer;
21674
22376
  const detector = PackageManagerDetector.layer;
21675
22377
  const discovery = WorkspaceDiscovery.layer(options).pipe(effect.Layer.provide(roots));
21676
22378
  const lockfiles = LockfileReader.layer(options).pipe(effect.Layer.provide(roots), effect.Layer.provide(detector), effect.Layer.provide(discovery));
21677
22379
  const catalogs = catalogsFactory(options).pipe(effect.Layer.provide(roots), effect.Layer.provide(lockfiles));
21678
- return effect.Layer.mergeAll(roots, detector, discovery, lockfiles, catalogs, PublishabilityDetector.layer);
22380
+ return effect.Layer.mergeAll(roots, detector, discovery, lockfiles, catalogs);
21679
22381
  };
21680
22382
  const layer = (options) => compose(options, WorkspaceCatalogs.layer);
21681
- /**
21682
- * The git-free composite plus {@link ChangeDetector} and
21683
- * {@link WorkspaceSnapshots}, over `@effected/git`'s `Git` service.
21684
- *
21685
- * @remarks
21686
- * The extra requirement is core's `ChildProcessSpawner` (behind `Git`), which
21687
- * is why it is a separate layer rather than a flag: a consumer that never
21688
- * detects changes or reads at a ref should not have to be able to spawn a
21689
- * subprocess. The consumer provides `ChildProcessSpawner` once at the edge
21690
- * (`@effect/platform-node`'s `NodeServices.layer`); a test provides
21691
- * `Layer.succeed(Git, …)` and needs no repository on disk.
21692
- *
21693
- * @public
21694
- */
21695
22383
  const layerWithGit = (options) => {
21696
22384
  const core = layer(options);
21697
22385
  const git = Git.layer;
21698
22386
  return effect.Layer.mergeAll(core, git, ChangeDetector.layer.pipe(effect.Layer.provide(git), effect.Layer.provide(core)), WorkspaceSnapshots.layer(options).pipe(effect.Layer.provide(git), effect.Layer.provide(core)));
21699
22387
  };
21700
- /**
21701
- * The two `@effected/npm` resolver contracts, implemented for real.
21702
- *
21703
- * @remarks
21704
- * Provide this alongside `@effected/package-json`'s `Package.resolve` and a
21705
- * manifest's `catalog:` and `workspace:` specifiers resolve against the actual
21706
- * workspace instead of the no-op layers' `Option.none()`.
21707
- *
21708
- * @example
21709
- * ```ts
21710
- * import { Package } from "@effected/package-json";
21711
- * import { Workspaces } from "@effected/workspaces";
21712
- * import { Layer } from "effect";
21713
- *
21714
- * const WorkspacesLayer = Workspaces.layer();
21715
- * const Resolvers = Workspaces.resolvers.pipe(Layer.provide(WorkspacesLayer));
21716
- * ```
21717
- *
21718
- * @public
21719
- */
21720
22388
  const resolvers = effect.Layer.mergeAll(WorkspaceCatalogs.catalogResolver, WorkspaceDiscovery.workspaceResolver);
21721
- /**
21722
- * The git-free composite, but with catalog assembly that **replays config
21723
- * dependency `pnpmfile.cjs` hooks** — {@link WorkspaceCatalogs.layerWithConfigDependencies}
21724
- * in place of the default no-op catalogs layer.
21725
- *
21726
- * @remarks
21727
- * Identical requirement set to {@link Workspaces.layer}; the only difference is
21728
- * that config-dependency code is executed in process. Opt in deliberately — the
21729
- * default {@link Workspaces.layer} never executes config-dependency code.
21730
- *
21731
- * **Bind the result to a `const`.**
21732
- *
21733
- * @public
21734
- */
21735
22389
  const layerWithConfigDependencies = (options) => compose(options, WorkspaceCatalogs.layerWithConfigDependencies);
21736
- /**
21737
- * The one-call resolver factory: {@link Workspaces.resolvers} pre-wired over
21738
- * {@link Workspaces.layerWithConfigDependencies}, so the two `@effected/npm`
21739
- * contracts (`CatalogResolver`, `WorkspaceResolver`) need only a platform
21740
- * (`FileSystem` + `Path`) from the consumer.
21741
- *
21742
- * @remarks
21743
- * This is deliberately a **parameterized layer function, and the fresh layer
21744
- * per call is the feature**: layers memoize by reference, so each call mints
21745
- * an unmemoized layer whose root discovery re-runs — including a per-call
21746
- * `process.cwd()` read when `options.cwd` is omitted. A build tool that
21747
- * changes directory between manifests gets a correct re-discovery each time
21748
- * precisely because nothing is shared across calls. When you *want* sharing,
21749
- * bind one call's result to a `const` and provide that; the memoization rule
21750
- * is unchanged, this factory just refuses to hide it.
21751
- *
21752
- * Catalog assembly replays config-dependency `pnpmfile` hooks (the
21753
- * `layerWithConfigDependencies` path) — the semantics a real pnpm install
21754
- * has. Compose {@link Workspaces.resolvers} with {@link Workspaces.layer}
21755
- * yourself if config-dependency code must not run in process.
21756
- *
21757
- * @example
21758
- * ```ts
21759
- * import { Workspaces } from "@effected/workspaces";
21760
- * import { Effect } from "effect";
21761
- *
21762
- * const program = doSomethingWithResolvers.pipe(
21763
- * Effect.provide(Workspaces.resolverLayer()),
21764
- * );
21765
- * ```
21766
- *
21767
- * @public
21768
- */
21769
22390
  const resolverLayer = (options) => resolvers.pipe(effect.Layer.provide(layerWithConfigDependencies(options)));
22391
+ const resolveManifest = effect.Effect.fn("Workspaces.resolveManifest")(function* (manifest, options) {
22392
+ return yield* manifest.resolve().pipe(effect.Effect.provide(resolverLayer(options)));
22393
+ });
22394
+ const localExecLayer = (options) => effect.Layer.effect(LocalExec, effect.Effect.gen(function* () {
22395
+ const roots = yield* WorkspaceRoot;
22396
+ const detector = yield* PackageManagerDetector;
22397
+ return { context: effect.Effect.gen(function* () {
22398
+ const cwd = options?.cwd ?? globalThis.process?.cwd?.() ?? "/";
22399
+ const root = yield* roots.find(cwd).pipe(effect.Effect.asSome, effect.Effect.orElseSucceed(effect.Option.none));
22400
+ if (effect.Option.isNone(root)) return effect.Option.none();
22401
+ const detected = yield* detector.detect(root.value).pipe(effect.Effect.asSome, effect.Effect.catchTag("PackageManagerDetectionError", () => effect.Effect.succeed(effect.Option.none())), effect.Effect.mapError((cause) => new LocalExecError({
22402
+ directory: root.value,
22403
+ cause
22404
+ })));
22405
+ if (effect.Option.isNone(detected)) return effect.Option.none();
22406
+ const { prefix, dlxPrefix } = LocalExec.prefixes(detected.value.name);
22407
+ return effect.Option.some(ExecContext.make({
22408
+ label: detected.value.name,
22409
+ prefix,
22410
+ dlxPrefix,
22411
+ directory: root.value
22412
+ }));
22413
+ }) };
22414
+ }));
21770
22415
  /**
21771
22416
  * The composite layers.
21772
22417
  *
21773
22418
  * @public
21774
22419
  */
21775
- const Workspaces = {
21776
- layer,
21777
- layerWithConfigDependencies,
21778
- layerWithGit,
21779
- resolveManifest: effect.Effect.fn("Workspaces.resolveManifest")(function* (manifest, options) {
21780
- return yield* manifest.resolve().pipe(effect.Effect.provide(resolverLayer(options)));
21781
- }),
21782
- resolverLayer,
21783
- resolvers
22420
+ var Workspaces = class {
22421
+ constructor() {}
22422
+ /**
22423
+ * Every service that needs only a filesystem: root, package-manager
22424
+ * detection, discovery, lockfile reading, catalogs and publishability.
22425
+ *
22426
+ * @remarks
22427
+ * Requires core `FileSystem` and `Path`, which the consumer provides at the
22428
+ * edge (`@effect/platform-node`, `@effect/platform-bun`, or a test's
22429
+ * `FileSystem.layerNoop`).
22430
+ *
22431
+ * **Bind the result to a `const`.** This is a parameterized factory and
22432
+ * layers memoize by reference, so calling it twice builds everything twice.
22433
+ *
22434
+ * @example
22435
+ * ```ts
22436
+ * import { Workspaces } from "@effected/workspaces";
22437
+ * import { Layer } from "effect";
22438
+ *
22439
+ * const WorkspacesLayer = Workspaces.layer();
22440
+ * const AppLayer = Layer.provide(WorkspacesLayer, PlatformLayer);
22441
+ * ```
22442
+ */
22443
+ static layer = layer;
22444
+ /**
22445
+ * The git-free composite, but with catalog assembly that **replays config
22446
+ * dependency `pnpmfile.cjs` hooks** —
22447
+ * {@link WorkspaceCatalogs.layerWithConfigDependencies} in place of the
22448
+ * default no-op catalogs layer.
22449
+ *
22450
+ * @remarks
22451
+ * Identical requirement set to {@link Workspaces.layer}; the only
22452
+ * difference is that config-dependency code is executed in process. Opt in
22453
+ * deliberately — the default {@link Workspaces.layer} never executes
22454
+ * config-dependency code.
22455
+ *
22456
+ * **Bind the result to a `const`.**
22457
+ */
22458
+ static layerWithConfigDependencies = layerWithConfigDependencies;
22459
+ /**
22460
+ * The git-free composite plus {@link ChangeDetector} and
22461
+ * {@link WorkspaceSnapshots}, over `@effected/git`'s `Git` service.
22462
+ *
22463
+ * @remarks
22464
+ * The extra requirement is core's `ChildProcessSpawner` (behind `Git`),
22465
+ * which is why it is a separate layer rather than a flag: a consumer that
22466
+ * never detects changes or reads at a ref should not have to be able to
22467
+ * spawn a subprocess. The consumer provides `ChildProcessSpawner` once at
22468
+ * the edge (`@effect/platform-node`'s `NodeServices.layer`); a test
22469
+ * provides `Layer.succeed(Git, …)` and needs no repository on disk.
22470
+ */
22471
+ static layerWithGit = layerWithGit;
22472
+ /**
22473
+ * This package's implementation of `@effected/commands`' `LocalExec`
22474
+ * contract: how to run a project-local binary here.
22475
+ *
22476
+ * @remarks
22477
+ * **An inverted contract, the `@effected/npm` `CatalogResolver`
22478
+ * precedent.** Tool discovery needs package-manager detection and
22479
+ * workspace-root resolution, both of which live here — but a direct edge
22480
+ * from `@effected/commands` to this package would make that boundary-tier
22481
+ * package integrated, and through the planned `npm` → `commands` edge
22482
+ * would drag `npm`, `lockfiles` (pure!) and `package-json` up a tier with
22483
+ * it. So `commands` declares the narrow contract and we ship the layer.
22484
+ *
22485
+ * **The argv knowledge is not duplicated.** `LocalExec.prefixes(name)` is
22486
+ * the one home of the four managers' `exec`/`dlx` prefixes; this layer
22487
+ * detects *which* manager owns the directory and asks `commands` what that
22488
+ * manager's argv looks like. Neither package reimplements the other's
22489
+ * half.
22490
+ *
22491
+ * **`None` is success.** Outside any workspace — and inside one whose
22492
+ * manager cannot be identified — the answer is `Option.none()`: "there is
22493
+ * no project-local way to run tools here" is an ordinary fact, not an
22494
+ * exceptional one, and a consumer running in a bare directory should not
22495
+ * have to catch an error to learn it. The contract's typed
22496
+ * `LocalExecError` is reserved for **mechanism** failure — a manifest that
22497
+ * exists but cannot be read or parsed, which means something is broken
22498
+ * rather than absent. That is npm's resolver convention, adopted
22499
+ * verbatim.
22500
+ *
22501
+ * `directory` is the resolved **workspace root**, not the caller's cwd: a
22502
+ * project-local launcher has to run where the workspace is.
22503
+ *
22504
+ * A consumer with no monorepo never needs this layer, and therefore never
22505
+ * installs this package — `LocalExec.layerNone` and `LocalExec.layerFor`
22506
+ * are one-liners in `@effected/commands`.
22507
+ *
22508
+ * **Bind the result to a `const`** — a parameterized layer factory mints a
22509
+ * fresh reference per call and layers memoize by reference.
22510
+ *
22511
+ * @example
22512
+ * ```ts
22513
+ * import { ToolDiscovery } from "@effected/commands";
22514
+ * import { Workspaces } from "@effected/workspaces";
22515
+ * import { Layer } from "effect";
22516
+ *
22517
+ * const AppLayer = ToolDiscovery.layer.pipe(
22518
+ * Layer.provide(Workspaces.localExecLayer()),
22519
+ * Layer.provide(Workspaces.layer()),
22520
+ * Layer.provide(NodeServices.layer),
22521
+ * );
22522
+ * ```
22523
+ */
22524
+ static localExecLayer = localExecLayer;
22525
+ /**
22526
+ * Resolve every `catalog:` and `workspace:` specifier in one `Manifest`
22527
+ * against the real workspace, in one call — the 90% path. Decode stays at
22528
+ * the consumer's edge: build the `Manifest` with `Manifest.decode` (from
22529
+ * `@effected/npm`), hand it here, and get a new `Manifest` back with
22530
+ * concrete ranges; `toRecord()` returns to the wire shape.
22531
+ *
22532
+ * @remarks
22533
+ * Composes `manifest.resolve()` with a fresh {@link Workspaces.resolverLayer}
22534
+ * per call, so the workspace root is re-discovered from `options.cwd` (or
22535
+ * the current `process.cwd()`) on every invocation. Consumers processing
22536
+ * many manifests should check `manifest.needsResolution` first and skip
22537
+ * the call entirely when no dependency field carries a
22538
+ * `catalog:`/`workspace:` specifier — that predicate is pure and avoids
22539
+ * catalog assembly altogether.
22540
+ *
22541
+ * A specifier the workspace cannot answer fails typed as
22542
+ * `UnresolvedDependencyError`; assembly and mechanism failures surface as
22543
+ * `CatalogAssemblyError` / `DependencyResolutionError`.
22544
+ *
22545
+ * @example
22546
+ * ```ts
22547
+ * import { Manifest } from "@effected/npm";
22548
+ * import { Workspaces } from "@effected/workspaces";
22549
+ * import { Effect } from "effect";
22550
+ *
22551
+ * const program = Effect.gen(function* () {
22552
+ * const manifest = yield* Manifest.decode({ dependencies: { effect: "catalog:" } });
22553
+ * const resolved = manifest.needsResolution ? yield* Workspaces.resolveManifest(manifest) : manifest;
22554
+ * return resolved.toRecord();
22555
+ * });
22556
+ * ```
22557
+ */
22558
+ static resolveManifest = resolveManifest;
22559
+ /**
22560
+ * The one-call resolver factory: {@link Workspaces.resolvers} pre-wired
22561
+ * over {@link Workspaces.layerWithConfigDependencies}, so the two
22562
+ * `@effected/npm` contracts (`CatalogResolver`, `WorkspaceResolver`) need
22563
+ * only a platform (`FileSystem` + `Path`) from the consumer.
22564
+ *
22565
+ * @remarks
22566
+ * This is deliberately a **parameterized layer function, and the fresh
22567
+ * layer per call is the feature**: layers memoize by reference, so each
22568
+ * call mints an unmemoized layer whose root discovery re-runs — including
22569
+ * a per-call `process.cwd()` read when `options.cwd` is omitted. A build
22570
+ * tool that changes directory between manifests gets a correct
22571
+ * re-discovery each time precisely because nothing is shared across
22572
+ * calls. When you *want* sharing, bind one call's result to a `const` and
22573
+ * provide that; the memoization rule is unchanged, this factory just
22574
+ * refuses to hide it.
22575
+ *
22576
+ * Catalog assembly replays config-dependency `pnpmfile` hooks (the
22577
+ * `layerWithConfigDependencies` path) — the semantics a real pnpm install
22578
+ * has. Compose {@link Workspaces.resolvers} with {@link Workspaces.layer}
22579
+ * yourself if config-dependency code must not run in process.
22580
+ *
22581
+ * @example
22582
+ * ```ts
22583
+ * import { Workspaces } from "@effected/workspaces";
22584
+ * import { Effect } from "effect";
22585
+ *
22586
+ * const program = doSomethingWithResolvers.pipe(
22587
+ * Effect.provide(Workspaces.resolverLayer()),
22588
+ * );
22589
+ * ```
22590
+ */
22591
+ static resolverLayer = resolverLayer;
22592
+ /**
22593
+ * The two `@effected/npm` resolver contracts, implemented for real.
22594
+ *
22595
+ * @remarks
22596
+ * Provide this alongside `@effected/package-json`'s `Package.resolve` and
22597
+ * a manifest's `catalog:` and `workspace:` specifiers resolve against the
22598
+ * actual workspace instead of the no-op layers' `Option.none()`.
22599
+ *
22600
+ * @example
22601
+ * ```ts
22602
+ * import { Package } from "@effected/package-json";
22603
+ * import { Workspaces } from "@effected/workspaces";
22604
+ * import { Layer } from "effect";
22605
+ *
22606
+ * const WorkspacesLayer = Workspaces.layer();
22607
+ * const Resolvers = Workspaces.resolvers.pipe(Layer.provide(WorkspacesLayer));
22608
+ * ```
22609
+ */
22610
+ static resolvers = resolvers;
21784
22611
  };
21785
22612
  //#endregion
21786
22613
  //#region ../silk-effects/dist/dev/pkg/services/SilkPublishability.js
@@ -22029,7 +22856,7 @@ effect.Layer.effect(PublishabilityDetector, effect.Effect.gen(function* () {
22029
22856
  const PublishabilityDetectorAdaptiveLive = effect.Layer.effect(PublishabilityDetector, effect.Effect.gen(function* () {
22030
22857
  const fs = yield* effect.FileSystem.FileSystem;
22031
22858
  const config = yield* ChangesetConfig;
22032
- const vanilla = yield* effect.Effect.provide(PublishabilityDetector, PublishabilityDetector.layer);
22859
+ const vanilla = PublishabilityDetector.npm;
22033
22860
  return { detect: (pkg) => effect.Effect.gen(function* () {
22034
22861
  const root = pkg.workspaceRoot;
22035
22862
  if (yield* config.isIgnored(pkg.name, root)) return [];
@@ -22751,7 +23578,6 @@ const MarkdownParseErrorBase = effect.Data.TaggedError("MarkdownParseError");
22751
23578
  * );
22752
23579
  * ```
22753
23580
  *
22754
- * @see {@link MarkdownService} for the Effect service that may produce this error
22755
23581
  *
22756
23582
  * @public
22757
23583
  */
@@ -23943,7 +24769,7 @@ var GitHubService = class extends effect.Context.Service()("GitHubService") {};
23943
24769
  * @remarks
23944
24770
  * This layer is used by the `\@savvy-web/changesets/changelog` entry point
23945
24771
  * to resolve commit hashes into PR numbers and author attribution. It is
23946
- * composed with {@link MarkdownLive} in the changelog formatter's
24772
+ * used by the changelog formatter's
23947
24773
  * `MainLayer`.
23948
24774
  *
23949
24775
  * @example
@@ -24012,6 +24838,277 @@ function makeGitHubTest(responses) {
24012
24838
  } });
24013
24839
  }
24014
24840
  //#endregion
24841
+ //#region ../silk-effects/dist/dev/pkg/changesets/schemas/primitives.js
24842
+ /**
24843
+ * Primitive reusable schemas for common constrained types.
24844
+ *
24845
+ * @remarks
24846
+ * These schemas serve as building blocks for more complex schemas throughout
24847
+ * the \@savvy-web/changesets package. They encode common constraints
24848
+ * (non-empty strings, positive integers) as Effect Schemas so that validation
24849
+ * is enforced at system boundaries.
24850
+ *
24851
+ * @see {@link https://effect.website/docs/schema/introduction | Effect Schema documentation}
24852
+ *
24853
+ */
24854
+ /**
24855
+ * A non-empty string schema.
24856
+ *
24857
+ * @remarks
24858
+ * Validates that a string has at least one character. Used as the base
24859
+ * constraint for package names, dependency identifiers, and other fields
24860
+ * that must not be blank.
24861
+ *
24862
+ * @example
24863
+ * ```typescript
24864
+ * import { Schema } from "effect";
24865
+ * import { NonEmptyString } from "@savvy-web/changesets";
24866
+ *
24867
+ * // Succeeds — non-empty string
24868
+ * const name = Schema.decodeUnknownSync(NonEmptyString)("react");
24869
+ *
24870
+ * // Throws ParseError — empty string
24871
+ * Schema.decodeUnknownSync(NonEmptyString)("");
24872
+ * ```
24873
+ *
24874
+ * @see {@link ChangesetSummarySchema} for a length-bounded variant used for changeset summaries
24875
+ *
24876
+ * @public
24877
+ */
24878
+ const NonEmptyString = effect.Schema.String.check(effect.Schema.isMinLength(1));
24879
+ /**
24880
+ * A positive integer schema.
24881
+ *
24882
+ * @remarks
24883
+ * Validates that a number is both an integer and strictly greater than zero.
24884
+ * Used as the base constraint for GitHub issue numbers and similar
24885
+ * identifiers that must be positive whole numbers.
24886
+ *
24887
+ * @example
24888
+ * ```typescript
24889
+ * import { Schema } from "effect";
24890
+ * import { PositiveInteger } from "@savvy-web/changesets";
24891
+ *
24892
+ * // Succeeds — positive integer
24893
+ * const issueNum = Schema.decodeUnknownSync(PositiveInteger)(42);
24894
+ *
24895
+ * // Throws ParseError — zero is not positive
24896
+ * Schema.decodeUnknownSync(PositiveInteger)(0);
24897
+ *
24898
+ * // Throws ParseError — floats are not integers
24899
+ * Schema.decodeUnknownSync(PositiveInteger)(3.14);
24900
+ * ```
24901
+ *
24902
+ * @see {@link IssueNumberSchema} which builds on this for GitHub issue/PR numbers
24903
+ *
24904
+ * @public
24905
+ */
24906
+ const PositiveInteger = effect.Schema.Number.check(effect.Schema.isInt(), effect.Schema.isGreaterThan(0));
24907
+ //#endregion
24908
+ //#region ../silk-effects/dist/dev/pkg/changesets/schemas/dependency-table.js
24909
+ /**
24910
+ * Effect schemas for structured dependency table entries.
24911
+ *
24912
+ * @remarks
24913
+ * These schemas define the canonical representation for dependency
24914
+ * changes tracked as markdown tables in changeset files and CHANGELOGs.
24915
+ * The table format provides a richer view than {@link DependencyUpdateSchema}
24916
+ * by supporting singular dependency type names, workspace/config types,
24917
+ * and explicit add/update/remove actions.
24918
+ *
24919
+ * A dependency table row looks like this in a CHANGELOG:
24920
+ *
24921
+ * | Dependency | Type | Action | From | To |
24922
+ * |---|---|---|---|---|
24923
+ * | effect | dependency | updated | 3.18.0 | 3.19.1 |
24924
+ *
24925
+ * @see {@link DependencyUpdateSchema} for the simpler Changesets API format
24926
+ * @see {@link https://effect.website/docs/schema/introduction | Effect Schema documentation}
24927
+ *
24928
+ */
24929
+ /**
24930
+ * Valid dependency table actions.
24931
+ *
24932
+ * @remarks
24933
+ * Represents the three possible operations on a dependency: `"added"` for
24934
+ * new dependencies, `"updated"` for version changes, and `"removed"` for
24935
+ * deletions. Used in the "Action" column of dependency tables.
24936
+ *
24937
+ * @example
24938
+ * ```typescript
24939
+ * import { Schema } from "effect";
24940
+ * import { DependencyActionSchema } from "@savvy-web/changesets";
24941
+ * import type { DependencyAction } from "@savvy-web/changesets";
24942
+ *
24943
+ * const action: DependencyAction = Schema.decodeUnknownSync(DependencyActionSchema)("updated");
24944
+ * ```
24945
+ *
24946
+ * @public
24947
+ */
24948
+ const DependencyActionSchema = effect.Schema.Literals([
24949
+ "added",
24950
+ "updated",
24951
+ "removed"
24952
+ ]);
24953
+ /**
24954
+ * Extended dependency types for table format.
24955
+ *
24956
+ * @remarks
24957
+ * Unlike {@link DependencyTypeSchema} (which uses plural npm field names like
24958
+ * `"dependencies"`), this schema uses singular forms (`"dependency"`) and adds
24959
+ * two additional types: `"workspace"` for monorepo workspace references and
24960
+ * `"config"` for configuration toolchain updates (e.g., ESLint, TypeScript).
24961
+ *
24962
+ * @example
24963
+ * ```typescript
24964
+ * import { Schema } from "effect";
24965
+ * import { DependencyTableTypeSchema } from "@savvy-web/changesets";
24966
+ * import type { DependencyTableType } from "@savvy-web/changesets";
24967
+ *
24968
+ * const tableType: DependencyTableType = Schema.decodeUnknownSync(
24969
+ * DependencyTableTypeSchema
24970
+ * )("workspace");
24971
+ * ```
24972
+ *
24973
+ * @see {@link DependencyTypeSchema} for the plural npm-field variant
24974
+ *
24975
+ * @public
24976
+ */
24977
+ const DependencyTableTypeSchema = effect.Schema.Literals([
24978
+ "dependency",
24979
+ "devDependency",
24980
+ "peerDependency",
24981
+ "optionalDependency",
24982
+ "workspace",
24983
+ "config"
24984
+ ]);
24985
+ /**
24986
+ * The canonical accepted-value pattern for a dependency-table From/To cell:
24987
+ * the em-dash sentinel (U+2014), a bare/`~`/`^` semver, or — as a last-resort
24988
+ * fallback when a `catalog:`/`workspace:` specifier could not be resolved to a
24989
+ * concrete version — a pnpm protocol string. Non-overlapping alternatives keep
24990
+ * this free of polynomial backtracking (CodeQL).
24991
+ *
24992
+ * @public
24993
+ */
24994
+ const VERSION_RE = /^(\u2014|[~^]?\d+\.\d+\.\d+(?:[-+.][\w.+-]+)?|(?:catalog|workspace|npm|jsr|file|link|portal):[^\s|]+)$/;
24995
+ /**
24996
+ * Version string or em dash (U+2014) sentinel for added/removed entries.
24997
+ *
24998
+ * @remarks
24999
+ * Accepts either a semver-like version string (with optional `~` or `^`
25000
+ * prefix and pre-release/build suffixes) or the em dash character `\u2014`
25001
+ * which serves as a sentinel: the "From" column uses `\u2014` for newly
25002
+ * added dependencies, and the "To" column uses it for removed ones.
25003
+ *
25004
+ * @example
25005
+ * ```typescript
25006
+ * import { Schema } from "effect";
25007
+ * import { VersionOrEmptySchema } from "@savvy-web/changesets";
25008
+ *
25009
+ * // Succeeds — semver version
25010
+ * Schema.decodeUnknownSync(VersionOrEmptySchema)("^3.19.1");
25011
+ *
25012
+ * // Succeeds — em dash sentinel for "no version"
25013
+ * Schema.decodeUnknownSync(VersionOrEmptySchema)("\u2014");
25014
+ *
25015
+ * // Throws ParseError — arbitrary text
25016
+ * Schema.decodeUnknownSync(VersionOrEmptySchema)("latest");
25017
+ * ```
25018
+ *
25019
+ * @public
25020
+ */
25021
+ const VersionOrEmptySchema = effect.Schema.String.check(effect.Schema.isPattern(VERSION_RE));
25022
+ /**
25023
+ * Schema for a single dependency table row.
25024
+ *
25025
+ * @remarks
25026
+ * Represents one row of a dependency update table in a CHANGELOG.
25027
+ * Each row captures the dependency name, its type, the change action,
25028
+ * and the "from" and "to" version strings. For added dependencies the
25029
+ * `from` field is an em dash; for removed dependencies the `to` field
25030
+ * is an em dash.
25031
+ *
25032
+ * @example
25033
+ * ```typescript
25034
+ * import { Schema } from "effect";
25035
+ * import { DependencyTableRowSchema } from "@savvy-web/changesets";
25036
+ * import type { DependencyTableRow } from "@savvy-web/changesets";
25037
+ *
25038
+ * const row: DependencyTableRow = Schema.decodeUnknownSync(DependencyTableRowSchema)({
25039
+ * dependency: "effect",
25040
+ * type: "dependency",
25041
+ * action: "updated",
25042
+ * from: "3.18.0",
25043
+ * to: "3.19.1",
25044
+ * });
25045
+ *
25046
+ * // Newly added dependency — "from" is em dash
25047
+ * const addedRow: DependencyTableRow = Schema.decodeUnknownSync(DependencyTableRowSchema)({
25048
+ * dependency: "@effect/cli",
25049
+ * type: "dependency",
25050
+ * action: "added",
25051
+ * from: "\u2014",
25052
+ * to: "0.50.0",
25053
+ * });
25054
+ * ```
25055
+ *
25056
+ * @see {@link DependencyTableRow} for the inferred TypeScript type
25057
+ * @see {@link DependencyTableSchema} for a non-empty array of rows
25058
+ *
25059
+ * @public
25060
+ */
25061
+ const DependencyTableRowSchema = effect.Schema.Struct({
25062
+ /** Package or toolchain name. */
25063
+ dependency: NonEmptyString,
25064
+ /** Dependency type. */
25065
+ type: DependencyTableTypeSchema,
25066
+ /** Change action. */
25067
+ action: DependencyActionSchema,
25068
+ /** Previous version (em dash for added). */
25069
+ from: VersionOrEmptySchema,
25070
+ /** New version (em dash for removed). */
25071
+ to: VersionOrEmptySchema
25072
+ });
25073
+ /**
25074
+ * Schema for a dependency table (non-empty array of rows).
25075
+ *
25076
+ * @remarks
25077
+ * Validates that the table contains at least one row. Used to represent
25078
+ * the full dependency update table in a changeset or CHANGELOG entry.
25079
+ *
25080
+ * @example
25081
+ * ```typescript
25082
+ * import { Schema } from "effect";
25083
+ * import { DependencyTableSchema } from "@savvy-web/changesets";
25084
+ *
25085
+ * const table = Schema.decodeUnknownSync(DependencyTableSchema)([
25086
+ * {
25087
+ * dependency: "effect",
25088
+ * type: "dependency",
25089
+ * action: "updated",
25090
+ * from: "3.18.0",
25091
+ * to: "3.19.1",
25092
+ * },
25093
+ * {
25094
+ * dependency: "typescript",
25095
+ * type: "config",
25096
+ * action: "updated",
25097
+ * from: "5.6.0",
25098
+ * to: "5.7.2",
25099
+ * },
25100
+ * ]);
25101
+ *
25102
+ * // Throws ParseError — empty array
25103
+ * Schema.decodeUnknownSync(DependencyTableSchema)([]);
25104
+ * ```
25105
+ *
25106
+ * @see {@link DependencyTableRowSchema} for the individual row schema
25107
+ *
25108
+ * @public
25109
+ */
25110
+ const DependencyTableSchema = effect.Schema.Array(DependencyTableRowSchema).check(effect.Schema.isMinLength(1));
25111
+ //#endregion
24015
25112
  //#region ../../node_modules/.pnpm/ccount@2.0.1/node_modules/ccount/index.js
24016
25113
  /**
24017
25114
  * Count how often a character (or substring) is used in a string.
@@ -43481,365 +44578,6 @@ function stringifyMarkdown(tree) {
43481
44578
  return createRemarkProcessor().stringify(tree);
43482
44579
  }
43483
44580
  //#endregion
43484
- //#region ../silk-effects/dist/dev/pkg/changesets/services/markdown.js
43485
- /**
43486
- * Markdown service for parsing and stringifying mdast trees.
43487
- *
43488
- * Defines the {@link MarkdownService} Effect service tag and the
43489
- * {@link MarkdownLive | production layer} backed by the remark/unified
43490
- * pipeline. This service provides a pure, side-effect-free interface to
43491
- * markdown parsing and stringification used throughout the changelog
43492
- * formatter and remark transform pipeline.
43493
- *
43494
- * @remarks
43495
- * The service wraps the `remark-pipeline` utility functions (`parseMarkdown`
43496
- * and `stringifyMarkdown`) behind an Effect interface. The `parse` operation
43497
- * returns an mdast `Root` node; the `stringify` operation serializes an
43498
- * mdast `Root` back to a markdown string. Both operations are synchronous
43499
- * under the hood but are lifted into `Effect.sync` for composability.
43500
- *
43501
- * @see {@link MarkdownService} for the Effect service tag
43502
- * @see {@link MarkdownServiceShape} for the service interface
43503
- * @see {@link MarkdownLive} for the production layer
43504
- */
43505
- /**
43506
- * Effect service tag for markdown parsing and stringification.
43507
- *
43508
- * Provides dependency-injected access to markdown parse/stringify operations.
43509
- * Use `yield* MarkdownService` inside an `Effect.gen` block to obtain the
43510
- * service instance.
43511
- *
43512
- * @remarks
43513
- * This tag follows the standard Effect `Context.Service` pattern. The
43514
- * {@link MarkdownLive} layer provides the default implementation backed by
43515
- * the remark/unified pipeline. For testing, you can supply a custom layer
43516
- * via `Layer.succeed(MarkdownService, { parse: ..., stringify: ... })`.
43517
- *
43518
- * @example
43519
- * ```typescript
43520
- * import { Effect } from "effect";
43521
- * import { MarkdownService, MarkdownLive } from "\@savvy-web/changesets";
43522
- *
43523
- * const program = Effect.gen(function* () {
43524
- * const md = yield* MarkdownService;
43525
- * const tree = yield* md.parse("# Hello\n\nWorld");
43526
- * const output = yield* md.stringify(tree);
43527
- * console.log(output); // "# Hello\n\nWorld\n"
43528
- * });
43529
- *
43530
- * Effect.runPromise(program.pipe(Effect.provide(MarkdownLive)));
43531
- * ```
43532
- *
43533
- * @see {@link MarkdownServiceShape} for the service interface
43534
- * @see {@link MarkdownLive} for the production layer
43535
- *
43536
- * @public
43537
- */
43538
- var MarkdownService = class extends effect.Context.Service()("MarkdownService") {};
43539
- /**
43540
- * Production layer for {@link MarkdownService}.
43541
- *
43542
- * Wraps the remark-pipeline utility functions (`parseMarkdown` and
43543
- * `stringifyMarkdown`) in `Effect.sync` for use in Effect programs.
43544
- * Both operations are synchronous and infallible.
43545
- *
43546
- * @remarks
43547
- * This layer is composed with {@link GitHubLive} in the
43548
- * `\@savvy-web/changesets/changelog` entry point to form the `MainLayer`
43549
- * that powers the Changesets API integration.
43550
- *
43551
- * @example
43552
- * ```typescript
43553
- * import { Effect, Layer } from "effect";
43554
- * import { MarkdownService, MarkdownLive } from "\@savvy-web/changesets";
43555
- *
43556
- * const program = Effect.gen(function* () {
43557
- * const md = yield* MarkdownService;
43558
- * const tree = yield* md.parse("**bold** text");
43559
- * return yield* md.stringify(tree);
43560
- * });
43561
- *
43562
- * Effect.runPromise(program.pipe(Effect.provide(MarkdownLive)));
43563
- * ```
43564
- *
43565
- * @public
43566
- */
43567
- const MarkdownLive = effect.Layer.succeed(MarkdownService, {
43568
- parse: (content) => effect.Effect.sync(() => parseMarkdown(content)),
43569
- stringify: (tree) => effect.Effect.sync(() => stringifyMarkdown(tree))
43570
- });
43571
- //#endregion
43572
- //#region ../silk-effects/dist/dev/pkg/changesets/schemas/primitives.js
43573
- /**
43574
- * Primitive reusable schemas for common constrained types.
43575
- *
43576
- * @remarks
43577
- * These schemas serve as building blocks for more complex schemas throughout
43578
- * the \@savvy-web/changesets package. They encode common constraints
43579
- * (non-empty strings, positive integers) as Effect Schemas so that validation
43580
- * is enforced at system boundaries.
43581
- *
43582
- * @see {@link https://effect.website/docs/schema/introduction | Effect Schema documentation}
43583
- *
43584
- */
43585
- /**
43586
- * A non-empty string schema.
43587
- *
43588
- * @remarks
43589
- * Validates that a string has at least one character. Used as the base
43590
- * constraint for package names, dependency identifiers, and other fields
43591
- * that must not be blank.
43592
- *
43593
- * @example
43594
- * ```typescript
43595
- * import { Schema } from "effect";
43596
- * import { NonEmptyString } from "@savvy-web/changesets";
43597
- *
43598
- * // Succeeds — non-empty string
43599
- * const name = Schema.decodeUnknownSync(NonEmptyString)("react");
43600
- *
43601
- * // Throws ParseError — empty string
43602
- * Schema.decodeUnknownSync(NonEmptyString)("");
43603
- * ```
43604
- *
43605
- * @see {@link ChangesetSummarySchema} for a length-bounded variant used for changeset summaries
43606
- *
43607
- * @public
43608
- */
43609
- const NonEmptyString = effect.Schema.String.check(effect.Schema.isMinLength(1));
43610
- /**
43611
- * A positive integer schema.
43612
- *
43613
- * @remarks
43614
- * Validates that a number is both an integer and strictly greater than zero.
43615
- * Used as the base constraint for GitHub issue numbers and similar
43616
- * identifiers that must be positive whole numbers.
43617
- *
43618
- * @example
43619
- * ```typescript
43620
- * import { Schema } from "effect";
43621
- * import { PositiveInteger } from "@savvy-web/changesets";
43622
- *
43623
- * // Succeeds — positive integer
43624
- * const issueNum = Schema.decodeUnknownSync(PositiveInteger)(42);
43625
- *
43626
- * // Throws ParseError — zero is not positive
43627
- * Schema.decodeUnknownSync(PositiveInteger)(0);
43628
- *
43629
- * // Throws ParseError — floats are not integers
43630
- * Schema.decodeUnknownSync(PositiveInteger)(3.14);
43631
- * ```
43632
- *
43633
- * @see {@link IssueNumberSchema} which builds on this for GitHub issue/PR numbers
43634
- *
43635
- * @public
43636
- */
43637
- const PositiveInteger = effect.Schema.Number.check(effect.Schema.isInt(), effect.Schema.isGreaterThan(0));
43638
- //#endregion
43639
- //#region ../silk-effects/dist/dev/pkg/changesets/schemas/dependency-table.js
43640
- /**
43641
- * Effect schemas for structured dependency table entries.
43642
- *
43643
- * @remarks
43644
- * These schemas define the canonical representation for dependency
43645
- * changes tracked as markdown tables in changeset files and CHANGELOGs.
43646
- * The table format provides a richer view than {@link DependencyUpdateSchema}
43647
- * by supporting singular dependency type names, workspace/config types,
43648
- * and explicit add/update/remove actions.
43649
- *
43650
- * A dependency table row looks like this in a CHANGELOG:
43651
- *
43652
- * | Dependency | Type | Action | From | To |
43653
- * |---|---|---|---|---|
43654
- * | effect | dependency | updated | 3.18.0 | 3.19.1 |
43655
- *
43656
- * @see {@link DependencyUpdateSchema} for the simpler Changesets API format
43657
- * @see {@link https://effect.website/docs/schema/introduction | Effect Schema documentation}
43658
- *
43659
- */
43660
- /**
43661
- * Valid dependency table actions.
43662
- *
43663
- * @remarks
43664
- * Represents the three possible operations on a dependency: `"added"` for
43665
- * new dependencies, `"updated"` for version changes, and `"removed"` for
43666
- * deletions. Used in the "Action" column of dependency tables.
43667
- *
43668
- * @example
43669
- * ```typescript
43670
- * import { Schema } from "effect";
43671
- * import { DependencyActionSchema } from "@savvy-web/changesets";
43672
- * import type { DependencyAction } from "@savvy-web/changesets";
43673
- *
43674
- * const action: DependencyAction = Schema.decodeUnknownSync(DependencyActionSchema)("updated");
43675
- * ```
43676
- *
43677
- * @public
43678
- */
43679
- const DependencyActionSchema = effect.Schema.Literals([
43680
- "added",
43681
- "updated",
43682
- "removed"
43683
- ]);
43684
- /**
43685
- * Extended dependency types for table format.
43686
- *
43687
- * @remarks
43688
- * Unlike {@link DependencyTypeSchema} (which uses plural npm field names like
43689
- * `"dependencies"`), this schema uses singular forms (`"dependency"`) and adds
43690
- * two additional types: `"workspace"` for monorepo workspace references and
43691
- * `"config"` for configuration toolchain updates (e.g., ESLint, TypeScript).
43692
- *
43693
- * @example
43694
- * ```typescript
43695
- * import { Schema } from "effect";
43696
- * import { DependencyTableTypeSchema } from "@savvy-web/changesets";
43697
- * import type { DependencyTableType } from "@savvy-web/changesets";
43698
- *
43699
- * const tableType: DependencyTableType = Schema.decodeUnknownSync(
43700
- * DependencyTableTypeSchema
43701
- * )("workspace");
43702
- * ```
43703
- *
43704
- * @see {@link DependencyTypeSchema} for the plural npm-field variant
43705
- *
43706
- * @public
43707
- */
43708
- const DependencyTableTypeSchema = effect.Schema.Literals([
43709
- "dependency",
43710
- "devDependency",
43711
- "peerDependency",
43712
- "optionalDependency",
43713
- "workspace",
43714
- "config"
43715
- ]);
43716
- /**
43717
- * The canonical accepted-value pattern for a dependency-table From/To cell:
43718
- * the em-dash sentinel (U+2014), a bare/`~`/`^` semver, or — as a last-resort
43719
- * fallback when a `catalog:`/`workspace:` specifier could not be resolved to a
43720
- * concrete version — a pnpm protocol string. Non-overlapping alternatives keep
43721
- * this free of polynomial backtracking (CodeQL).
43722
- *
43723
- * @public
43724
- */
43725
- const VERSION_RE = /^(\u2014|[~^]?\d+\.\d+\.\d+(?:[-+.][\w.+-]+)?|(?:catalog|workspace|npm|jsr|file|link|portal):[^\s|]+)$/;
43726
- /**
43727
- * Version string or em dash (U+2014) sentinel for added/removed entries.
43728
- *
43729
- * @remarks
43730
- * Accepts either a semver-like version string (with optional `~` or `^`
43731
- * prefix and pre-release/build suffixes) or the em dash character `\u2014`
43732
- * which serves as a sentinel: the "From" column uses `\u2014` for newly
43733
- * added dependencies, and the "To" column uses it for removed ones.
43734
- *
43735
- * @example
43736
- * ```typescript
43737
- * import { Schema } from "effect";
43738
- * import { VersionOrEmptySchema } from "@savvy-web/changesets";
43739
- *
43740
- * // Succeeds — semver version
43741
- * Schema.decodeUnknownSync(VersionOrEmptySchema)("^3.19.1");
43742
- *
43743
- * // Succeeds — em dash sentinel for "no version"
43744
- * Schema.decodeUnknownSync(VersionOrEmptySchema)("\u2014");
43745
- *
43746
- * // Throws ParseError — arbitrary text
43747
- * Schema.decodeUnknownSync(VersionOrEmptySchema)("latest");
43748
- * ```
43749
- *
43750
- * @public
43751
- */
43752
- const VersionOrEmptySchema = effect.Schema.String.check(effect.Schema.isPattern(VERSION_RE));
43753
- /**
43754
- * Schema for a single dependency table row.
43755
- *
43756
- * @remarks
43757
- * Represents one row of a dependency update table in a CHANGELOG.
43758
- * Each row captures the dependency name, its type, the change action,
43759
- * and the "from" and "to" version strings. For added dependencies the
43760
- * `from` field is an em dash; for removed dependencies the `to` field
43761
- * is an em dash.
43762
- *
43763
- * @example
43764
- * ```typescript
43765
- * import { Schema } from "effect";
43766
- * import { DependencyTableRowSchema } from "@savvy-web/changesets";
43767
- * import type { DependencyTableRow } from "@savvy-web/changesets";
43768
- *
43769
- * const row: DependencyTableRow = Schema.decodeUnknownSync(DependencyTableRowSchema)({
43770
- * dependency: "effect",
43771
- * type: "dependency",
43772
- * action: "updated",
43773
- * from: "3.18.0",
43774
- * to: "3.19.1",
43775
- * });
43776
- *
43777
- * // Newly added dependency — "from" is em dash
43778
- * const addedRow: DependencyTableRow = Schema.decodeUnknownSync(DependencyTableRowSchema)({
43779
- * dependency: "@effect/cli",
43780
- * type: "dependency",
43781
- * action: "added",
43782
- * from: "\u2014",
43783
- * to: "0.50.0",
43784
- * });
43785
- * ```
43786
- *
43787
- * @see {@link DependencyTableRow} for the inferred TypeScript type
43788
- * @see {@link DependencyTableSchema} for a non-empty array of rows
43789
- *
43790
- * @public
43791
- */
43792
- const DependencyTableRowSchema = effect.Schema.Struct({
43793
- /** Package or toolchain name. */
43794
- dependency: NonEmptyString,
43795
- /** Dependency type. */
43796
- type: DependencyTableTypeSchema,
43797
- /** Change action. */
43798
- action: DependencyActionSchema,
43799
- /** Previous version (em dash for added). */
43800
- from: VersionOrEmptySchema,
43801
- /** New version (em dash for removed). */
43802
- to: VersionOrEmptySchema
43803
- });
43804
- /**
43805
- * Schema for a dependency table (non-empty array of rows).
43806
- *
43807
- * @remarks
43808
- * Validates that the table contains at least one row. Used to represent
43809
- * the full dependency update table in a changeset or CHANGELOG entry.
43810
- *
43811
- * @example
43812
- * ```typescript
43813
- * import { Schema } from "effect";
43814
- * import { DependencyTableSchema } from "@savvy-web/changesets";
43815
- *
43816
- * const table = Schema.decodeUnknownSync(DependencyTableSchema)([
43817
- * {
43818
- * dependency: "effect",
43819
- * type: "dependency",
43820
- * action: "updated",
43821
- * from: "3.18.0",
43822
- * to: "3.19.1",
43823
- * },
43824
- * {
43825
- * dependency: "typescript",
43826
- * type: "config",
43827
- * action: "updated",
43828
- * from: "5.6.0",
43829
- * to: "5.7.2",
43830
- * },
43831
- * ]);
43832
- *
43833
- * // Throws ParseError — empty array
43834
- * Schema.decodeUnknownSync(DependencyTableSchema)([]);
43835
- * ```
43836
- *
43837
- * @see {@link DependencyTableRowSchema} for the individual row schema
43838
- *
43839
- * @public
43840
- */
43841
- const DependencyTableSchema = effect.Schema.Array(DependencyTableRowSchema).check(effect.Schema.isMinLength(1));
43842
- //#endregion
43843
44581
  //#region ../silk-effects/dist/dev/pkg/changesets/utils/dependency-table.js
43844
44582
  /**
43845
44583
  * Dependency table utilities for parsing, serializing, collapsing, and sorting
@@ -45001,8 +45739,7 @@ function getReleaseLine(changeset, versionType, options) {
45001
45739
  * @remarks
45002
45740
  * The module composes two Effect programs — {@link getReleaseLine} and
45003
45741
  * {@link getDependencyReleaseLine} — and runs each through
45004
- * `Effect.runPromise` with a merged layer of {@link GitHubLive} (for commit
45005
- * metadata) and {@link MarkdownLive} (for mdast parsing). Options are
45742
+ * `Effect.runPromise` with {@link GitHubLive} (for commit metadata). Options are
45006
45743
  * validated at the boundary via `validateChangesetOptions` before being
45007
45744
  * passed to the formatters.
45008
45745
  *
@@ -45042,16 +45779,16 @@ function getReleaseLine(changeset, versionType, options) {
45042
45779
  * @see {@link getDependencyReleaseLine} in `./getDependencyReleaseLine.ts` for dependency table formatting
45043
45780
  */
45044
45781
  /**
45045
- * Combined layer providing all services needed by the formatters.
45782
+ * The layer providing every service the formatters need.
45046
45783
  *
45047
- * Merges {@link GitHubLive} and {@link MarkdownLive} into a single layer
45048
- * that satisfies the environment requirements of both `getReleaseLine`
45049
- * (which needs `GitHubService` and `MarkdownService`) and
45050
- * `getDependencyReleaseLine` (which needs `GitHubService`).
45784
+ * {@link GitHubLive} satisfies the requirements of both `getReleaseLine` and
45785
+ * `getDependencyReleaseLine`, which each need only `GitHubService`. Markdown
45786
+ * parsing is not a layer: the formatters call the remark pipeline's
45787
+ * `parseMarkdown` / `stringifyMarkdown` functions directly.
45051
45788
  *
45052
45789
  * @internal
45053
45790
  */
45054
- const MainLayer = effect.Layer.mergeAll(GitHubLive, MarkdownLive);
45791
+ const MainLayer = GitHubLive;
45055
45792
  /**
45056
45793
  * Changesets API `ChangelogFunctions` implementation.
45057
45794
  *
@@ -45092,8 +45829,7 @@ const changelogFunctions = {
45092
45829
  * Delegates to the Changesets-compatible `getReleaseLine` and
45093
45830
  * `getDependencyReleaseLine` functions. Internally, these use the
45094
45831
  * {@link ChangelogService} Effect service layer, which coordinates
45095
- * the {@link GitHubService} (for commit/PR metadata) and
45096
- * {@link MarkdownService} (for AST manipulation) to produce
45832
+ * the {@link GitHubService} (for commit/PR metadata) to produce
45097
45833
  * structured changelog entries.
45098
45834
  *
45099
45835
  * @remarks
@@ -46783,20 +47519,25 @@ function readRawPackageJson(fs, pkgDir) {
46783
47519
  }
46784
47520
  /**
46785
47521
  * Build resolved scopes from the discovered workspace packages, keeping only
46786
- * those that are a release surface (declare publishConfig that yields at least
46787
- * one publish target). Used both when `.changeset/config.json` declares no
46788
- * explicit `packages` record AND to augment an explicit record with the
46789
- * remaining workspace packages it does not list (so the record annotates the
46790
- * listed packages without shrinking the release surface). The changeset
46791
- * `ignore` list is intentionally NOT consulted here an ignored package still
46792
- * declares publishConfig and remains a valid changeset target.
46793
- */
46794
- function buildFallbackScopes(fs, workspaces) {
47522
+ * those that are a release surface: a package that declares publishConfig
47523
+ * yielding at least one publish target, OR when the changeset config sets
47524
+ * `privatePackages.version: true` (`versionPrivate`) any workspace package
47525
+ * at all, since changesets versions private packages too in that mode (#360:
47526
+ * a private single-root repo with `privatePackages.version: true` previously
47527
+ * produced an empty release surface and left every file unmapped). Used both
47528
+ * when `.changeset/config.json` declares no explicit `packages` record AND to
47529
+ * augment an explicit record with the remaining workspace packages it does
47530
+ * not list (so the record annotates the listed packages without shrinking the
47531
+ * release surface). The changeset `ignore` list is intentionally NOT
47532
+ * consulted here — an ignored package still declares publishConfig and
47533
+ * remains a valid changeset target.
47534
+ */
47535
+ function buildFallbackScopes(fs, workspaces, versionPrivate) {
46795
47536
  return effect.Effect.forEach(workspaces, (ws) => effect.Effect.gen(function* () {
46796
47537
  const raw = yield* readRawPackageJson(fs, ws.path);
46797
47538
  if (raw === null) return [];
46798
47539
  const binding = yield* readTargetsBinding(fs, ws.path);
46799
- if (SilkPublishability.detect(ws.name, raw, binding).length === 0) return [];
47540
+ if (SilkPublishability.detect(ws.name, raw, binding).length === 0 && !versionPrivate) return [];
46800
47541
  return [{
46801
47542
  name: ws.name,
46802
47543
  workspaceDir: ws.path,
@@ -46902,6 +47643,8 @@ function makeShape$3(reader, discovery, fs) {
46902
47643
  version: w.version
46903
47644
  }));
46904
47645
  const hasExplicitPackages = Object.keys(decodedOptions.packages ?? {}).length > 0;
47646
+ const privatePackages = config.privatePackages;
47647
+ const versionPrivate = privatePackages !== void 0 && privatePackages !== false && privatePackages.version === true;
46905
47648
  let scopes;
46906
47649
  if (hasExplicitPackages) {
46907
47650
  const explicitScopes = yield* buildResolvedScopes({
@@ -46917,9 +47660,9 @@ function makeShape$3(reader, discovery, fs) {
46917
47660
  throw e;
46918
47661
  }
46919
47662
  const explicitNames = new Set(explicitScopes.map((s) => s.name));
46920
- const discoveredScopes = yield* buildFallbackScopes(fs, workspaces.filter((w) => !explicitNames.has(w.name)));
47663
+ const discoveredScopes = yield* buildFallbackScopes(fs, workspaces.filter((w) => !explicitNames.has(w.name)), versionPrivate);
46921
47664
  scopes = [...explicitScopes, ...discoveredScopes];
46922
- } else scopes = yield* buildFallbackScopes(fs, workspaces);
47665
+ } else scopes = yield* buildFallbackScopes(fs, workspaces, versionPrivate);
46923
47666
  const inspected = {
46924
47667
  configPath,
46925
47668
  projectDir,
@@ -46953,12 +47696,19 @@ function makeShape$3(reader, discovery, fs) {
46953
47696
  function classifyOne(inspected, path) {
46954
47697
  const abs = (0, node_path.resolve)(inspected.projectDir, path);
46955
47698
  let bestWorkspace = null;
46956
- for (const s of inspected.packages) if (isInside(s.workspaceDir, abs)) {
46957
- const depth = s.workspaceDir.length;
46958
- if (!bestWorkspace || depth > bestWorkspace.depth) bestWorkspace = {
46959
- pkg: s.name,
46960
- depth
46961
- };
47699
+ let rootScope = null;
47700
+ for (const s of inspected.packages) {
47701
+ if (s.workspaceDir === inspected.projectDir) {
47702
+ rootScope = s.name;
47703
+ continue;
47704
+ }
47705
+ if (isInside(s.workspaceDir, abs)) {
47706
+ const depth = s.workspaceDir.length;
47707
+ if (!bestWorkspace || depth > bestWorkspace.depth) bestWorkspace = {
47708
+ pkg: s.name,
47709
+ depth
47710
+ };
47711
+ }
46962
47712
  }
46963
47713
  if (bestWorkspace) return {
46964
47714
  path,
@@ -46985,6 +47735,11 @@ function classifyOne(inspected, path) {
46985
47735
  glob: vf.glob
46986
47736
  }
46987
47737
  };
47738
+ if (rootScope && isInside(inspected.projectDir, abs)) return {
47739
+ path,
47740
+ package: rootScope,
47741
+ reason: "workspace"
47742
+ };
46988
47743
  return {
46989
47744
  path,
46990
47745
  package: null,
@@ -47196,7 +47951,7 @@ function makeBranchAnalyzerTest(fixed) {
47196
47951
  * ```typescript
47197
47952
  * import { Effect } from "effect";
47198
47953
  * import type { ChangesetOptions } from "\@savvy-web/changesets";
47199
- * import { ChangelogService, GitHubLive, MarkdownLive } from "\@savvy-web/changesets";
47954
+ * import { ChangelogService, GitHubLive } from "\@savvy-web/changesets";
47200
47955
  *
47201
47956
  * const program = Effect.gen(function* () {
47202
47957
  * const changelog = yield* ChangelogService;
@@ -65995,9 +66750,7 @@ var changesets_exports = /* @__PURE__ */ __exportAll({
65995
66750
  MaintenanceNotePlugin: () => MaintenanceNotePlugin,
65996
66751
  MaintenanceReasonSchema: () => MaintenanceReasonSchema,
65997
66752
  MaintenanceTriggerSchema: () => MaintenanceTriggerSchema,
65998
- MarkdownLive: () => MarkdownLive,
65999
66753
  MarkdownParseError: () => MarkdownParseError,
66000
- MarkdownService: () => MarkdownService,
66001
66754
  MarkdownlintContentStructureRule: () => ContentStructureRule$1,
66002
66755
  MarkdownlintDependencyTableFormatRule: () => DependencyTableFormatRule$1,
66003
66756
  MarkdownlintHeadingHierarchyRule: () => HeadingHierarchyRule$1,