@savvy-web/silk 3.7.12 → 3.8.1

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.
@@ -2353,7 +2353,7 @@ var GlobSet = class GlobSet extends Schema.Class("GlobSet")(Schema.Struct({ patt
2353
2353
  };
2354
2354
 
2355
2355
  //#endregion
2356
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.5.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_d53253b32eb6a388ea04dc81d5e132f1/node_modules/@effected/lockfiles/BunExtension.js
2356
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.6.0_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_060c8bbc0d868c806eb6e32fbf3c19ea/node_modules/@effected/lockfiles/BunExtension.js
2357
2357
  /**
2358
2358
  * Extension data specific to bun lockfiles, attached to `Lockfile.extension`
2359
2359
  * when the format is `"bun"`.
@@ -5621,7 +5621,7 @@ var ReleaseAgeGate = class ReleaseAgeGate extends Schema.Class("ReleaseAgeGate")
5621
5621
  };
5622
5622
 
5623
5623
  //#endregion
5624
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.5.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_d53253b32eb6a388ea04dc81d5e132f1/node_modules/@effected/lockfiles/ImporterDependency.js
5624
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.6.0_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_060c8bbc0d868c806eb6e32fbf3c19ea/node_modules/@effected/lockfiles/ImporterDependency.js
5625
5625
  /**
5626
5626
  * One declared dependency of one workspace importer, as the lockfile records it.
5627
5627
  *
@@ -5660,7 +5660,7 @@ var ImporterDependency = class extends Schema.Class("ImporterDependency")({
5660
5660
  }) {};
5661
5661
 
5662
5662
  //#endregion
5663
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.5.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_d53253b32eb6a388ea04dc81d5e132f1/node_modules/@effected/lockfiles/LockfileImporter.js
5663
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.6.0_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_060c8bbc0d868c806eb6e32fbf3c19ea/node_modules/@effected/lockfiles/LockfileImporter.js
5664
5664
  /**
5665
5665
  * One workspace importer's declared dependencies, as the lockfile records them.
5666
5666
  *
@@ -5685,14 +5685,23 @@ var LockfileImporter = class extends Schema.Class("LockfileImporter")({
5685
5685
  }) {};
5686
5686
 
5687
5687
  //#endregion
5688
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.5.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_d53253b32eb6a388ea04dc81d5e132f1/node_modules/@effected/lockfiles/ResolvedPackage.js
5688
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.6.0_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_060c8bbc0d868c806eb6e32fbf3c19ea/node_modules/@effected/lockfiles/ResolvedPackage.js
5689
5689
  const EMPTY_DEPENDENCIES = {};
5690
+ const EMPTY_PEER_META = {};
5691
+ const EMPTY_EDGE_NAMES = [];
5690
5692
  /**
5691
5693
  * A package resolved from a lockfile.
5692
5694
  *
5693
5695
  * @remarks
5694
5696
  * The common shape every format's entries normalize into:
5695
5697
  *
5698
+ * - `instanceId` — the lockfile-native identity of this *instance*, verbatim:
5699
+ * pnpm's snapshot key (`react-dom@18.3.1(react@17.0.2)`), npm's full entry
5700
+ * key (`node_modules/express/node_modules/debug`), bun's `packages` key
5701
+ * (`@acme/lib/react-dom`) or yarn's locator (`react-dom@npm:18.3.1`). It is
5702
+ * **opaque** — no scheme is synthesized and none should be parsed by a
5703
+ * consumer; it exists so `resolved` can name an instance, and so two
5704
+ * peer-resolved variants of one `name@version` stay distinguishable.
5696
5705
  * - `name` — the resolved package name. For pnpm *workspace* packages
5697
5706
  * straight out of `Lockfile.parse` this is the importer path until
5698
5707
  * `Lockfile#withImporterNames` rewrites it.
@@ -5708,20 +5717,66 @@ const EMPTY_DEPENDENCIES = {};
5708
5717
  * packages, when the lockfile records one.
5709
5718
  * - `dependencies` — the package's own dependency map, defaulting to `{}`
5710
5719
  * both at construction and when decoding serialized data.
5720
+ * - `peerDependencies` — the package's *declared* peer ranges, keyed by peer
5721
+ * name. Every format records them (pnpm and npm as their own section, bun
5722
+ * inline in the package tuple's info object, yarn Berry as an entry
5723
+ * section), so this is populated across all four. Declarations only: what
5724
+ * the package *asks for*, never what actually resolved.
5725
+ * - `peerDependenciesMeta` — the per-peer flags, normalized to
5726
+ * `{ optional: boolean }`. bun spells optional peers as an `optionalPeers`
5727
+ * array of names rather than a meta object; that spelling is normalized
5728
+ * into this shape so one consumer algorithm serves every format. A peer
5729
+ * with no meta entry is required.
5730
+ * - `resolved` — this instance's *outgoing edges*: dependency (and, where the
5731
+ * format records it, peer) name → the `instanceId` that name actually
5732
+ * resolved to in this instance's context. This is the answer to "which
5733
+ * concrete version of P did X get", which `peerDependencies` deliberately
5734
+ * does not answer.
5735
+ *
5736
+ * Every entry is **verified**: an edge is emitted only when the composed or
5737
+ * walked-up identity matches a real instance in the same lockfile. An edge
5738
+ * that cannot be resolved honestly is *omitted*, never guessed — a wrong
5739
+ * resolved edge is a silent wrong answer, an absent one is a visible gap.
5740
+ * yarn records peer resolution virtually and is therefore dependency-edges
5741
+ * only.
5742
+ *
5743
+ * - `unresolvedEdges` — dependency names whose edge the lockfile **records**
5744
+ * but this model could not name: a `link:` target that is not a workspace
5745
+ * importer, a composed identity matching no instance. It is the companion
5746
+ * `resolved` needs to be honest, because an absent key in `resolved` would
5747
+ * otherwise mean two different things — "nothing is there" and "something is
5748
+ * there that I could not name" — and a consumer reading the first meaning
5749
+ * for the second turns this package's gap into its own false positive.
5750
+ *
5751
+ * A dependency the lockfile simply does not record is **not** an unresolved
5752
+ * edge; it is an absence, and must not appear here. npm and bun contribute
5753
+ * nothing at all: their sections are *declarations* resolved positionally, so
5754
+ * "the walk found nothing" is genuine absence. A fail-closed signal that is
5755
+ * always on is a signal nobody reads.
5756
+ *
5757
+ * All four record fields — `dependencies`, `peerDependencies`,
5758
+ * `peerDependenciesMeta` and `resolved` — default to `{}` at construction and
5759
+ * when decoding, and `unresolvedEdges` defaults to `[]`. An absent section is
5760
+ * therefore an empty collection, never `undefined`.
5711
5761
  *
5712
5762
  * @public
5713
5763
  */
5714
5764
  var ResolvedPackage = class extends Schema.Class("ResolvedPackage")({
5715
5765
  name: Schema.NonEmptyString,
5716
5766
  version: Schema.String,
5767
+ instanceId: Schema.NonEmptyString,
5717
5768
  integrity: Schema.optionalKey(IntegrityHash),
5718
5769
  isWorkspace: Schema.Boolean,
5719
5770
  relativePath: Schema.optionalKey(Schema.String),
5720
- dependencies: Schema.Record(Schema.String, Schema.String).pipe(Schema.withDecodingDefaultKey(Effect.succeed(EMPTY_DEPENDENCIES)), Schema.withConstructorDefault(Effect.succeed(EMPTY_DEPENDENCIES)))
5771
+ dependencies: Schema.Record(Schema.String, Schema.String).pipe(Schema.withDecodingDefaultKey(Effect.succeed(EMPTY_DEPENDENCIES)), Schema.withConstructorDefault(Effect.succeed(EMPTY_DEPENDENCIES))),
5772
+ peerDependencies: Schema.Record(Schema.String, Schema.String).pipe(Schema.withDecodingDefaultKey(Effect.succeed(EMPTY_DEPENDENCIES)), Schema.withConstructorDefault(Effect.succeed(EMPTY_DEPENDENCIES))),
5773
+ peerDependenciesMeta: Schema.Record(Schema.String, Schema.Struct({ optional: Schema.Boolean })).pipe(Schema.withDecodingDefaultKey(Effect.succeed(EMPTY_PEER_META)), Schema.withConstructorDefault(Effect.succeed(EMPTY_PEER_META))),
5774
+ resolved: Schema.Record(Schema.String, Schema.String).pipe(Schema.withDecodingDefaultKey(Effect.succeed(EMPTY_DEPENDENCIES)), Schema.withConstructorDefault(Effect.succeed(EMPTY_DEPENDENCIES))),
5775
+ unresolvedEdges: Schema.Array(Schema.String).pipe(Schema.withDecodingDefaultKey(Effect.succeed(EMPTY_EDGE_NAMES)), Schema.withConstructorDefault(Effect.succeed(EMPTY_EDGE_NAMES)))
5721
5776
  }) {};
5722
5777
 
5723
5778
  //#endregion
5724
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.5.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_d53253b32eb6a388ea04dc81d5e132f1/node_modules/@effected/lockfiles/WorkspaceDependency.js
5779
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.6.0_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_060c8bbc0d868c806eb6e32fbf3c19ea/node_modules/@effected/lockfiles/WorkspaceDependency.js
5725
5780
  /**
5726
5781
  * A directed dependency edge between two workspace packages as recorded in
5727
5782
  * the lockfile.
@@ -5744,7 +5799,7 @@ var WorkspaceDependency = class extends Schema.Class("WorkspaceDependency")({
5744
5799
  }) {};
5745
5800
 
5746
5801
  //#endregion
5747
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.5.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_d53253b32eb6a388ea04dc81d5e132f1/node_modules/@effected/lockfiles/PnpmExtension.js
5802
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.6.0_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_060c8bbc0d868c806eb6e32fbf3c19ea/node_modules/@effected/lockfiles/PnpmExtension.js
5748
5803
  /**
5749
5804
  * Extension data specific to pnpm lockfiles, attached to `Lockfile.extension`
5750
5805
  * when the format is `"pnpm"`.
@@ -5770,10 +5825,10 @@ var PnpmExtension = class extends Schema.Class("PnpmExtension")({
5770
5825
  }) {};
5771
5826
 
5772
5827
  //#endregion
5773
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.5.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_d53253b32eb6a388ea04dc81d5e132f1/node_modules/@effected/lockfiles/LockfileFormat.js
5828
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.6.0_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_060c8bbc0d868c806eb6e32fbf3c19ea/node_modules/@effected/lockfiles/LockfileFormat.js
5774
5829
  /**
5775
5830
  * The lockfile formats this package parses: bun's `bun.lock` (JSONC), npm's
5776
- * `package-lock.json` (v2/v3 JSON), pnpm's `pnpm-lock.yaml` and yarn Berry's
5831
+ * `package-lock.json` (JSON), pnpm's `pnpm-lock.yaml` and yarn Berry's
5777
5832
  * `yarn.lock` (both YAML).
5778
5833
  *
5779
5834
  * @remarks
@@ -5782,6 +5837,10 @@ var PnpmExtension = class extends Schema.Class("PnpmExtension")({
5782
5837
  * Berry only; classic (v1) `yarn.lock` is not YAML and fails
5783
5838
  * `Lockfile.parse` with a typed `LockfileParseError`.
5784
5839
  *
5840
+ * The format literal says nothing about which *versions* of that format are
5841
+ * supported: pnpm `lockfileVersion` 9+ and npm `lockfileVersion` 3+ parse,
5842
+ * and older ones fail typed. See `Lockfile.parse`.
5843
+ *
5785
5844
  * @public
5786
5845
  */
5787
5846
  const LockfileFormat = Schema.Literals([
@@ -5809,7 +5868,7 @@ const FILENAMES = {
5809
5868
  const filenameFor = (format) => FILENAMES[format][0];
5810
5869
 
5811
5870
  //#endregion
5812
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.5.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_d53253b32eb6a388ea04dc81d5e132f1/node_modules/@effected/lockfiles/internal/shared.js
5871
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.6.0_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_060c8bbc0d868c806eb6e32fbf3c19ea/node_modules/@effected/lockfiles/internal/shared.js
5813
5872
  /**
5814
5873
  * The four dependency sections of a manifest, in a stable order — the shared
5815
5874
  * dependency-sections table (v3's `DEP_SECTIONS`). Each entry is both the
@@ -5920,6 +5979,79 @@ const importerDependencies = (entry, read) => {
5920
5979
  }
5921
5980
  return deps;
5922
5981
  };
5982
+ const EMPTY_PEERS = {
5983
+ peerDependencies: {},
5984
+ peerDependenciesMeta: {}
5985
+ };
5986
+ /**
5987
+ * Normalize one format's peer declarations into the unified pair.
5988
+ *
5989
+ * Every format records the ranges the same way (a name→range map), but the
5990
+ * optional flag has two spellings: a `peerDependenciesMeta` object (pnpm, npm,
5991
+ * yarn Berry) and bun's `optionalPeers` array of names. Both are accepted and
5992
+ * collapse to `{ optional: boolean }` per peer, so a consumer reads one shape
5993
+ * regardless of which manager wrote the lockfile.
5994
+ *
5995
+ * Absence yields empty records, never `undefined` — an absent section means
5996
+ * "declares no peers", which is a fact, not a gap. Records are built with
5997
+ * `Object.fromEntries` (own-property semantics), so a `__proto__` peer name
5998
+ * neither pollutes nor drops.
5999
+ *
6000
+ * @internal
6001
+ */
6002
+ const peerDeclarations = (peers, meta, optionalPeers) => {
6003
+ if (peers === void 0 && meta === void 0 && optionalPeers === void 0) return EMPTY_PEERS;
6004
+ const flags = /* @__PURE__ */ new Map();
6005
+ if (meta !== void 0) for (const [name, value] of Object.entries(meta)) flags.set(name, value?.optional === true);
6006
+ if (optionalPeers !== void 0) for (const name of optionalPeers) flags.set(name, true);
6007
+ return {
6008
+ peerDependencies: peers === void 0 ? {} : Object.fromEntries(Object.entries(peers)),
6009
+ peerDependenciesMeta: Object.fromEntries([...flags].map(([name, optional]) => [name, { optional }]))
6010
+ };
6011
+ };
6012
+ /**
6013
+ * The minimum lockfile-format version each gated format is parsed at.
6014
+ *
6015
+ * This is a deliberate narrowing of the supported input domain, not an
6016
+ * implementation detail: an older lockfile fails typed rather than parsing
6017
+ * into a model that cannot answer resolution questions. Note the gate is on
6018
+ * the **lockfile format version**, which is the only version a lockfile
6019
+ * records — the writing package manager's version is not recoverable from the
6020
+ * file, so no manager-version claim could be enforced here.
6021
+ *
6022
+ * @internal
6023
+ */
6024
+ const MINIMUM_LOCKFILE_VERSION = {
6025
+ pnpm: 9,
6026
+ npm: 3
6027
+ };
6028
+ /**
6029
+ * Fail typed when a lockfile predates the supported format version.
6030
+ *
6031
+ * Routed through {@link validationFailure} rather than {@link framingFailure}:
6032
+ * the document was located perfectly well, so this is a shape judgement about
6033
+ * a located document, not a framing problem. The cause is a structured record
6034
+ * rather than an engine error, so a consumer can tell "your lockfile is too
6035
+ * old" from "your lockfile is malformed" without parsing a message.
6036
+ *
6037
+ * A version that is not a number at all (`lockfileVersion: "next"`) is not a
6038
+ * supported version either, and fails the same way.
6039
+ *
6040
+ * @internal
6041
+ */
6042
+ const requireLockfileVersion = (format, raw) => {
6043
+ const minimum = MINIMUM_LOCKFILE_VERSION[format];
6044
+ const parsed = typeof raw === "number" ? raw : Number.parseFloat(raw);
6045
+ if (Number.isFinite(parsed) && parsed >= minimum) return Effect.void;
6046
+ const cause = {
6047
+ _tag: "UnsupportedLockfileVersion",
6048
+ format,
6049
+ lockfileVersion: raw,
6050
+ minimumSupported: minimum,
6051
+ message: `${format} lockfileVersion ${JSON.stringify(raw)} is not supported: @effected/lockfiles parses ${format} lockfileVersion ${minimum} and newer`
6052
+ };
6053
+ return Effect.fail(validationFailure(cause));
6054
+ };
5923
6055
  /** @internal */
5924
6056
  const syntaxFailure = (cause) => ({
5925
6057
  stage: "syntax",
@@ -7781,16 +7913,38 @@ var JsoncModifier = class {
7781
7913
  };
7782
7914
 
7783
7915
  //#endregion
7784
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.5.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_d53253b32eb6a388ea04dc81d5e132f1/node_modules/@effected/lockfiles/internal/bun.js
7916
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.6.0_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_060c8bbc0d868c806eb6e32fbf3c19ea/node_modules/@effected/lockfiles/internal/bun.js
7785
7917
  const DepRecord$2 = Schema.optionalKey(Schema.Record(Schema.String, Schema.String));
7918
+ const OptionalPeers = Schema.optionalKey(Schema.Array(Schema.String));
7786
7919
  const BunWorkspaceEntry = Schema.Struct({
7787
7920
  name: Schema.optionalKey(Schema.String),
7788
7921
  version: Schema.optionalKey(Schema.String),
7789
7922
  dependencies: DepRecord$2,
7790
7923
  devDependencies: DepRecord$2,
7791
7924
  peerDependencies: DepRecord$2,
7792
- optionalDependencies: DepRecord$2
7925
+ optionalDependencies: DepRecord$2,
7926
+ optionalPeers: OptionalPeers
7927
+ });
7928
+ /**
7929
+ * The info object at package-tuple index 2. bun's tuple shape is
7930
+ * under-documented upstream, so it is read permissively and *out of band*: a
7931
+ * shape that does not decode is skipped (the package still lands, with no
7932
+ * peers) rather than failing the whole parse.
7933
+ *
7934
+ * @internal
7935
+ */
7936
+ const BunPackageInfo = Schema.Struct({
7937
+ dependencies: DepRecord$2,
7938
+ devDependencies: DepRecord$2,
7939
+ optionalDependencies: DepRecord$2,
7940
+ peerDependencies: DepRecord$2,
7941
+ optionalPeers: OptionalPeers
7793
7942
  });
7943
+ const decodeBunPackageInfo = Schema.decodeUnknownExit(BunPackageInfo);
7944
+ const readBunPackageInfo = (value) => {
7945
+ const exit = decodeBunPackageInfo(value);
7946
+ return Exit.isSuccess(exit) ? exit.value : void 0;
7947
+ };
7794
7948
  const BunLockfileRaw = Schema.Struct({
7795
7949
  lockfileVersion: Schema.Number,
7796
7950
  workspaces: Schema.optionalKey(Schema.Record(Schema.String, BunWorkspaceEntry)),
@@ -7813,8 +7967,60 @@ const parseBun = (content) => Effect.gen(function* () {
7813
7967
  const validated = yield* Schema.decodeUnknownEffect(BunLockfileRaw)(parsed).pipe(Effect.mapError(validationFailure));
7814
7968
  return yield* toFields$3(validated);
7815
7969
  });
7970
+ /**
7971
+ * Resolve one entry's outgoing edges by replaying bun's own key scheme.
7972
+ *
7973
+ * bun encodes install position in the `packages` key: a nested install is
7974
+ * keyed `<parent-key>/<name>`, so `"react-dom/react"` is literally "the react
7975
+ * react-dom got". Package names are themselves slash-bearing when scoped, so
7976
+ * the parent chain is **not** computed by splitting on `/` — it is read off
7977
+ * the key space, taking those prefixes of the key that are themselves keys,
7978
+ * longest first. Deepest wins; the root (`<name>` alone) is tried last.
7979
+ *
7980
+ * Only keys that exist are emitted, so an edge bun did not record is omitted
7981
+ * rather than invented.
7982
+ *
7983
+ * @internal
7984
+ */
7985
+ const resolveBunEdges = (key, sections, keys) => {
7986
+ const names = /* @__PURE__ */ new Set();
7987
+ for (const section of sections) {
7988
+ if (!section) continue;
7989
+ for (const name of Object.keys(section)) if (name !== "") names.add(name);
7990
+ }
7991
+ if (names.size === 0) return {};
7992
+ const prefixes = [key];
7993
+ for (let i = key.indexOf("/"); i !== -1; i = key.indexOf("/", i + 1)) {
7994
+ const candidate = key.slice(0, i);
7995
+ if (keys.has(candidate)) prefixes.push(candidate);
7996
+ }
7997
+ prefixes.sort((a, b) => b.length - a.length);
7998
+ prefixes.push("");
7999
+ const edges = /* @__PURE__ */ new Map();
8000
+ for (const name of names) for (const prefix of prefixes) {
8001
+ const candidate = prefix === "" ? name : `${prefix}/${name}`;
8002
+ if (keys.has(candidate)) {
8003
+ edges.set(name, candidate);
8004
+ break;
8005
+ }
8006
+ }
8007
+ return Object.fromEntries(edges);
8008
+ };
8009
+ const infoSections = (info) => [
8010
+ info?.dependencies,
8011
+ info?.devDependencies,
8012
+ info?.optionalDependencies,
8013
+ info?.peerDependencies
8014
+ ];
8015
+ const workspaceSections = (entry) => [
8016
+ entry.dependencies,
8017
+ entry.devDependencies,
8018
+ entry.optionalDependencies,
8019
+ entry.peerDependencies
8020
+ ];
7816
8021
  const toFields$3 = (raw) => Effect.gen(function* () {
7817
8022
  const packages = [];
8023
+ const keys = new Set(raw.packages ? Object.keys(raw.packages) : []);
7818
8024
  const workspaceNames = /* @__PURE__ */ new Set();
7819
8025
  const workspaceEntries = /* @__PURE__ */ new Map();
7820
8026
  const importers = [];
@@ -7827,11 +8033,16 @@ const toFields$3 = (raw) => Effect.gen(function* () {
7827
8033
  if (wsPath === "") continue;
7828
8034
  const name = wsEntry.name === void 0 || wsEntry.name === "" ? wsPath : wsEntry.name;
7829
8035
  workspaceNames.add(name);
8036
+ const instanceId = keys.has(name) ? name : wsPath;
8037
+ if (instanceId === "") continue;
7830
8038
  packages.push(ResolvedPackage.make({
7831
8039
  name,
7832
8040
  version: wsEntry.version ?? "0.0.0",
8041
+ instanceId,
7833
8042
  isWorkspace: true,
7834
- relativePath: wsPath
8043
+ relativePath: wsPath,
8044
+ ...peerDeclarations(wsEntry.peerDependencies, void 0, wsEntry.optionalPeers),
8045
+ resolved: resolveBunEdges(instanceId, workspaceSections(wsEntry), keys)
7835
8046
  }));
7836
8047
  workspaceEntries.set(name, {
7837
8048
  ...wsEntry.dependencies ? { dependencies: wsEntry.dependencies } : {},
@@ -7841,7 +8052,8 @@ const toFields$3 = (raw) => Effect.gen(function* () {
7841
8052
  });
7842
8053
  }
7843
8054
  }
7844
- if (raw.packages) for (const tuple of Object.values(raw.packages)) {
8055
+ if (raw.packages) for (const [key, tuple] of Object.entries(raw.packages)) {
8056
+ if (key === "") continue;
7845
8057
  if (tuple.length < 1) continue;
7846
8058
  const first = tuple[0];
7847
8059
  if (typeof first !== "string") continue;
@@ -7851,11 +8063,15 @@ const toFields$3 = (raw) => Effect.gen(function* () {
7851
8063
  const version = first.slice(atIdx + 1);
7852
8064
  if (workspaceNames.has(name)) continue;
7853
8065
  const integrity = yield* toIntegrityHash(tuple.length >= 4 && typeof tuple[3] === "string" ? tuple[3] : void 0);
8066
+ const info = tuple.length >= 3 ? readBunPackageInfo(tuple[2]) : void 0;
7854
8067
  packages.push(ResolvedPackage.make({
7855
8068
  name,
7856
8069
  version,
8070
+ instanceId: key,
7857
8071
  ...integrity !== void 0 ? { integrity } : {},
7858
- isWorkspace: false
8072
+ isWorkspace: false,
8073
+ ...peerDeclarations(info?.peerDependencies, void 0, info?.optionalPeers),
8074
+ resolved: resolveBunEdges(key, infoSections(info), keys)
7859
8075
  }));
7860
8076
  }
7861
8077
  const workspaceDependencies = extractWorkspaceDeps(workspaceEntries, workspaceNames);
@@ -7875,8 +8091,9 @@ const toFields$3 = (raw) => Effect.gen(function* () {
7875
8091
  });
7876
8092
 
7877
8093
  //#endregion
7878
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.5.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_d53253b32eb6a388ea04dc81d5e132f1/node_modules/@effected/lockfiles/internal/npm.js
8094
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.6.0_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_060c8bbc0d868c806eb6e32fbf3c19ea/node_modules/@effected/lockfiles/internal/npm.js
7879
8095
  const DepRecord$1 = Schema.optionalKey(Schema.Record(Schema.String, Schema.String));
8096
+ const PeerMetaRecord = Schema.optionalKey(Schema.Record(Schema.String, Schema.Struct({ optional: Schema.optionalKey(Schema.Boolean) })));
7880
8097
  const NpmPackageEntry = Schema.Struct({
7881
8098
  name: Schema.optionalKey(Schema.String),
7882
8099
  version: Schema.optionalKey(Schema.String),
@@ -7887,8 +8104,22 @@ const NpmPackageEntry = Schema.Struct({
7887
8104
  dependencies: DepRecord$1,
7888
8105
  devDependencies: DepRecord$1,
7889
8106
  peerDependencies: DepRecord$1,
8107
+ peerDependenciesMeta: PeerMetaRecord,
7890
8108
  optionalDependencies: DepRecord$1
7891
8109
  });
8110
+ /**
8111
+ * The version gate's own input: `lockfileVersion` and nothing else.
8112
+ *
8113
+ * The gate has to read the version *before* the shape decode, because the
8114
+ * shape it would decode against is the shape of a supported version. `packages`
8115
+ * is a required key here and a v1 tree does not have one, so a shape-first
8116
+ * order reports npm v1 as **malformed** rather than as **too old** — losing
8117
+ * exactly the distinction the `UnsupportedLockfileVersion` cause exists to
8118
+ * carry.
8119
+ *
8120
+ * @internal
8121
+ */
8122
+ const NpmVersionProbe = Schema.Struct({ lockfileVersion: Schema.Union([Schema.Number, Schema.String]) });
7892
8123
  const NpmLockfileRaw = Schema.Struct({
7893
8124
  name: Schema.optionalKey(Schema.String),
7894
8125
  version: Schema.optionalKey(Schema.String),
@@ -7897,10 +8128,73 @@ const NpmLockfileRaw = Schema.Struct({
7897
8128
  packages: Schema.Record(Schema.String, NpmPackageEntry)
7898
8129
  });
7899
8130
  const NODE_MODULES_PREFIX = "node_modules/";
8131
+ const NESTED_NODE_MODULES = "/node_modules/";
8132
+ /**
8133
+ * Where a `packages` key's package name starts: after the **last**
8134
+ * `node_modules/` segment, not the first.
8135
+ *
8136
+ * npm encodes the whole install position in the key, so
8137
+ * `node_modules/express/node_modules/debug` is *debug*, nested under express —
8138
+ * and `packages/lib/node_modules/react` is *react*, nested under a workspace
8139
+ * directory and carrying no `node_modules/` prefix at all. Returns `-1` for a
8140
+ * key that is not a package position (the root `""` entry, a workspace path
8141
+ * entry), which the caller skips.
8142
+ *
8143
+ * @internal
8144
+ */
8145
+ const packageNameIndex = (key) => {
8146
+ const nested = key.lastIndexOf(NESTED_NODE_MODULES);
8147
+ if (nested !== -1) return nested + 14;
8148
+ return key.startsWith(NODE_MODULES_PREFIX) ? 13 : -1;
8149
+ };
8150
+ /**
8151
+ * Resolve one entry's outgoing edges by replaying node resolution over the key
8152
+ * space: from the depending package's own directory, try
8153
+ * `<prefix>/node_modules/<name>`, then strip one path segment and try again,
8154
+ * out to the root — **deepest first**, first hit wins. That order is the whole
8155
+ * algorithm: outermost-first would return the hoisted copy and silently
8156
+ * mis-report every shadowed dependency.
8157
+ *
8158
+ * Only keys that actually exist in the lockfile are emitted, so an edge npm
8159
+ * did not record is omitted rather than invented.
8160
+ *
8161
+ * @internal
8162
+ */
8163
+ const resolveNpmEdges = (start, sections, packages) => {
8164
+ const names = /* @__PURE__ */ new Set();
8165
+ for (const section of sections) {
8166
+ if (!section) continue;
8167
+ for (const name of Object.keys(section)) if (name !== "") names.add(name);
8168
+ }
8169
+ if (names.size === 0) return {};
8170
+ const prefixes = [];
8171
+ for (let prefix = start;;) {
8172
+ prefixes.push(prefix);
8173
+ if (prefix === "") break;
8174
+ const slash = prefix.lastIndexOf("/");
8175
+ prefix = slash === -1 ? "" : prefix.slice(0, slash);
8176
+ }
8177
+ const edges = /* @__PURE__ */ new Map();
8178
+ for (const name of names) for (const prefix of prefixes) {
8179
+ const candidate = prefix === "" ? `${NODE_MODULES_PREFIX}${name}` : `${prefix}${NESTED_NODE_MODULES}${name}`;
8180
+ if (Object.hasOwn(packages, candidate)) {
8181
+ edges.set(name, candidate);
8182
+ break;
8183
+ }
8184
+ }
8185
+ return Object.fromEntries(edges);
8186
+ };
8187
+ const entrySections = (entry) => [
8188
+ entry?.dependencies,
8189
+ entry?.devDependencies,
8190
+ entry?.optionalDependencies,
8191
+ entry?.peerDependencies
8192
+ ];
7900
8193
  /**
7901
- * Parse npm `package-lock.json` (v2/v3) content into the unified field
7902
- * bundle. Native `JSON.parse` inside `Effect.try` its throw on hostile
7903
- * input (including V8's `RangeError` on pathological depth) lands typed as
8194
+ * Parse npm `package-lock.json` content into the unified field bundle —
8195
+ * `lockfileVersion` 3 and newer; v2 and older fail typed at validation.
8196
+ * Native `JSON.parse` inside `Effect.try` its throw on hostile input
8197
+ * (including V8's `RangeError` on pathological depth) lands typed as
7904
8198
  * `stage: "syntax"`.
7905
8199
  *
7906
8200
  * @internal
@@ -7910,6 +8204,8 @@ const parseNpm = (content) => Effect.gen(function* () {
7910
8204
  try: () => JSON.parse(content),
7911
8205
  catch: syntaxFailure
7912
8206
  });
8207
+ const probe = yield* Schema.decodeUnknownEffect(NpmVersionProbe)(raw).pipe(Effect.mapError(validationFailure));
8208
+ yield* requireLockfileVersion("npm", probe.lockfileVersion);
7913
8209
  const validated = yield* Schema.decodeUnknownEffect(NpmLockfileRaw)(raw).pipe(Effect.mapError(validationFailure));
7914
8210
  return yield* toFields$2(validated);
7915
8211
  });
@@ -7923,22 +8219,30 @@ const toFields$2 = (raw) => Effect.gen(function* () {
7923
8219
  path: ".",
7924
8220
  dependencies: importerDependencies(rootEntry, (s) => ({ specifier: s }))
7925
8221
  }));
7926
- for (const [key, entry] of Object.entries(raw.packages)) if (key.startsWith(NODE_MODULES_PREFIX) && entry.link === true) {
7927
- const name = (entry.resolved !== void 0 ? raw.packages[entry.resolved] : void 0)?.name ?? entry.name ?? key.slice(13);
7928
- if (name !== "") workspaceNames.add(name);
8222
+ for (const [key, entry] of Object.entries(raw.packages)) {
8223
+ const nameIndex = packageNameIndex(key);
8224
+ if (nameIndex !== -1 && entry.link === true) {
8225
+ const name = (entry.resolved !== void 0 ? raw.packages[entry.resolved] : void 0)?.name ?? entry.name ?? key.slice(nameIndex);
8226
+ if (name !== "") workspaceNames.add(name);
8227
+ }
7929
8228
  }
7930
8229
  for (const [key, entry] of Object.entries(raw.packages)) {
7931
8230
  if (key === "") continue;
7932
- if (key.startsWith(NODE_MODULES_PREFIX) && entry.link === true) {
8231
+ const nameIndex = packageNameIndex(key);
8232
+ if (nameIndex === -1) continue;
8233
+ if (entry.link === true) {
7933
8234
  const resolved = entry.resolved;
7934
8235
  const wsEntry = resolved !== void 0 ? raw.packages[resolved] : void 0;
7935
- const name = wsEntry?.name ?? entry.name ?? key.slice(13);
8236
+ const name = wsEntry?.name ?? entry.name ?? key.slice(nameIndex);
7936
8237
  if (name === "") continue;
7937
8238
  packages.push(ResolvedPackage.make({
7938
8239
  name,
7939
8240
  version: wsEntry?.version ?? "0.0.0",
8241
+ instanceId: key,
7940
8242
  isWorkspace: true,
7941
- ...resolved !== void 0 ? { relativePath: resolved } : {}
8243
+ ...resolved !== void 0 ? { relativePath: resolved } : {},
8244
+ ...peerDeclarations(wsEntry?.peerDependencies, wsEntry?.peerDependenciesMeta),
8245
+ resolved: resolveNpmEdges(resolved !== void 0 && resolved !== "" ? resolved : key, entrySections(wsEntry), raw.packages)
7942
8246
  }));
7943
8247
  if (wsEntry) workspaceEntries.set(name, {
7944
8248
  ...wsEntry.dependencies ? { dependencies: wsEntry.dependencies } : {},
@@ -7950,16 +8254,19 @@ const toFields$2 = (raw) => Effect.gen(function* () {
7950
8254
  path: resolved,
7951
8255
  dependencies: wsEntry ? importerDependencies(wsEntry, (s) => ({ specifier: s })) : []
7952
8256
  }));
7953
- } else if (key.startsWith(NODE_MODULES_PREFIX)) {
7954
- const name = key.slice(13);
8257
+ } else {
8258
+ const name = key.slice(nameIndex);
7955
8259
  if (name !== "" && entry.version !== void 0) {
7956
8260
  const integrity = yield* toIntegrityHash(entry.integrity);
7957
8261
  packages.push(ResolvedPackage.make({
7958
8262
  name,
7959
8263
  version: entry.version,
8264
+ instanceId: key,
7960
8265
  ...integrity !== void 0 ? { integrity } : {},
7961
8266
  isWorkspace: false,
7962
- dependencies: entry.dependencies ?? {}
8267
+ dependencies: entry.dependencies ?? {},
8268
+ ...peerDeclarations(entry.peerDependencies, entry.peerDependenciesMeta),
8269
+ resolved: resolveNpmEdges(key, entrySections(entry), raw.packages)
7963
8270
  }));
7964
8271
  }
7965
8272
  }
@@ -15757,7 +16064,7 @@ function deepEqualValues(a, b) {
15757
16064
  }
15758
16065
 
15759
16066
  //#endregion
15760
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.5.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_d53253b32eb6a388ea04dc81d5e132f1/node_modules/@effected/lockfiles/internal/documents.js
16067
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.6.0_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_060c8bbc0d868c806eb6e32fbf3c19ea/node_modules/@effected/lockfiles/internal/documents.js
15761
16068
  /**
15762
16069
  * An empty YAML document composes to `null` (`Yaml.parseAll("")` is `[null]`,
15763
16070
  * and the trailing document of an env-only `pnpm-lock.yaml` is `null` too).
@@ -15828,7 +16135,7 @@ const selectSoleDocument = (content) => Effect.gen(function* () {
15828
16135
  });
15829
16136
 
15830
16137
  //#endregion
15831
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.5.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_d53253b32eb6a388ea04dc81d5e132f1/node_modules/@effected/lockfiles/internal/pnpm.js
16138
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.6.0_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_060c8bbc0d868c806eb6e32fbf3c19ea/node_modules/@effected/lockfiles/internal/pnpm.js
15832
16139
  const PnpmImporterDeps = Schema.optionalKey(Schema.Record(Schema.String, Schema.Struct({
15833
16140
  specifier: Schema.String,
15834
16141
  version: Schema.String
@@ -15839,6 +16146,18 @@ const PnpmImporter = Schema.Struct({
15839
16146
  peerDependencies: PnpmImporterDeps,
15840
16147
  optionalDependencies: PnpmImporterDeps
15841
16148
  });
16149
+ /**
16150
+ * The version gate's own input: `lockfileVersion` and nothing else.
16151
+ *
16152
+ * The gate has to read the version *before* the shape decode, because the
16153
+ * shape it decodes against is the shape of a supported version. `importers` is
16154
+ * a required key here and a pre-v9 single-project lockfile has none — it
16155
+ * records its dependencies at the top level — so a shape-first order reports a
16156
+ * lockfile we reject for being too old as merely malformed instead.
16157
+ *
16158
+ * @internal
16159
+ */
16160
+ const PnpmVersionProbe = Schema.Struct({ lockfileVersion: Schema.Union([Schema.String, Schema.Number]) });
15842
16161
  const PnpmLockfileRaw = Schema.Struct({
15843
16162
  lockfileVersion: Schema.Union([Schema.String, Schema.Number]),
15844
16163
  settings: Schema.optionalKey(Schema.Struct({
@@ -15851,7 +16170,17 @@ const PnpmLockfileRaw = Schema.Struct({
15851
16170
  version: Schema.String
15852
16171
  })])))),
15853
16172
  importers: Schema.Record(Schema.String, PnpmImporter),
15854
- packages: Schema.optionalKey(Schema.Record(Schema.String, Schema.Struct({ resolution: Schema.optionalKey(Schema.Struct({ integrity: Schema.optionalKey(Schema.String) })) })))
16173
+ packages: Schema.optionalKey(Schema.Record(Schema.String, Schema.Struct({
16174
+ resolution: Schema.optionalKey(Schema.Struct({ integrity: Schema.optionalKey(Schema.String) })),
16175
+ peerDependencies: Schema.optionalKey(Schema.Record(Schema.String, Schema.String)),
16176
+ peerDependenciesMeta: Schema.optionalKey(Schema.Record(Schema.String, Schema.Struct({ optional: Schema.optionalKey(Schema.Boolean) }))),
16177
+ dependencies: Schema.optionalKey(Schema.Record(Schema.String, Schema.String)),
16178
+ optionalDependencies: Schema.optionalKey(Schema.Record(Schema.String, Schema.String))
16179
+ }))),
16180
+ snapshots: Schema.optionalKey(Schema.Record(Schema.String, Schema.Struct({
16181
+ dependencies: Schema.optionalKey(Schema.Record(Schema.String, Schema.String)),
16182
+ optionalDependencies: Schema.optionalKey(Schema.Record(Schema.String, Schema.String))
16183
+ })))
15855
16184
  });
15856
16185
  /**
15857
16186
  * Parse pnpm `pnpm-lock.yaml` content into the unified field bundle.
@@ -15871,10 +16200,103 @@ const PnpmLockfileRaw = Schema.Struct({
15871
16200
  */
15872
16201
  const parsePnpm = (content) => Effect.gen(function* () {
15873
16202
  const { document, documents } = yield* selectPnpmDocument(content);
16203
+ const probe = yield* Schema.decodeUnknownEffect(PnpmVersionProbe)(document).pipe(Effect.mapError(validationFailure));
16204
+ yield* requireLockfileVersion("pnpm", probe.lockfileVersion);
15874
16205
  const validated = yield* Schema.decodeUnknownEffect(PnpmLockfileRaw)(document).pipe(Effect.mapError(validationFailure));
15875
16206
  if (Object.keys(validated.importers).length === 0) return yield* Effect.fail(framingFailure("noImporters", documents));
15876
16207
  return yield* toFields$1(validated);
15877
16208
  });
16209
+ /**
16210
+ * Resolve one instance's outgoing edges to instance ids.
16211
+ *
16212
+ * pnpm names a resolved dependency as `name` → `version`, where the version may
16213
+ * itself carry a peer suffix (`1.6.0(react@17.0.2)`); the referenced instance's
16214
+ * key is those two composed back together. The composition is *verified*
16215
+ * against the lockfile's own key set rather than trusted — the composed key is
16216
+ * v9's bare `name@version` and nothing else, because the format gate admits no
16217
+ * lockfile that spells keys the pre-v9 leading-slash way — and an edge that
16218
+ * matches nothing is **omitted**. That is what keeps a `link:`/`file:`
16219
+ * resolution, which names no instance in this lockfile, from becoming a
16220
+ * plausible lie.
16221
+ *
16222
+ * @internal
16223
+ */
16224
+ const resolveEdges = (sections, instanceIds) => {
16225
+ const edges = /* @__PURE__ */ new Map();
16226
+ const unnameable = /* @__PURE__ */ new Set();
16227
+ for (const section of sections) {
16228
+ if (!section) continue;
16229
+ for (const [name, version] of Object.entries(section)) {
16230
+ if (name === "") continue;
16231
+ if (version.startsWith(LINK_PREFIX)) {
16232
+ const target = resolveLinkTarget("", version.slice(LINK_PREFIX.length));
16233
+ if (target !== void 0 && instanceIds.has(target)) edges.set(name, target);
16234
+ else unnameable.add(name);
16235
+ continue;
16236
+ }
16237
+ const bare = `${name}@${version}`;
16238
+ if (instanceIds.has(bare)) edges.set(name, bare);
16239
+ else unnameable.add(name);
16240
+ }
16241
+ }
16242
+ return {
16243
+ resolved: Object.fromEntries(edges),
16244
+ unresolvedEdges: [...unnameable].sort()
16245
+ };
16246
+ };
16247
+ /** The protocol pnpm records a workspace-directory resolution under. @internal */
16248
+ const LINK_PREFIX = "link:";
16249
+ /**
16250
+ * Normalize a `link:` target against the linking importer's path, so a
16251
+ * workspace edge can name the workspace importer's instance id.
16252
+ * Total: a target that walks above the root yields `undefined`.
16253
+ *
16254
+ * @internal
16255
+ */
16256
+ const resolveLinkTarget = (importerPath, target) => {
16257
+ const segments = [];
16258
+ for (const segment of `${importerPath}/${target}`.split("/")) {
16259
+ if (segment === "" || segment === ".") continue;
16260
+ if (segment === "..") {
16261
+ if (segments.pop() === void 0) return void 0;
16262
+ continue;
16263
+ }
16264
+ segments.push(segment);
16265
+ }
16266
+ return segments.length === 0 ? void 0 : segments.join("/");
16267
+ };
16268
+ /**
16269
+ * Resolve one importer's outgoing edges. pnpm records `{ specifier, version }`
16270
+ * per importer dependency, where the version is either a registry version (the
16271
+ * instance-id composition {@link resolveEdges} performs) or a `link:` target
16272
+ * naming another importer — normalized against this importer's own path. Both
16273
+ * are checked against the lockfile's instance ids before being emitted.
16274
+ *
16275
+ * @internal
16276
+ */
16277
+ const resolveImporterEdges = (importer, importerPath, instanceIds) => {
16278
+ const edges = /* @__PURE__ */ new Map();
16279
+ const unnameable = /* @__PURE__ */ new Set();
16280
+ for (const group of importerDepGroups(importer)) {
16281
+ if (!group) continue;
16282
+ for (const [name, info] of Object.entries(group)) {
16283
+ if (name === "") continue;
16284
+ if (info.version.startsWith(LINK_PREFIX)) {
16285
+ const target = resolveLinkTarget(importerPath, info.version.slice(5));
16286
+ if (target !== void 0 && instanceIds.has(target)) edges.set(name, target);
16287
+ else unnameable.add(name);
16288
+ continue;
16289
+ }
16290
+ const bare = `${name}@${info.version}`;
16291
+ if (instanceIds.has(bare)) edges.set(name, bare);
16292
+ else unnameable.add(name);
16293
+ }
16294
+ }
16295
+ return {
16296
+ resolved: Object.fromEntries(edges),
16297
+ unresolvedEdges: [...unnameable].sort()
16298
+ };
16299
+ };
15878
16300
  const toVersionMap = (deps) => {
15879
16301
  if (!deps) return void 0;
15880
16302
  return Object.fromEntries(Object.entries(deps).map(([name, info]) => [name, info.specifier]));
@@ -15915,28 +16337,50 @@ const toFields$1 = (raw) => Effect.gen(function* () {
15915
16337
  }
15916
16338
  for (const path of Object.keys(raw.importers)) if (path !== "." && path !== "") workspaceNames.add(path);
15917
16339
  const packages = [];
15918
- for (const importerPath of Object.keys(raw.importers)) {
16340
+ const snapshots = raw.snapshots;
16341
+ const instanceIds = /* @__PURE__ */ new Set([
16342
+ ...snapshots ? Object.keys(snapshots) : [],
16343
+ ...raw.packages ? Object.keys(raw.packages) : [],
16344
+ ...Object.keys(raw.importers)
16345
+ ]);
16346
+ const emitted = /* @__PURE__ */ new Set();
16347
+ for (const [importerPath, importer] of Object.entries(raw.importers)) {
15919
16348
  if (importerPath === "." || importerPath === "") continue;
15920
16349
  packages.push(ResolvedPackage.make({
15921
16350
  name: importerPath,
15922
16351
  version: "0.0.0",
16352
+ instanceId: importerPath,
15923
16353
  isWorkspace: true,
15924
- relativePath: importerPath
16354
+ relativePath: importerPath,
16355
+ ...resolveImporterEdges(importer, importerPath, instanceIds)
15925
16356
  }));
15926
16357
  }
15927
- if (raw.packages) for (const [key, pkg] of Object.entries(raw.packages)) {
15928
- const { plain: bare } = splitPeerSuffix(key);
16358
+ const emit = (instanceId, meta, edges) => Effect.gen(function* () {
16359
+ const { plain: bare } = splitPeerSuffix(instanceId);
15929
16360
  const atIndex = bare.lastIndexOf("@");
15930
- if (atIndex <= 0) continue;
16361
+ if (atIndex <= 0) return;
15931
16362
  const name = bare.slice(0, atIndex);
15932
16363
  const version = bare.slice(atIndex + 1);
15933
- const integrity = yield* toIntegrityHash(pkg.resolution?.integrity);
16364
+ const integrity = yield* toIntegrityHash(meta?.resolution?.integrity);
16365
+ emitted.add(instanceId);
15934
16366
  packages.push(ResolvedPackage.make({
15935
16367
  name,
15936
16368
  version,
16369
+ instanceId,
15937
16370
  ...integrity !== void 0 ? { integrity } : {},
15938
- isWorkspace: false
16371
+ isWorkspace: false,
16372
+ ...peerDeclarations(meta?.peerDependencies, meta?.peerDependenciesMeta),
16373
+ ...resolveEdges(edges, instanceIds)
15939
16374
  }));
16375
+ });
16376
+ if (snapshots) for (const [key, snapshot] of Object.entries(snapshots)) {
16377
+ const plain = splitPeerSuffix(key).plain;
16378
+ yield* emit(key, raw.packages !== void 0 && Object.hasOwn(raw.packages, plain) ? raw.packages[plain] : void 0, [snapshot.dependencies, snapshot.optionalDependencies]);
16379
+ }
16380
+ const covered = new Set([...emitted].map((key) => splitPeerSuffix(key).plain));
16381
+ if (raw.packages) for (const [key, pkg] of Object.entries(raw.packages)) {
16382
+ if (covered.has(key)) continue;
16383
+ yield* emit(key, pkg, [pkg.dependencies, pkg.optionalDependencies]);
15940
16384
  }
15941
16385
  const workspaceDependencies = extractWorkspaceDeps(workspaceEntries, workspaceNames);
15942
16386
  const extension = PnpmExtension.make({
@@ -15954,7 +16398,7 @@ const toFields$1 = (raw) => Effect.gen(function* () {
15954
16398
  });
15955
16399
 
15956
16400
  //#endregion
15957
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.5.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_d53253b32eb6a388ea04dc81d5e132f1/node_modules/@effected/lockfiles/internal/yarn.js
16401
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.6.0_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_060c8bbc0d868c806eb6e32fbf3c19ea/node_modules/@effected/lockfiles/internal/yarn.js
15958
16402
  const YarnLockfileRaw = Schema.Record(Schema.String, Schema.Unknown);
15959
16403
  const DepRecord = Schema.optionalKey(Schema.Record(Schema.String, Schema.String));
15960
16404
  const YarnEntry = Schema.Struct({
@@ -15963,6 +16407,7 @@ const YarnEntry = Schema.Struct({
15963
16407
  dependencies: DepRecord,
15964
16408
  devDependencies: DepRecord,
15965
16409
  peerDependencies: DepRecord,
16410
+ peerDependenciesMeta: Schema.optionalKey(Schema.Record(Schema.String, Schema.Struct({ optional: Schema.optionalKey(Schema.Boolean) }))),
15966
16411
  optionalDependencies: DepRecord,
15967
16412
  checksum: Schema.optionalKey(Schema.String),
15968
16413
  languageName: Schema.optionalKey(Schema.String),
@@ -15996,6 +16441,13 @@ const toFields = (lockfileVersion, decoded) => Effect.gen(function* () {
15996
16441
  const packages = [];
15997
16442
  const workspaceNames = /* @__PURE__ */ new Set();
15998
16443
  const workspaceEntries = /* @__PURE__ */ new Map();
16444
+ const locators = /* @__PURE__ */ new Map();
16445
+ for (const [key, entry] of decoded) {
16446
+ const descriptors = key.split(", ");
16447
+ const locator = entry.resolution ?? descriptors[0];
16448
+ if (locator === void 0 || locator === "") continue;
16449
+ for (const descriptor of descriptors) if (descriptor !== "") locators.set(descriptor, locator);
16450
+ }
15999
16451
  for (const [key, entry] of decoded) if (entry.linkType === "soft") {
16000
16452
  const name = extractYarnPackageName(key);
16001
16453
  if (name !== void 0) workspaceNames.add(name);
@@ -16006,12 +16458,17 @@ const toFields = (lockfileVersion, decoded) => Effect.gen(function* () {
16006
16458
  const isWorkspace = entry.linkType === "soft";
16007
16459
  const relativePath = isWorkspace ? extractYarnWorkspacePath(key) : void 0;
16008
16460
  const integrity = yield* toIntegrityHash(entry.checksum);
16461
+ const instanceId = entry.resolution ?? key.split(", ")[0] ?? "";
16462
+ if (instanceId === "") continue;
16009
16463
  packages.push(ResolvedPackage.make({
16010
16464
  name,
16011
16465
  version: entry.version ?? "0.0.0",
16466
+ instanceId,
16012
16467
  ...integrity !== void 0 ? { integrity } : {},
16013
16468
  isWorkspace,
16014
- ...relativePath !== void 0 ? { relativePath } : {}
16469
+ ...relativePath !== void 0 ? { relativePath } : {},
16470
+ ...peerDeclarations(entry.peerDependencies, entry.peerDependenciesMeta),
16471
+ ...resolveYarnEdges(entry, locators)
16015
16472
  }));
16016
16473
  if (isWorkspace) {
16017
16474
  const deps = cleanYarnDeps(entry.dependencies);
@@ -16034,6 +16491,46 @@ const toFields = (lockfileVersion, decoded) => Effect.gen(function* () {
16034
16491
  };
16035
16492
  });
16036
16493
  /**
16494
+ * Resolve one entry's outgoing edges through the descriptor→locator index.
16495
+ *
16496
+ * A yarn dependency value is a *descriptor* range (`"npm:5.3.0"`), and the
16497
+ * lockfile keys enumerate exactly which descriptors resolve to which locator,
16498
+ * so the lookup is exact rather than reconstructed.
16499
+ *
16500
+ * **`devDependencies` is not a section a Berry lockfile has.** yarn folds a
16501
+ * workspace's dev declarations into the entry's `dependencies` map — the
16502
+ * lockfile a project produces is byte-identical whether a dependency is
16503
+ * declared under `dependencies` or `devDependencies` (probed against yarn
16504
+ * 4.9.1). Dev edges are therefore already resolved here; iterating
16505
+ * `entry.devDependencies` would be dead code, and the schema keeps the field
16506
+ * only as permissive scaffolding for hand-edited input.
16507
+ *
16508
+ * **Dependency edges only.** yarn resolves peers virtually — a peer-bearing
16509
+ * package gets a `@virtual:` locator per consumer, and this lockfile shape does
16510
+ * not record which one satisfied which peer. Emitting a peer edge here would
16511
+ * mean guessing, so peers are left out: an absent edge is a true statement, a
16512
+ * plausible one would not be.
16513
+ *
16514
+ * @internal
16515
+ */
16516
+ const resolveYarnEdges = (entry, locators) => {
16517
+ const edges = /* @__PURE__ */ new Map();
16518
+ const unnameable = /* @__PURE__ */ new Set();
16519
+ for (const section of [entry.dependencies, entry.optionalDependencies]) {
16520
+ if (!section) continue;
16521
+ for (const [name, range] of Object.entries(section)) {
16522
+ if (name === "") continue;
16523
+ const locator = locators.get(`${name}@${range}`);
16524
+ if (locator !== void 0) edges.set(name, locator);
16525
+ else unnameable.add(name);
16526
+ }
16527
+ }
16528
+ return {
16529
+ resolved: Object.fromEntries(edges),
16530
+ unresolvedEdges: [...unnameable].sort()
16531
+ };
16532
+ };
16533
+ /**
16037
16534
  * Extract the package name from a yarn lockfile key. Handles compound keys
16038
16535
  * (`"a@workspace:*, a@workspace:packages/a"`) via the first descriptor and
16039
16536
  * `@patch:` descriptors (which embed `@npm:` inside). Total: malformed keys
@@ -16078,7 +16575,7 @@ const cleanYarnDeps = (deps) => {
16078
16575
  };
16079
16576
 
16080
16577
  //#endregion
16081
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.5.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_d53253b32eb6a388ea04dc81d5e132f1/node_modules/@effected/lockfiles/Lockfile.js
16578
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.6.0_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_060c8bbc0d868c806eb6e32fbf3c19ea/node_modules/@effected/lockfiles/Lockfile.js
16082
16579
  const EMPTY_IMPORTERS = [];
16083
16580
  /**
16084
16581
  * Failure of `Lockfile.parse`: the given content is not a valid lockfile of
@@ -16250,10 +16747,15 @@ var Lockfile = class Lockfile extends Schema.Class("Lockfile")({
16250
16747
  return ResolvedPackage.make({
16251
16748
  name: realName,
16252
16749
  version: pkg.version,
16750
+ instanceId: pkg.instanceId,
16253
16751
  ...pkg.integrity !== void 0 ? { integrity: pkg.integrity } : {},
16254
16752
  isWorkspace: pkg.isWorkspace,
16255
16753
  relativePath: pkg.relativePath,
16256
- dependencies: pkg.dependencies
16754
+ dependencies: pkg.dependencies,
16755
+ peerDependencies: pkg.peerDependencies,
16756
+ peerDependenciesMeta: pkg.peerDependenciesMeta,
16757
+ resolved: pkg.resolved,
16758
+ unresolvedEdges: pkg.unresolvedEdges
16257
16759
  });
16258
16760
  });
16259
16761
  const workspaceDependencies = this.workspaceDependencies.map((dep) => {
@@ -16323,7 +16825,7 @@ var Lockfile = class Lockfile extends Schema.Class("Lockfile")({
16323
16825
  };
16324
16826
 
16325
16827
  //#endregion
16326
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.5.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_d53253b32eb6a388ea04dc81d5e132f1/node_modules/@effected/lockfiles/LockfileIntegrity.js
16828
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.6.0_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_060c8bbc0d868c806eb6e32fbf3c19ea/node_modules/@effected/lockfiles/LockfileIntegrity.js
16327
16829
  /**
16328
16830
  * The minimal manifest shape {@link LockfileIntegrity.compare} checks a
16329
16831
  * lockfile against: a package name plus the four optional dependency maps.
@@ -19199,7 +19701,7 @@ var Package = class Package extends Schema.Class("Package")({
19199
19701
  };
19200
19702
 
19201
19703
  //#endregion
19202
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/WorkspacePackage.js
19704
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.0_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/WorkspacePackage.js
19203
19705
  const EMPTY$1 = Object.freeze(Object.create(null));
19204
19706
  const EMPTY_MANIFEST = Object.freeze(Object.create(null));
19205
19707
  /**
@@ -19801,7 +20303,7 @@ var Walker$1 = class {
19801
20303
  };
19802
20304
 
19803
20305
  //#endregion
19804
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/WorkspaceRoot.js
20306
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.0_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/WorkspaceRoot.js
19805
20307
  /**
19806
20308
  * The marker filenames {@link WorkspaceRoot} probes for, in priority order.
19807
20309
  *
@@ -19989,7 +20491,7 @@ var WorkspaceRoot = class WorkspaceRoot extends Context.Service()("@effected/wor
19989
20491
  };
19990
20492
 
19991
20493
  //#endregion
19992
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/internal/limits.js
20494
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.0_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/internal/limits.js
19993
20495
  /**
19994
20496
  * Hard ceiling on directories the enumerator will visit for one pattern set.
19995
20497
  * Guards the pathological case a depth cap alone does not: a wide, shallow
@@ -20008,7 +20510,7 @@ const MAX_ENUMERATION_ENTRIES = 1e5;
20008
20510
  const PRUNED_DIRECTORIES = /* @__PURE__ */ new Set([".git", "node_modules"]);
20009
20511
 
20010
20512
  //#endregion
20011
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/internal/traverse.js
20513
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.0_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/internal/traverse.js
20012
20514
  /** Directory names never descended into. */
20013
20515
  const isPruned = (entry) => PRUNED_DIRECTORIES.has(entry);
20014
20516
  /** Join root-relative POSIX segments; `""` is the root itself. */
@@ -20099,7 +20601,7 @@ var Traversal = class {
20099
20601
  };
20100
20602
 
20101
20603
  //#endregion
20102
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/internal/enumerate.js
20604
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.0_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/internal/enumerate.js
20103
20605
  /** Strip a trailing slash from `GlobPattern.enumerationPrefix` to get a relative directory. */
20104
20606
  const baseOf = (pattern) => pattern.enumerationPrefix.replace(/\/$/, "");
20105
20607
  /**
@@ -20116,6 +20618,8 @@ const enumerate = (root, globs, options) => Effect.gen(function* () {
20116
20618
  if (!isValidMaxDepth(maxDepth)) return yield* Effect.die(/* @__PURE__ */ new Error(`enumerate: ${badMaxDepthMessage(maxDepth)}`));
20117
20619
  const isPackage = (absolute) => fs.exists(path.join(absolute, "package.json")).pipe(Effect.orElseSucceed(() => false));
20118
20620
  const isDirectory = (absolute) => fs.stat(absolute).pipe(Effect.map((info) => info.type === "Directory"), Effect.orElseSucceed(() => false));
20621
+ const excludes = globs.excludes;
20622
+ const isExcluded = excludes.length === 0 ? (_) => false : (relative) => excludes.some((exclude) => exclude.matches(relative));
20119
20623
  const included = /* @__PURE__ */ new Map();
20120
20624
  /** A shared-traversal stop, materialized as this module's failure record. */
20121
20625
  const failureOf = (stop, pattern) => ({
@@ -20124,6 +20628,7 @@ const enumerate = (root, globs, options) => Effect.gen(function* () {
20124
20628
  detail: stop.detail
20125
20629
  });
20126
20630
  for (const literal of globs.literals) {
20631
+ if (isExcluded(literal)) continue;
20127
20632
  const absolute = path.join(root, literal);
20128
20633
  if (yield* isPackage(absolute)) included.set(literal, absolute);
20129
20634
  }
@@ -20151,26 +20656,23 @@ const enumerate = (root, globs, options) => Effect.gen(function* () {
20151
20656
  const absolute = path.join(frame.absolute, entry);
20152
20657
  if (!(yield* isDirectory(absolute))) continue;
20153
20658
  if (wildcard.crossesSegments && !traversal.admits(frame)) return yield* Effect.fail(failureOf(traversal.depthStop(), wildcard.source));
20154
- if (wildcard.matches(relative) && (yield* isPackage(absolute))) included.set(relative, absolute);
20659
+ if (wildcard.matches(relative) && !isExcluded(relative) && (yield* isPackage(absolute))) included.set(relative, absolute);
20155
20660
  if (!wildcard.crossesSegments) continue;
20156
20661
  traversal.push(frame, relative, absolute);
20157
20662
  }
20158
20663
  }
20159
20664
  }
20160
20665
  const results = [];
20161
- for (const [relativePath, absolute] of included) {
20162
- if (globs.excludes.some((exclude) => exclude.matches(relativePath))) continue;
20163
- results.push({
20164
- relativePath,
20165
- path: absolute
20166
- });
20167
- }
20666
+ for (const [relativePath, absolute] of included) results.push({
20667
+ relativePath,
20668
+ path: absolute
20669
+ });
20168
20670
  results.sort((a, b) => a.relativePath < b.relativePath ? -1 : a.relativePath > b.relativePath ? 1 : 0);
20169
20671
  return results;
20170
20672
  });
20171
20673
 
20172
20674
  //#endregion
20173
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/internal/patterns.js
20675
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.0_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/internal/patterns.js
20174
20676
  const stringsOf = (value) => Array.isArray(value) ? value.filter((entry) => typeof entry === "string") : void 0;
20175
20677
  /** The `packages:` list of a `pnpm-workspace.yaml` document. Total on a parsed document. */
20176
20678
  const pnpmPatternsOf = (document) => {
@@ -20228,7 +20730,7 @@ const readPatterns = (root) => Effect.gen(function* () {
20228
20730
  });
20229
20731
 
20230
20732
  //#endregion
20231
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/WorkspaceDiscovery.js
20733
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.0_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/WorkspaceDiscovery.js
20232
20734
  /**
20233
20735
  * Raised when a workspace member's `package.json` cannot be read, parsed, or
20234
20736
  * used — it is missing, malformed, or lacks a `name` or `version`.
@@ -20685,7 +21187,7 @@ var WorkspaceDiscovery = class WorkspaceDiscovery extends Context.Service()("@ef
20685
21187
  const isStringRecord$2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value) && Object.values(value).every((entry) => typeof entry === "string");
20686
21188
 
20687
21189
  //#endregion
20688
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/DependencyGraph.js
21190
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.0_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/DependencyGraph.js
20689
21191
  /**
20690
21192
  * Raised when the workspace dependency graph cannot be topologically ordered
20691
21193
  * because it contains a cycle.
@@ -24385,7 +24887,7 @@ var Git = class Git extends Context.Service()("@effected/git/Git") {
24385
24887
  };
24386
24888
 
24387
24889
  //#endregion
24388
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/ChangeDetector.js
24890
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.0_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/ChangeDetector.js
24389
24891
  /**
24390
24892
  * Which git refs to compare, and whether to fold in the working tree.
24391
24893
  *
@@ -24685,7 +25187,7 @@ function resolveFromCatalog(catalogs, wantedDependency) {
24685
25187
  }
24686
25188
 
24687
25189
  //#endregion
24688
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/internal/catalogs.js
25190
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.0_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/internal/catalogs.js
24689
25191
  /** Project a pnpm-workspace manifest's `catalog` / `catalogs` fields into a `Catalogs` map. */
24690
25192
  const inlineCatalogs = (manifest) => {
24691
25193
  if (manifest.catalog === void 0 && manifest.catalogs === void 0) return {};
@@ -24751,7 +25253,28 @@ const rangeOf = (catalogs, dependency, specifier) => {
24751
25253
  };
24752
25254
 
24753
25255
  //#endregion
24754
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/ConfigDependencyHooks.js
25256
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.0_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/ConfigDependencyHooks.js
25257
+ /**
25258
+ * The empty {@link PeerDependencyRules}: every axis present and empty.
25259
+ *
25260
+ * @remarks
25261
+ * Exported so that "I assert this workspace's rules are empty" is **one token**
25262
+ * rather than three hand-written empty axes. That matters where the distinction
25263
+ * is load-bearing — supplying rules asserts they were looked up, while omitting
25264
+ * them asserts nothing — and a caller spelling the object out by hand will
25265
+ * eventually fill two of the three axes and mean the third.
25266
+ *
25267
+ * Frozen, since it is shared.
25268
+ *
25269
+ * @public
25270
+ */
25271
+ const NoPeerDependencyRules = Object.freeze({
25272
+ allowedVersions: Object.freeze({}),
25273
+ ignoreMissing: Object.freeze([]),
25274
+ allowAny: Object.freeze([])
25275
+ });
25276
+ /** Internal alias, kept short at the many call sites in this module. */
25277
+ const NO_PEER_RULES = NoPeerDependencyRules;
24755
25278
  /** Whether `value` is a non-null, non-array object. */
24756
25279
  const isObject$2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
24757
25280
  /**
@@ -24779,7 +25302,7 @@ const moduleNotFoundUrl = (cause) => isObject$2(cause) && cause.code === "ERR_MO
24779
25302
  */
24780
25303
  const hasTraversalSegment = (name) => name.split(/[/\\]/).includes("..");
24781
25304
  /** Turn the seed record into the pnpm hook config, with the default catalog split out under `catalog`. */
24782
- const seedToConfig = (seed) => {
25305
+ const seedToConfig = (seed, rules) => {
24783
25306
  const catalogs = {};
24784
25307
  let catalog = {};
24785
25308
  for (const [name, entries] of Object.entries(seed)) if (name === "default") catalog = { ...entries };
@@ -24788,7 +25311,8 @@ const seedToConfig = (seed) => {
24788
25311
  catalog,
24789
25312
  catalogs,
24790
25313
  minimumReleaseAge: void 0,
24791
- minimumReleaseAgeExclude: void 0
25314
+ minimumReleaseAgeExclude: void 0,
25315
+ peerDependencyRules: rules
24792
25316
  };
24793
25317
  };
24794
25318
  /** A finite number if `value` is one, else the prior threaded value — a garbage age is dropped, not fatal. */
@@ -24813,10 +25337,33 @@ const configOf = (value, fallback) => {
24813
25337
  catalog: isObject$2(value.catalog) ? value.catalog : fallback.catalog,
24814
25338
  catalogs: isObject$2(value.catalogs) ? value.catalogs : fallback.catalogs,
24815
25339
  minimumReleaseAge: finiteNumberOr(value.minimumReleaseAge, fallback.minimumReleaseAge),
24816
- minimumReleaseAgeExclude: stringArrayOr(value.minimumReleaseAgeExclude, fallback.minimumReleaseAgeExclude)
25340
+ minimumReleaseAgeExclude: stringArrayOr(value.minimumReleaseAgeExclude, fallback.minimumReleaseAgeExclude),
25341
+ peerDependencyRules: peerRulesOr(value.peerDependencyRules, fallback.peerDependencyRules)
24817
25342
  };
24818
25343
  };
24819
25344
  /**
25345
+ * A peer-rules block if `value` is one, else the prior threaded value — a
25346
+ * malformed block is dropped, not fatal, matching the other slices.
25347
+ *
25348
+ * Each axis is normalized independently: a hook that rewrites `allowedVersions`
25349
+ * and leaves `ignoreMissing` alone must not blank the latter.
25350
+ */
25351
+ const stringRecordOr = (value, fallback) => isObject$2(value) && Object.values(value).every((entry) => typeof entry === "string") ? value : fallback;
25352
+ const peerRulesOr = (value, fallback) => {
25353
+ if (!isObject$2(value)) return fallback;
25354
+ const allowed = stringRecordOr(value.allowedVersions, fallback?.allowedVersions);
25355
+ const ignoreMissing = stringArrayOr(value.ignoreMissing, fallback?.ignoreMissing);
25356
+ const allowAny = stringArrayOr(value.allowAny, fallback?.allowAny);
25357
+ if (allowed === void 0 && ignoreMissing === void 0 && allowAny === void 0) return fallback;
25358
+ return {
25359
+ allowedVersions: allowed ?? {},
25360
+ ignoreMissing: ignoreMissing ?? [],
25361
+ allowAny: allowAny ?? []
25362
+ };
25363
+ };
25364
+ /** Project the threaded config's rules into the slice, defaulting every axis to empty. */
25365
+ const peerRulesOf = (config) => config.peerDependencyRules ?? NO_PEER_RULES;
25366
+ /**
24820
25367
  * Project the threaded config's release-age keys into a partial gate
24821
25368
  * contribution, omitting a key the hooks never set (never an explicit
24822
25369
  * `undefined` — the fields are `optionalKey`).
@@ -24869,13 +25416,23 @@ const updateConfigOf = (mod) => {
24869
25416
  * noise on stdout.
24870
25417
  */
24871
25418
  const REPLAY_SCRIPT = `
24872
- const [root, seedJson, ...names] = process.argv.slice(1);
25419
+ const [root, seedJson, rulesJson, ...names] = process.argv.slice(1);
24873
25420
  const { pathToFileURL } = await import("node:url");
24874
25421
  const { join } = await import("node:path");
24875
25422
  const isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
24876
25423
  const finiteNumberOr = (value, fallback) => (typeof value === "number" && Number.isFinite(value) ? value : fallback);
24877
25424
  const stringArrayOr = (value, fallback) =>
24878
25425
  Array.isArray(value) && value.every((entry) => typeof entry === "string") ? value : fallback;
25426
+ const stringRecordOr = (value, fallback) =>
25427
+ isObject(value) && Object.values(value).every((entry) => typeof entry === "string") ? value : fallback;
25428
+ const peerRulesOr = (value, fallback) => {
25429
+ if (!isObject(value)) return fallback;
25430
+ const allowed = stringRecordOr(value.allowedVersions, fallback && fallback.allowedVersions);
25431
+ const ignoreMissing = stringArrayOr(value.ignoreMissing, fallback && fallback.ignoreMissing);
25432
+ const allowAny = stringArrayOr(value.allowAny, fallback && fallback.allowAny);
25433
+ if (allowed === undefined && ignoreMissing === undefined && allowAny === undefined) return fallback;
25434
+ return { allowedVersions: allowed || {}, ignoreMissing: ignoreMissing || [], allowAny: allowAny || [] };
25435
+ };
24879
25436
  const configOf = (value, fallback) =>
24880
25437
  isObject(value)
24881
25438
  ? {
@@ -24883,6 +25440,7 @@ const configOf = (value, fallback) =>
24883
25440
  catalogs: isObject(value.catalogs) ? value.catalogs : fallback.catalogs,
24884
25441
  minimumReleaseAge: finiteNumberOr(value.minimumReleaseAge, fallback.minimumReleaseAge),
24885
25442
  minimumReleaseAgeExclude: stringArrayOr(value.minimumReleaseAgeExclude, fallback.minimumReleaseAgeExclude),
25443
+ peerDependencyRules: peerRulesOr(value.peerDependencyRules, fallback.peerDependencyRules),
24886
25444
  }
24887
25445
  : fallback;
24888
25446
  const failure = (name, cause) => ({
@@ -24898,7 +25456,13 @@ const replay = async () => {
24898
25456
  if (name === "default") catalog = { ...entries };
24899
25457
  else catalogs[name] = { ...entries };
24900
25458
  }
24901
- let config = { catalog, catalogs, minimumReleaseAge: undefined, minimumReleaseAgeExclude: undefined };
25459
+ let config = {
25460
+ catalog,
25461
+ catalogs,
25462
+ minimumReleaseAge: undefined,
25463
+ minimumReleaseAgeExclude: undefined,
25464
+ peerDependencyRules: JSON.parse(rulesJson),
25465
+ };
24902
25466
  for (const name of names) {
24903
25467
  let loaded;
24904
25468
  let found = false;
@@ -24999,9 +25563,10 @@ var ConfigDependencyHooks = class ConfigDependencyHooks extends Context.Service(
24999
25563
  * config dependency. The default {@link WorkspaceCatalogs} layer wires this, so
25000
25564
  * the default catalog path provably executes no config-dependency code.
25001
25565
  */
25002
- static layerNoop = Layer.succeed(ConfigDependencyHooks, { inject: (_root, _configDependencies, seed) => Effect.succeed({
25566
+ static layerNoop = Layer.succeed(ConfigDependencyHooks, { inject: (_root, _configDependencies, seed, rules) => Effect.succeed({
25003
25567
  catalogs: seed,
25004
- releaseAge: {}
25568
+ releaseAge: {},
25569
+ peerDependencyRules: rules ?? NO_PEER_RULES
25005
25570
  }) });
25006
25571
  /**
25007
25572
  * The live layer: dynamically imports each config dependency's `pnpmfile.cjs`
@@ -25019,13 +25584,14 @@ var ConfigDependencyHooks = class ConfigDependencyHooks extends Context.Service(
25019
25584
  * import, so this layer runs on either runtime. Only ever wired by
25020
25585
  * `WorkspaceCatalogs.layerWithConfigDependencies`.
25021
25586
  */
25022
- static layerLive = Layer.succeed(ConfigDependencyHooks, { inject: (root, configDependencies, seed) => Effect.gen(function* () {
25587
+ static layerLive = Layer.succeed(ConfigDependencyHooks, { inject: (root, configDependencies, seed, rules) => Effect.gen(function* () {
25023
25588
  const names = Object.keys(configDependencies);
25024
25589
  if (names.length === 0) return {
25025
25590
  catalogs: seed,
25026
- releaseAge: {}
25591
+ releaseAge: {},
25592
+ peerDependencyRules: rules ?? NO_PEER_RULES
25027
25593
  };
25028
- let config = seedToConfig(seed);
25594
+ let config = seedToConfig(seed, rules);
25029
25595
  for (const name of names) {
25030
25596
  if (hasTraversalSegment(name)) return yield* Effect.fail(new CatalogAssemblyError({
25031
25597
  source: "hooks",
@@ -25071,7 +25637,8 @@ var ConfigDependencyHooks = class ConfigDependencyHooks extends Context.Service(
25071
25637
  }
25072
25638
  return {
25073
25639
  catalogs: configToEntries(config),
25074
- releaseAge: releaseAgeOf(config)
25640
+ releaseAge: releaseAgeOf(config),
25641
+ peerDependencyRules: peerRulesOf(config)
25075
25642
  };
25076
25643
  }) });
25077
25644
  /**
@@ -25127,11 +25694,12 @@ var ConfigDependencyHooks = class ConfigDependencyHooks extends Context.Service(
25127
25694
  */
25128
25695
  static layerSubprocess = Layer.effect(ConfigDependencyHooks, Effect.gen(function* () {
25129
25696
  const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
25130
- return { inject: (root, configDependencies, seed) => Effect.gen(function* () {
25697
+ return { inject: (root, configDependencies, seed, rules) => Effect.gen(function* () {
25131
25698
  const names = Object.keys(configDependencies);
25132
25699
  if (names.length === 0) return {
25133
25700
  catalogs: seed,
25134
- releaseAge: {}
25701
+ releaseAge: {},
25702
+ peerDependencyRules: rules ?? NO_PEER_RULES
25135
25703
  };
25136
25704
  for (const name of names) if (hasTraversalSegment(name)) return yield* Effect.fail(new CatalogAssemblyError({
25137
25705
  source: "hooks",
@@ -25144,6 +25712,7 @@ var ConfigDependencyHooks = class ConfigDependencyHooks extends Context.Service(
25144
25712
  REPLAY_SCRIPT,
25145
25713
  root,
25146
25714
  JSON.stringify(seed),
25715
+ JSON.stringify(rules ?? NO_PEER_RULES),
25147
25716
  ...names
25148
25717
  ]);
25149
25718
  const payload = yield* Run.jsonLine(command, ReplayPayload, { timeout: REPLAY_TIMEOUT }).pipe(Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner), Effect.catch((cause) => Effect.fail(new CatalogAssemblyError({
@@ -25156,17 +25725,18 @@ var ConfigDependencyHooks = class ConfigDependencyHooks extends Context.Service(
25156
25725
  path: payload.name ?? root,
25157
25726
  cause: replayFailureCause(payload)
25158
25727
  }));
25159
- const config = configOf(payload.config, seedToConfig(seed));
25728
+ const config = configOf(payload.config, seedToConfig(seed, rules));
25160
25729
  return {
25161
25730
  catalogs: configToEntries(config),
25162
- releaseAge: releaseAgeOf(config)
25731
+ releaseAge: releaseAgeOf(config),
25732
+ peerDependencyRules: peerRulesOf(config)
25163
25733
  };
25164
25734
  }) };
25165
25735
  }));
25166
25736
  };
25167
25737
 
25168
25738
  //#endregion
25169
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/PackageManagerName.js
25739
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.0_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/PackageManagerName.js
25170
25740
  /**
25171
25741
  * The four package managers this package understands.
25172
25742
  *
@@ -25542,7 +26112,7 @@ var PackageManagerDetector = class PackageManagerDetector extends Context.Servic
25542
26112
  };
25543
26113
 
25544
26114
  //#endregion
25545
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/LockfileReader.js
26115
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.0_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/LockfileReader.js
25546
26116
  /**
25547
26117
  * Raised when the workspace's lockfile cannot be read off disk.
25548
26118
  *
@@ -25723,7 +26293,7 @@ var LockfileReader = class LockfileReader extends Context.Service()("@effected/w
25723
26293
  };
25724
26294
 
25725
26295
  //#endregion
25726
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/Publishability.js
26296
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.0_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/Publishability.js
25727
26297
  /** The public npm registry, used when `publishConfig.registry` says nothing. */
25728
26298
  const DEFAULT_REGISTRY = "https://registry.npmjs.org/";
25729
26299
  /**
@@ -25883,7 +26453,7 @@ var PublishabilityDetector = class extends Context.Service()("@effected/workspac
25883
26453
  };
25884
26454
 
25885
26455
  //#endregion
25886
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/internal/importerVersions.js
26456
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.0_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/internal/importerVersions.js
25887
26457
  /**
25888
26458
  * Strip pnpm's peer-disambiguation suffix from a recorded importer version.
25889
26459
  *
@@ -25970,7 +26540,7 @@ const unanimousVersionOf = (index, dependency) => {
25970
26540
  };
25971
26541
 
25972
26542
  //#endregion
25973
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/WorkspaceCatalogs.js
26543
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.0_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/WorkspaceCatalogs.js
25974
26544
  /**
25975
26545
  * An immutable, fully-normalized catalog collection — the one catalog
25976
26546
  * resolution semantic in the package.
@@ -26174,6 +26744,41 @@ const inlineReleaseAge = (document) => {
26174
26744
  cause
26175
26745
  })));
26176
26746
  };
26747
+ /**
26748
+ * The `peerDependencyRules` a `pnpm-workspace.yaml` declares inline — the half
26749
+ * `pnpm:export` materializes into the file, as opposed to the half a config
26750
+ * dependency injects at replay time.
26751
+ *
26752
+ * @remarks
26753
+ * **Tolerant, unlike the catalog blocks**, and the asymmetry is deliberate: a
26754
+ * malformed catalog block must hard-fail because a silently-empty catalog makes
26755
+ * every dependency look newly added, whereas a malformed rules block costs only
26756
+ * suppression — the failure mode is reporting a peer pnpm would have hidden,
26757
+ * which is visible and safe. Failing the whole assembly over it would take the
26758
+ * catalogs down with it.
26759
+ *
26760
+ * Every axis is read independently, so a malformed `ignoreMissing` does not
26761
+ * discard a well-formed `allowedVersions`.
26762
+ */
26763
+ const EMPTY_PEER_RULES = {
26764
+ allowedVersions: {},
26765
+ ignoreMissing: [],
26766
+ allowAny: []
26767
+ };
26768
+ const inlinePeerDependencyRules = (document) => {
26769
+ if (!isObject$1(document) || !isObject$1(document.peerDependencyRules)) return EMPTY_PEER_RULES;
26770
+ const block = document.peerDependencyRules;
26771
+ const allowedVersions = {};
26772
+ if (isObject$1(block.allowedVersions)) {
26773
+ for (const [key, value] of Object.entries(block.allowedVersions)) if (typeof value === "string") allowedVersions[key] = value;
26774
+ }
26775
+ const strings = (value) => Array.isArray(value) ? value.filter((entry) => typeof entry === "string") : [];
26776
+ return {
26777
+ allowedVersions,
26778
+ ignoreMissing: strings(block.ignoreMissing),
26779
+ allowAny: strings(block.allowAny)
26780
+ };
26781
+ };
26177
26782
  /** A hard-fail catalog-assembly failure naming the malformed part of a `workspaces` field. */
26178
26783
  const malformed = (source, path, detail) => new CatalogAssemblyError({
26179
26784
  source,
@@ -26306,6 +26911,7 @@ var WorkspaceCatalogs = class WorkspaceCatalogs extends Context.Service()("@effe
26306
26911
  let injected;
26307
26912
  let inlineGate = {};
26308
26913
  let hookGate = {};
26914
+ let peerDependencyRules = EMPTY_PEER_RULES;
26309
26915
  if (hasPnpmWorkspace) {
26310
26916
  const text = yield* fs.readFileString(workspaceYaml).pipe(Effect.mapError((cause) => new CatalogAssemblyError({
26311
26917
  source: "manifest",
@@ -26320,15 +26926,17 @@ var WorkspaceCatalogs = class WorkspaceCatalogs extends Context.Service()("@effe
26320
26926
  yield* validatePnpmWorkspaceCatalogs(document);
26321
26927
  inline = CatalogSet.fromCatalogs(inlineCatalogs(catalogBlocksOf(document)));
26322
26928
  inlineGate = yield* inlineReleaseAge(document);
26323
- const injection = yield* hooks.inject(root, configDependenciesOf(document), inline.entries);
26929
+ const injection = yield* hooks.inject(root, configDependenciesOf(document), inline.entries, inlinePeerDependencyRules(document));
26324
26930
  injected = CatalogSet.fromCatalogs(injection.catalogs);
26325
26931
  hookGate = injection.releaseAge;
26932
+ peerDependencyRules = injection.peerDependencyRules;
26326
26933
  } else {
26327
26934
  const manifestPath = path.join(root, "package.json");
26328
26935
  if (!(yield* probeExists(manifestPath))) return {
26329
26936
  catalogs: fromLockfile,
26330
26937
  releaseAgeGate: ReleaseAgeGate.combine(),
26331
- importerVersions
26938
+ importerVersions,
26939
+ peerDependencyRules: EMPTY_PEER_RULES
26332
26940
  };
26333
26941
  const text = yield* fs.readFileString(manifestPath).pipe(Effect.mapError((cause) => new CatalogAssemblyError({
26334
26942
  source: "manifest",
@@ -26348,7 +26956,8 @@ var WorkspaceCatalogs = class WorkspaceCatalogs extends Context.Service()("@effe
26348
26956
  return {
26349
26957
  catalogs: assembled,
26350
26958
  releaseAgeGate,
26351
- importerVersions
26959
+ importerVersions,
26960
+ peerDependencyRules
26352
26961
  };
26353
26962
  });
26354
26963
  const [resolveOnce, invalidate] = yield* Effect.cachedInvalidateWithTTL(assemble, Duration.infinity);
@@ -26360,6 +26969,9 @@ var WorkspaceCatalogs = class WorkspaceCatalogs extends Context.Service()("@effe
26360
26969
  resolveSpecifier: Effect.fn("WorkspaceCatalogs.resolveSpecifier")(function* (dependency, specifier) {
26361
26970
  return (yield* memo).catalogs.resolveSpecifier(dependency, specifier);
26362
26971
  }),
26972
+ peerDependencyRules: Effect.fn("WorkspaceCatalogs.peerDependencyRules")(function* () {
26973
+ return (yield* memo).peerDependencyRules;
26974
+ }),
26363
26975
  releaseAgeGate: Effect.fn("WorkspaceCatalogs.releaseAgeGate")(function* () {
26364
26976
  return (yield* memo).releaseAgeGate;
26365
26977
  }),
@@ -26446,6 +27058,7 @@ var WorkspaceCatalogs = class WorkspaceCatalogs extends Context.Service()("@effe
26446
27058
  return {
26447
27059
  set: () => unstubbed$1("set"),
26448
27060
  resolveSpecifier: set !== void 0 ? (dependency, specifier) => Effect.map(set(), (catalogs) => catalogs.resolveSpecifier(dependency, specifier)) : () => unstubbed$1("resolveSpecifier"),
27061
+ peerDependencyRules: () => unstubbed$1("peerDependencyRules"),
26449
27062
  releaseAgeGate: () => unstubbed$1("releaseAgeGate"),
26450
27063
  importerVersions: () => unstubbed$1("importerVersions"),
26451
27064
  ...overrides
@@ -26498,7 +27111,7 @@ var WorkspaceCatalogs = class WorkspaceCatalogs extends Context.Service()("@effe
26498
27111
  };
26499
27112
 
26500
27113
  //#endregion
26501
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/WorkspaceStateSnapshot.js
27114
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.0_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/WorkspaceStateSnapshot.js
26502
27115
  const EMPTY = Object.freeze(Object.create(null));
26503
27116
  const DependencyMap = Schema.Record(Schema.String, Schema.String).pipe(Schema.withDecodingDefaultKey(Effect.succeed(EMPTY)), Schema.withConstructorDefault(Effect.succeed(EMPTY)));
26504
27117
  /**
@@ -26722,7 +27335,7 @@ var WorkspaceStateSnapshot = class extends Schema.Class("WorkspaceStateSnapshot"
26722
27335
  };
26723
27336
 
26724
27337
  //#endregion
26725
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/WorkspaceSnapshots.js
27338
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.0_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/WorkspaceSnapshots.js
26726
27339
  /** Whether `value` is a non-null, non-array object. */
26727
27340
  const isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
26728
27341
  /** Whether every value in a record is a string — a usable dependency map. */
@@ -27000,7 +27613,7 @@ var WorkspaceSnapshots = class WorkspaceSnapshots extends Context.Service()("@ef
27000
27613
  };
27001
27614
 
27002
27615
  //#endregion
27003
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.14.2_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/Workspaces.js
27616
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.0_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/Workspaces.js
27004
27617
  const compose = (options, catalogsFactory) => {
27005
27618
  const roots = WorkspaceRoot.layer;
27006
27619
  const detector = PackageManagerDetector.layer;