@savvy-web/silk 3.2.1 → 3.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -16673,7 +16673,7 @@ var Package = class Package extends effect.Schema.Class("Package")({
16673
16673
  }
16674
16674
  };
16675
16675
  //#endregion
16676
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.6.2_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspacePackage.js
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
16677
16677
  const EMPTY$1 = Object.freeze(Object.create(null));
16678
16678
  const EMPTY_MANIFEST = Object.freeze(Object.create(null));
16679
16679
  /**
@@ -17278,7 +17278,7 @@ const Walker$1 = {
17278
17278
  findRoot: findRoot$1
17279
17279
  };
17280
17280
  //#endregion
17281
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.6.2_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspaceRoot.js
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
17282
17282
  /**
17283
17283
  * The marker filenames {@link WorkspaceRoot} probes for, in priority order.
17284
17284
  *
@@ -17465,7 +17465,7 @@ var WorkspaceRoot = class WorkspaceRoot extends effect.Context.Service()("@effec
17465
17465
  static layerTest = (root) => effect.Layer.effect(WorkspaceRoot, WorkspaceRoot.makeTest(root)).pipe(effect.Layer.provide(effect.Path.layer));
17466
17466
  };
17467
17467
  //#endregion
17468
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.6.2_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/limits.js
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
17469
17469
  /**
17470
17470
  * Hard ceiling on directories the enumerator will visit for one pattern set.
17471
17471
  * Guards the pathological case a depth cap alone does not: a wide, shallow
@@ -17483,7 +17483,7 @@ const MAX_ENUMERATION_ENTRIES = 1e5;
17483
17483
  */
17484
17484
  const PRUNED_DIRECTORIES = /* @__PURE__ */ new Set([".git", "node_modules"]);
17485
17485
  //#endregion
17486
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.6.2_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/traverse.js
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
17487
17487
  /** Directory names never descended into. */
17488
17488
  const isPruned = (entry) => PRUNED_DIRECTORIES.has(entry);
17489
17489
  /** Join root-relative POSIX segments; `""` is the root itself. */
@@ -17573,7 +17573,7 @@ var Traversal = class {
17573
17573
  }
17574
17574
  };
17575
17575
  //#endregion
17576
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.6.2_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/enumerate.js
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
17577
17577
  /** Strip a trailing slash from `GlobPattern.enumerationPrefix` to get a relative directory. */
17578
17578
  const baseOf = (pattern) => pattern.enumerationPrefix.replace(/\/$/, "");
17579
17579
  /**
@@ -17643,7 +17643,7 @@ const enumerate = (root, globs, options) => effect.Effect.gen(function* () {
17643
17643
  return results;
17644
17644
  });
17645
17645
  //#endregion
17646
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.6.2_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/patterns.js
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
17647
17647
  const stringsOf = (value) => Array.isArray(value) ? value.filter((entry) => typeof entry === "string") : void 0;
17648
17648
  /** The `packages:` list of a `pnpm-workspace.yaml` document. Total on a parsed document. */
17649
17649
  const pnpmPatternsOf = (document) => {
@@ -17700,7 +17700,7 @@ const readPatterns = (root) => effect.Effect.gen(function* () {
17700
17700
  return manifestPatternsOf(manifest);
17701
17701
  });
17702
17702
  //#endregion
17703
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.6.2_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspaceDiscovery.js
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
17704
17704
  /**
17705
17705
  * Raised when a workspace member's `package.json` cannot be read, parsed, or
17706
17706
  * used — it is missing, malformed, or lacks a `name` or `version`.
@@ -18134,7 +18134,7 @@ var WorkspaceDiscovery = class WorkspaceDiscovery extends effect.Context.Service
18134
18134
  };
18135
18135
  const isStringRecord$2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value) && Object.values(value).every((entry) => typeof entry === "string");
18136
18136
  //#endregion
18137
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.6.2_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/DependencyGraph.js
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
18138
18138
  /**
18139
18139
  * Raised when the workspace dependency graph cannot be topologically ordered
18140
18140
  * because it contains a cycle.
@@ -19732,7 +19732,7 @@ var Git = class extends effect.Context.Service()("@effected/git/Git") {
19732
19732
  }));
19733
19733
  };
19734
19734
  //#endregion
19735
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.6.2_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/ChangeDetector.js
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
19736
19736
  /**
19737
19737
  * Which git refs to compare, and whether to fold in the working tree.
19738
19738
  *
@@ -19984,7 +19984,7 @@ function resolveFromCatalog(catalogs, wantedDependency) {
19984
19984
  };
19985
19985
  }
19986
19986
  //#endregion
19987
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.6.2_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/catalogs.js
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
19988
19988
  /** Project a pnpm-workspace manifest's `catalog` / `catalogs` fields into a `Catalogs` map. */
19989
19989
  const inlineCatalogs = (manifest) => {
19990
19990
  if (manifest.catalog === void 0 && manifest.catalogs === void 0) return {};
@@ -20048,7 +20048,7 @@ const rangeOf = (catalogs, dependency, specifier) => {
20048
20048
  });
20049
20049
  };
20050
20050
  //#endregion
20051
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.6.2_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/ConfigDependencyHooks.js
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
20052
20052
  /** Whether `value` is a non-null, non-array object. */
20053
20053
  const isObject$2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
20054
20054
  /**
@@ -20234,7 +20234,7 @@ var ConfigDependencyHooks = class ConfigDependencyHooks extends effect.Context.S
20234
20234
  }) });
20235
20235
  };
20236
20236
  //#endregion
20237
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.6.2_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/PackageManagerName.js
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
20238
20238
  /**
20239
20239
  * The four package managers this package understands.
20240
20240
  *
@@ -20476,7 +20476,7 @@ var PackageManagerDetector = class PackageManagerDetector extends effect.Context
20476
20476
  static layer = effect.Layer.effect(PackageManagerDetector, PackageManagerDetector.make);
20477
20477
  };
20478
20478
  //#endregion
20479
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.6.2_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/LockfileReader.js
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
20480
20480
  /**
20481
20481
  * Raised when the workspace's lockfile cannot be read off disk.
20482
20482
  *
@@ -20586,7 +20586,7 @@ var LockfileReader = class LockfileReader extends effect.Context.Service()("@eff
20586
20586
  static layer = (options) => effect.Layer.effect(LockfileReader, LockfileReader.make(options));
20587
20587
  };
20588
20588
  //#endregion
20589
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.6.2_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/Publishability.js
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
20590
20590
  /** The public npm registry, used when `publishConfig.registry` says nothing. */
20591
20591
  const DEFAULT_REGISTRY = "https://registry.npmjs.org/";
20592
20592
  /**
@@ -20686,7 +20686,93 @@ var PublishabilityDetector = class PublishabilityDetector extends effect.Context
20686
20686
  }) });
20687
20687
  };
20688
20688
  //#endregion
20689
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.6.2_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspaceCatalogs.js
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
20690
+ /**
20691
+ * Strip pnpm's peer-disambiguation suffix from a recorded importer version.
20692
+ *
20693
+ * pnpm records an importer version as the resolved version followed by the peer
20694
+ * context it was resolved under — `4.0.0-beta.101(effect@4.0.0-beta.101)(ioredis@5.11.1(supports-color@8.1.1))`.
20695
+ * `@effected/lockfiles` stores that string verbatim (its `packages:` key parser
20696
+ * strips the suffix; the importer entries deliberately keep it), so the raw
20697
+ * value must never reach a consumer's dependency table — it would render the
20698
+ * whole parenthesized chain as the "version" a dependency moved to.
20699
+ *
20700
+ * Everything from the first `(` is dropped; a version with no suffix passes
20701
+ * through untouched.
20702
+ */
20703
+ const stripPeerSuffix = (version) => {
20704
+ const paren = version.indexOf("(");
20705
+ return paren === -1 ? version : version.slice(0, paren);
20706
+ };
20707
+ /**
20708
+ * Whether a recorded importer version is a concrete version usable as a
20709
+ * resolution answer.
20710
+ *
20711
+ * A `link:` / `file:` entry records a filesystem edge rather than a version, and
20712
+ * an empty string is pnpm's "specifier only, nothing installed" marker. Both
20713
+ * would be worse than no answer at all: the fallback exists to report a concrete
20714
+ * version movement, and reporting `link:../foo` as a version is noise a
20715
+ * changeset would carry into release notes.
20716
+ */
20717
+ const isConcreteVersion = (version) => version.length > 0 && !version.startsWith("link:") && !version.startsWith("file:");
20718
+ /**
20719
+ * Build the importer-path → dependency-name → version index a snapshot uses to
20720
+ * answer `catalog:` specifiers its catalog set cannot resolve.
20721
+ *
20722
+ * @remarks
20723
+ * Keyed by **name only** within each importer, deliberately across every
20724
+ * dependency field. The bug this fixes is a peer declared `catalog:effect:peers`
20725
+ * whose importer records no `peerDependencies` entry at all — pnpm writes peer
20726
+ * declarations into the importer block only when they are also installed, so the
20727
+ * concrete version lives on the package's `devDependencies` row for the same
20728
+ * name. Joining by name across fields is what finds it; joining by field, or by
20729
+ * matching the recorded specifier, would not.
20730
+ *
20731
+ * Only pnpm populates importer versions; bun and npm record resolved versions on
20732
+ * their package entries instead, so those formats yield an empty index and the
20733
+ * fallback is inert for them.
20734
+ */
20735
+ const importerVersionsOf = (lockfile) => {
20736
+ const index = Object.create(null);
20737
+ for (const importer of lockfile.importers) {
20738
+ const versions = Object.create(null);
20739
+ for (const dependency of importer.dependencies) {
20740
+ const recorded = dependency.version;
20741
+ if (recorded === void 0) continue;
20742
+ const version = stripPeerSuffix(recorded);
20743
+ if (!isConcreteVersion(version)) continue;
20744
+ versions[dependency.name] ??= version;
20745
+ }
20746
+ index[importer.path] = versions;
20747
+ }
20748
+ return index;
20749
+ };
20750
+ /**
20751
+ * The version every importer agrees `dependency` resolved to, or `undefined`
20752
+ * when they disagree or none record it.
20753
+ *
20754
+ * @remarks
20755
+ * The unambiguity rule is what makes a workspace-wide answer safe from a
20756
+ * snapshot method that receives no importer context. Two packages in one
20757
+ * monorepo may legitimately hold different versions of the same dependency; in
20758
+ * that case there is no single correct answer, so this yields nothing and the
20759
+ * caller keeps today's behavior (no row) rather than inventing a wrong one.
20760
+ */
20761
+ const unanimousVersionOf = (index, dependency) => {
20762
+ let agreed;
20763
+ for (const versions of Object.values(index)) {
20764
+ const version = versions[dependency];
20765
+ if (version === void 0) continue;
20766
+ if (agreed === void 0) {
20767
+ agreed = version;
20768
+ continue;
20769
+ }
20770
+ if (agreed !== version) return void 0;
20771
+ }
20772
+ return agreed;
20773
+ };
20774
+ //#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
20690
20776
  /**
20691
20777
  * An immutable, fully-normalized catalog collection — the one catalog
20692
20778
  * resolution semantic in the package.
@@ -21005,7 +21091,15 @@ var WorkspaceCatalogs = class WorkspaceCatalogs extends effect.Context.Service()
21005
21091
  }));
21006
21092
  const assemble = effect.Effect.gen(function* () {
21007
21093
  const root = yield* effect.Effect.suspend(() => roots.find(options?.cwd ?? process.cwd()));
21008
- const fromLockfile = yield* lockfiles.read().pipe(effect.Effect.map(CatalogSet.fromLockfile), effect.Effect.catch((_failure) => effect.Effect.succeed(CatalogSet.empty())));
21094
+ const lockfileOutputs = yield* lockfiles.read().pipe(effect.Effect.map((lockfile) => ({
21095
+ catalogs: CatalogSet.fromLockfile(lockfile),
21096
+ importerVersions: importerVersionsOf(lockfile)
21097
+ })), effect.Effect.catch((_failure) => effect.Effect.succeed({
21098
+ catalogs: CatalogSet.empty(),
21099
+ importerVersions: {}
21100
+ })));
21101
+ const fromLockfile = lockfileOutputs.catalogs;
21102
+ const importerVersions = lockfileOutputs.importerVersions;
21009
21103
  const workspaceYaml = path.join(root, "pnpm-workspace.yaml");
21010
21104
  const hasPnpmWorkspace = yield* probeExists(workspaceYaml);
21011
21105
  let inline;
@@ -21033,7 +21127,8 @@ var WorkspaceCatalogs = class WorkspaceCatalogs extends effect.Context.Service()
21033
21127
  const manifestPath = path.join(root, "package.json");
21034
21128
  if (!(yield* probeExists(manifestPath))) return {
21035
21129
  catalogs: fromLockfile,
21036
- releaseAgeGate: ReleaseAgeGate.combine()
21130
+ releaseAgeGate: ReleaseAgeGate.combine(),
21131
+ importerVersions
21037
21132
  };
21038
21133
  const text = yield* fs.readFileString(manifestPath).pipe(effect.Effect.mapError((cause) => new CatalogAssemblyError({
21039
21134
  source: "manifest",
@@ -21052,7 +21147,8 @@ var WorkspaceCatalogs = class WorkspaceCatalogs extends effect.Context.Service()
21052
21147
  }));
21053
21148
  return {
21054
21149
  catalogs: assembled,
21055
- releaseAgeGate
21150
+ releaseAgeGate,
21151
+ importerVersions
21056
21152
  };
21057
21153
  });
21058
21154
  const [resolveOnce, invalidate] = yield* effect.Effect.cachedInvalidateWithTTL(assemble, effect.Duration.infinity);
@@ -21066,6 +21162,9 @@ var WorkspaceCatalogs = class WorkspaceCatalogs extends effect.Context.Service()
21066
21162
  }),
21067
21163
  releaseAgeGate: effect.Effect.fn("WorkspaceCatalogs.releaseAgeGate")(function* () {
21068
21164
  return (yield* memo).releaseAgeGate;
21165
+ }),
21166
+ importerVersions: effect.Effect.fn("WorkspaceCatalogs.importerVersions")(function* () {
21167
+ return (yield* memo).importerVersions;
21069
21168
  })
21070
21169
  };
21071
21170
  });
@@ -21116,7 +21215,7 @@ var WorkspaceCatalogs = class WorkspaceCatalogs extends effect.Context.Service()
21116
21215
  }));
21117
21216
  };
21118
21217
  //#endregion
21119
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.6.2_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspaceStateSnapshot.js
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
21120
21219
  const EMPTY = Object.freeze(Object.create(null));
21121
21220
  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)));
21122
21221
  /**
@@ -21200,7 +21299,19 @@ var WorkspaceStateSnapshot = class extends effect.Schema.Class("WorkspaceStateSn
21200
21299
  /** Every workspace package captured at this moment. */
21201
21300
  packages: effect.Schema.Array(PackageStateSnapshot),
21202
21301
  /** The catalog set assembled at this moment. */
21203
- catalogs: CatalogSet
21302
+ catalogs: CatalogSet,
21303
+ /**
21304
+ * Each importer's dependency-name → resolved-version map, as the manager's
21305
+ * lockfile recorded it at this moment.
21306
+ *
21307
+ * @remarks
21308
+ * Defaults to `{}`, so a `WorkspaceStateSnapshot` serialized before this field
21309
+ * existed still decodes — and an empty index simply makes the `catalog:`
21310
+ * fallback in {@link WorkspaceStateSnapshot.resolve} inert, which is exactly
21311
+ * the behavior those older values were captured under. Only pnpm records
21312
+ * importer versions; bun and npm yield an empty index.
21313
+ */
21314
+ importerVersions: effect.Schema.optionalKey(effect.Schema.Record(effect.Schema.String, effect.Schema.Record(effect.Schema.String, effect.Schema.String)))
21204
21315
  }) {
21205
21316
  #versionIndex;
21206
21317
  #packageIndex;
@@ -21235,16 +21346,62 @@ var WorkspaceStateSnapshot = class extends effect.Schema.Class("WorkspaceStateSn
21235
21346
  * unparseable string — is `Option.none()`, because there is no indirection to
21236
21347
  * resolve. Total.
21237
21348
  *
21349
+ * A `catalog:` specifier the catalog set cannot resolve falls back to this
21350
+ * snapshot's `importerVersions` — but only to a version
21351
+ * **every** importer recording that dependency agrees on. A catalog injected
21352
+ * by a config-dependency pnpmfile hook appears in no committed catalog source,
21353
+ * so without this fallback both sides of a before/after diff resolve it to the
21354
+ * same raw string and a real version movement produces no row. When importers
21355
+ * disagree there is no single correct answer, so this stays `Option.none()`
21356
+ * rather than inventing one; {@link WorkspaceStateSnapshot.resolveIn} answers
21357
+ * precisely for callers that know which importer is asking.
21358
+ *
21238
21359
  * @param dependency - The dependency's package name (what `workspace:` /
21239
21360
  * `catalog:` resolve for).
21240
21361
  * @param specifier - The raw specifier string.
21241
21362
  */
21242
21363
  resolve(dependency, specifier) {
21364
+ return this.#resolveWith(dependency, specifier, () => effect.Option.fromUndefinedOr(unanimousVersionOf(this.importerVersions ?? {}, dependency)));
21365
+ }
21366
+ /**
21367
+ * The concrete range or version a specifier resolved to AS OF this snapshot,
21368
+ * scoped to the importer that declared it.
21369
+ *
21370
+ * @remarks
21371
+ * Identical to {@link WorkspaceStateSnapshot.resolve} except in how an
21372
+ * unresolvable `catalog:` specifier falls back: this consults **only**
21373
+ * `importerPath`'s own recorded versions, so a monorepo whose packages hold
21374
+ * different versions of one dependency still gets an exact answer where
21375
+ * `resolve` must abstain. Prefer this whenever the caller knows the importer —
21376
+ * a consumer iterating `packages` has `relativePath` in hand, which is the
21377
+ * importer key (`"."` for the root package).
21378
+ *
21379
+ * An unknown `importerPath`, or one recording nothing for `dependency`, is
21380
+ * `Option.none()`. Total.
21381
+ *
21382
+ * @param importerPath - The importer's path relative to the workspace root,
21383
+ * `"."` for the root package — `PackageStateSnapshot.relativePath`.
21384
+ * @param dependency - The dependency's package name.
21385
+ * @param specifier - The raw specifier string.
21386
+ */
21387
+ resolveIn(importerPath, dependency, specifier) {
21388
+ return this.#resolveWith(dependency, specifier, () => effect.Option.fromUndefinedOr(this.importerVersions?.[importerPath]?.[dependency]));
21389
+ }
21390
+ /**
21391
+ * The shared resolution path: classify, answer from the captured state, and
21392
+ * consult `onUnresolvedCatalog` only for a `catalog:` specifier the catalog set
21393
+ * could not answer. A plain range is already its own answer and must keep
21394
+ * resolving to `Option.none()` so the caller falls back to the raw string.
21395
+ */
21396
+ #resolveWith(dependency, specifier, onUnresolvedCatalog) {
21243
21397
  const exit = effect.Schema.decodeUnknownExit(DependencySpecifier.FromString)(specifier);
21244
21398
  if (!effect.Exit.isSuccess(exit)) return effect.Option.none();
21245
21399
  const classified = exit.value;
21246
21400
  switch (classified._tag) {
21247
- case "catalog": return this.catalogs.rangeOf(dependency, classified.name);
21401
+ case "catalog": {
21402
+ const fromCatalogs = this.catalogs.rangeOf(dependency, classified.name);
21403
+ return effect.Option.isSome(fromCatalogs) ? fromCatalogs : onUnresolvedCatalog();
21404
+ }
21248
21405
  case "workspace": return effect.Option.fromUndefinedOr(this.#versions().get(dependency));
21249
21406
  default: return effect.Option.none();
21250
21407
  }
@@ -21281,7 +21438,7 @@ var WorkspaceStateSnapshot = class extends effect.Schema.Class("WorkspaceStateSn
21281
21438
  }
21282
21439
  };
21283
21440
  //#endregion
21284
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.6.2_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspaceSnapshots.js
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
21285
21442
  /** Whether `value` is a non-null, non-array object. */
21286
21443
  const isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
21287
21444
  /** Whether every value in a record is a string — a usable dependency map. */
@@ -21335,6 +21492,11 @@ const bunInlineCatalogs = (manifest) => {
21335
21492
  catalogs: workspaces.catalogs
21336
21493
  });
21337
21494
  };
21495
+ /** The contribution of an absent or malformed lockfile: nothing, on both counts. */
21496
+ const EMPTY_LOCKFILE_RECORD = {
21497
+ catalogs: CatalogSet.empty(),
21498
+ importerVersions: {}
21499
+ };
21338
21500
  /**
21339
21501
  * Reads workspace state at a git ref with no checkout, and the live worktree.
21340
21502
  *
@@ -21367,10 +21529,17 @@ var WorkspaceSnapshots = class WorkspaceSnapshots extends effect.Context.Service
21367
21529
  const roots = yield* WorkspaceRoot;
21368
21530
  const discovery = yield* WorkspaceDiscovery;
21369
21531
  const catalogsService = yield* WorkspaceCatalogs;
21370
- /** The catalog set a manager's lockfile records at the ref, or empty when absent/malformed. */
21371
- const lockfileCatalogs = (root, ref, format) => git.show(root, ref, `./${filenameFor(format)}`).pipe(effect.Effect.flatMap((content) => effect.Option.match(content, {
21372
- onNone: () => effect.Effect.succeed(CatalogSet.empty()),
21373
- onSome: (text) => Lockfile.parse(text, { format }).pipe(effect.Effect.map(CatalogSet.fromLockfile), effect.Effect.catch(() => effect.Effect.succeed(CatalogSet.empty())))
21532
+ /**
21533
+ * What a manager's lockfile records at the ref: its catalog set and its
21534
+ * importer versions, from ONE parse. Empty on both counts when the
21535
+ * lockfile is absent or malformed.
21536
+ */
21537
+ const lockfileRecord = (root, ref, format) => git.show(root, ref, `./${filenameFor(format)}`).pipe(effect.Effect.flatMap((content) => effect.Option.match(content, {
21538
+ onNone: () => effect.Effect.succeed(EMPTY_LOCKFILE_RECORD),
21539
+ onSome: (text) => Lockfile.parse(text, { format }).pipe(effect.Effect.map((lockfile) => ({
21540
+ catalogs: CatalogSet.fromLockfile(lockfile),
21541
+ importerVersions: importerVersionsOf(lockfile)
21542
+ })), effect.Effect.catch(() => effect.Effect.succeed(EMPTY_LOCKFILE_RECORD)))
21374
21543
  })));
21375
21544
  const computeAt = (root, ref) => effect.Effect.gen(function* () {
21376
21545
  const pnpmWorkspaceText = yield* git.show(root, ref, "./pnpm-workspace.yaml");
@@ -21381,7 +21550,7 @@ var WorkspaceSnapshots = class WorkspaceSnapshots extends effect.Context.Service
21381
21550
  });
21382
21551
  let patterns;
21383
21552
  let inline;
21384
- let fromLockfile;
21553
+ let recorded;
21385
21554
  if (effect.Option.isSome(pnpmWorkspaceText)) {
21386
21555
  const pnpmPatterns = pnpmPatternsOf(yield* Yaml.parse(pnpmWorkspaceText.value).pipe(effect.Effect.mapError((cause) => new CatalogAssemblyError({
21387
21556
  source: "manifest",
@@ -21390,13 +21559,13 @@ var WorkspaceSnapshots = class WorkspaceSnapshots extends effect.Context.Service
21390
21559
  }))));
21391
21560
  patterns = pnpmPatterns.length > 0 ? pnpmPatterns : manifestPatternsOf(rootManifest);
21392
21561
  inline = yield* CatalogSet.fromWorkspaceYaml(pnpmWorkspaceText.value);
21393
- fromLockfile = yield* lockfileCatalogs(root, ref, "pnpm");
21562
+ recorded = yield* lockfileRecord(root, ref, "pnpm");
21394
21563
  } else {
21395
21564
  patterns = manifestPatternsOf(rootManifest);
21396
21565
  inline = bunInlineCatalogs(rootManifest);
21397
- fromLockfile = yield* lockfileCatalogs(root, ref, "bun");
21566
+ recorded = yield* lockfileRecord(root, ref, "bun");
21398
21567
  }
21399
- const catalogs = CatalogSet.merge(fromLockfile, inline);
21568
+ const catalogs = CatalogSet.merge(recorded.catalogs, inline);
21400
21569
  const globs = yield* GlobSet.compile(patterns).pipe(effect.Effect.mapError((error) => new CatalogAssemblyError({
21401
21570
  source: "manifest",
21402
21571
  path: error.pattern,
@@ -21423,7 +21592,8 @@ var WorkspaceSnapshots = class WorkspaceSnapshots extends effect.Context.Service
21423
21592
  for (const member of members) if (effect.Option.isSome(member)) packages.push(member.value);
21424
21593
  return WorkspaceStateSnapshot.make({
21425
21594
  packages,
21426
- catalogs
21595
+ catalogs,
21596
+ importerVersions: recorded.importerVersions
21427
21597
  });
21428
21598
  });
21429
21599
  const atCaches = /* @__PURE__ */ new Map();
@@ -21447,6 +21617,7 @@ var WorkspaceSnapshots = class WorkspaceSnapshots extends effect.Context.Service
21447
21617
  worktree: effect.Effect.fn("WorkspaceSnapshots.worktree")(function* () {
21448
21618
  const packages = yield* discovery.listPackages();
21449
21619
  const catalogs = yield* catalogsService.set();
21620
+ const importerVersions = yield* catalogsService.importerVersions();
21450
21621
  const snapshotPackages = packages.map((pkg) => PackageStateSnapshot.make({
21451
21622
  name: pkg.name,
21452
21623
  version: pkg.version,
@@ -21458,7 +21629,8 @@ var WorkspaceSnapshots = class WorkspaceSnapshots extends effect.Context.Service
21458
21629
  }));
21459
21630
  return WorkspaceStateSnapshot.make({
21460
21631
  packages: snapshotPackages,
21461
- catalogs
21632
+ catalogs,
21633
+ importerVersions
21462
21634
  });
21463
21635
  })
21464
21636
  };
@@ -21473,7 +21645,7 @@ var WorkspaceSnapshots = class WorkspaceSnapshots extends effect.Context.Service
21473
21645
  static layer = (options) => effect.Layer.effect(WorkspaceSnapshots, WorkspaceSnapshots.make(options));
21474
21646
  };
21475
21647
  //#endregion
21476
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.6.2_@effected+jsonc@0.5.1_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/Workspaces.js
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
21477
21649
  /**
21478
21650
  * Every service that needs only a filesystem: root, package-manager detection,
21479
21651
  * discovery, lockfile reading, catalogs and publishability.
@@ -43164,6 +43336,80 @@ function isUint8Array(value) {
43164
43336
  //#endregion
43165
43337
  //#region ../silk-effects/dist/dev/pkg/changesets/utils/remark-pipeline.js
43166
43338
  /**
43339
+ * Marker set on the `data` of a text node whose value must be written to
43340
+ * markdown verbatim rather than escaped.
43341
+ *
43342
+ * @remarks
43343
+ * `remark-stringify` escapes any character that could open a markdown
43344
+ * construct. Inside a dependency table that is always wrong: with
43345
+ * `remark-gfm` enabled `~` is the strikethrough delimiter, so the specifier
43346
+ * `~0.2.1` is written as `\~0.2.1`, and `_` in a package name becomes `\_`.
43347
+ * The corruption compounds on every re-serialization, and dependency-table
43348
+ * cells round-trip through consolidation and PR-body reconstruction.
43349
+ *
43350
+ * The marker is deliberately narrow. It is set only by the dependency-table
43351
+ * cell builder, whose cell vocabulary is closed — package name, dependency
43352
+ * type, action, version specifier, and the em-dash sentinel — and none of
43353
+ * those can legitimately carry markdown. Prose elsewhere in a changeset keeps
43354
+ * the default escaping.
43355
+ *
43356
+ * @internal
43357
+ */
43358
+ const LITERAL_TEXT_MARKER = "silkLiteralText";
43359
+ /**
43360
+ * Mark a text node so {@link createRemarkProcessor} writes it verbatim.
43361
+ *
43362
+ * @param value - The literal cell text
43363
+ * @returns An MDAST `Text` node carrying the literal marker
43364
+ *
43365
+ * @internal
43366
+ */
43367
+ function literalText(value) {
43368
+ return {
43369
+ type: "text",
43370
+ value,
43371
+ data: { [LITERAL_TEXT_MARKER]: true }
43372
+ };
43373
+ }
43374
+ /**
43375
+ * Whether a text node was marked by {@link literalText}.
43376
+ *
43377
+ * @internal
43378
+ */
43379
+ function isLiteralText(node) {
43380
+ return node.data?.[LITERAL_TEXT_MARKER] === true;
43381
+ }
43382
+ /**
43383
+ * Escape the two characters that would otherwise corrupt the table grid.
43384
+ *
43385
+ * @remarks
43386
+ * A `|` would close the cell early and a `\` would be read as an escape
43387
+ * introducer, so both are escaped to keep the written cell parseable back to
43388
+ * its exact input. Every other character is emitted as-is. Because parsing
43389
+ * consumes the backslash, a value that already carries a legacy `\~` from the
43390
+ * old escaping path re-parses to its clean form rather than accumulating
43391
+ * another layer.
43392
+ *
43393
+ * @internal
43394
+ */
43395
+ function escapeCellLiteral(value) {
43396
+ return value.replace(/[\\|]/g, "\\$&");
43397
+ }
43398
+ /**
43399
+ * `mdast-util-to-markdown` handler overrides used by the shared processor.
43400
+ *
43401
+ * @remarks
43402
+ * Replaces the default `text` handler — which is `state.safe(node.value, info)`
43403
+ * — with one that bypasses escaping for nodes marked by {@link literalText}
43404
+ * and delegates to the default behavior for everything else.
43405
+ *
43406
+ * @internal
43407
+ */
43408
+ const literalTextHandlers = { text: (node, _parent, state, info) => {
43409
+ const text = node;
43410
+ return isLiteralText(text) ? escapeCellLiteral(text.value) : state.safe(text.value, info);
43411
+ } };
43412
+ /**
43167
43413
  * Create a unified processor configured with remark-parse, remark-gfm,
43168
43414
  * and remark-stringify.
43169
43415
  *
@@ -43171,7 +43417,8 @@ function isUint8Array(value) {
43171
43417
  * Each call creates a fresh processor instance. The plugin chain is:
43172
43418
  * 1. `remark-parse` — markdown to MDAST
43173
43419
  * 2. `remark-gfm` — GitHub Flavored Markdown extensions (tables, etc.)
43174
- * 3. `remark-stringify` — MDAST back to markdown
43420
+ * 3. `remark-stringify` — MDAST back to markdown, with the
43421
+ * {@link literalText} handler override
43175
43422
  *
43176
43423
  * @privateRemarks
43177
43424
  * Return type is intentionally inferred because the unified `Processor`
@@ -43182,7 +43429,7 @@ function isUint8Array(value) {
43182
43429
  * @internal
43183
43430
  */
43184
43431
  function createRemarkProcessor() {
43185
- return unified().use(remarkParse).use(remarkGfm).use(remarkStringify);
43432
+ return unified().use(remarkParse).use(remarkGfm).use(remarkStringify, { handlers: literalTextHandlers });
43186
43433
  }
43187
43434
  /**
43188
43435
  * Parse a markdown string into an MDAST AST synchronously.
@@ -43690,6 +43937,12 @@ function parseDependencyTable(table) {
43690
43937
  /**
43691
43938
  * Create a table cell with a text node.
43692
43939
  *
43940
+ * @remarks
43941
+ * The cell text is marked literal, so stringification writes it verbatim
43942
+ * instead of escaping characters that could open a markdown construct. See
43943
+ * {@link literalText} — without it `~0.2.1` is written as `\~0.2.1` and
43944
+ * `some_pkg` as `some\_pkg`.
43945
+ *
43693
43946
  * @param text - The cell text content
43694
43947
  * @returns An MDAST `TableCell` node
43695
43948
  *
@@ -43698,10 +43951,7 @@ function parseDependencyTable(table) {
43698
43951
  function makeCell(text) {
43699
43952
  return {
43700
43953
  type: "tableCell",
43701
- children: [{
43702
- type: "text",
43703
- value: text
43704
- }]
43954
+ children: [literalText(text)]
43705
43955
  };
43706
43956
  }
43707
43957
  /**
@@ -43776,11 +44026,10 @@ function serializeDependencyTable(rows) {
43776
44026
  * @internal
43777
44027
  */
43778
44028
  function serializeDependencyTableToMarkdown(rows) {
43779
- const tree = {
44029
+ return stringifyMarkdown({
43780
44030
  type: "root",
43781
44031
  children: [serializeDependencyTable(rows)]
43782
- };
43783
- return unified().use(remarkGfm).use(remarkStringify).stringify(tree).trim();
44032
+ }).trim();
43784
44033
  }
43785
44034
  /**
43786
44035
  * Sort priority for dependency actions: removed first, then updated, then added.
@@ -46972,10 +47221,23 @@ const DEP_TYPE_MAP = [
46972
47221
  ["optionalDependencies", "optionalDependency"]
46973
47222
  ];
46974
47223
  /**
46975
- * Resolve a specifier against the snapshot it belongs to, falling back to
46976
- * the raw specifier string when the snapshot cannot resolve it.
46977
- */
46978
- const resolveOrRaw = (snapshot, dep, spec) => effect.Option.getOrElse(snapshot.resolve(dep, spec), () => spec);
47224
+ * Resolve a specifier against the snapshot it belongs to, scoped to the
47225
+ * importer that declared it, falling back to the raw specifier string when
47226
+ * the snapshot cannot resolve it.
47227
+ *
47228
+ * @remarks
47229
+ * Uses `resolveIn` rather than the workspace-wide `resolve`. Both consult the
47230
+ * ref's own lockfile importer entries when a `catalog:` specifier is not in the
47231
+ * catalog set — which is what makes hook-injected catalogs (`catalog:effect:peers`,
47232
+ * injected by a config-dependency pnpmfile and recorded in neither
47233
+ * `pnpm-workspace.yaml` nor the lockfile's `catalogs:` block) resolvable at all.
47234
+ * The workspace-wide form abstains whenever two importers disagree on a
47235
+ * dependency's version, which in a multi-package repo reproduces the original
47236
+ * defect: both sides fall back to the identical raw specifier, compare equal,
47237
+ * and emit no row. Scoping to the declaring importer answers precisely where
47238
+ * the workspace-wide form cannot.
47239
+ */
47240
+ const resolveOrRaw = (snapshot, importerPath, dep, spec) => effect.Option.getOrElse(snapshot.resolveIn(importerPath, dep, spec), () => spec);
46979
47241
  /**
46980
47242
  * Drop no-net-change field moves: the same dependency removed from one field
46981
47243
  * and added to another with an equal resolved version (e.g. a dep promoted
@@ -47020,13 +47282,15 @@ function computeWorkspaceDependencyDiffs(before, after) {
47020
47282
  for (const afterPkg of after.packages) {
47021
47283
  const beforePkg = effect.Option.getOrNull(before.package(afterPkg.name));
47022
47284
  const rows = [];
47285
+ const afterImporter = afterPkg.relativePath;
47286
+ const beforeImporter = beforePkg?.relativePath ?? afterImporter;
47023
47287
  for (const [field, type] of DEP_TYPE_MAP) {
47024
47288
  const beforeRecord = beforePkg?.[field] ?? {};
47025
47289
  const afterRecord = afterPkg[field];
47026
47290
  const seen = /* @__PURE__ */ new Set();
47027
47291
  for (const [name, beforeSpec] of Object.entries(beforeRecord)) {
47028
47292
  seen.add(name);
47029
- const from = resolveOrRaw(before, name, beforeSpec);
47293
+ const from = resolveOrRaw(before, beforeImporter, name, beforeSpec);
47030
47294
  const afterSpec = afterRecord[name];
47031
47295
  if (afterSpec === void 0) {
47032
47296
  rows.push({
@@ -47038,7 +47302,7 @@ function computeWorkspaceDependencyDiffs(before, after) {
47038
47302
  });
47039
47303
  continue;
47040
47304
  }
47041
- const to = resolveOrRaw(after, name, afterSpec);
47305
+ const to = resolveOrRaw(after, afterImporter, name, afterSpec);
47042
47306
  if (from !== to) rows.push({
47043
47307
  dependency: name,
47044
47308
  type,
@@ -47054,7 +47318,7 @@ function computeWorkspaceDependencyDiffs(before, after) {
47054
47318
  type,
47055
47319
  action: "added",
47056
47320
  from: EM_DASH$1,
47057
- to: resolveOrRaw(after, name, afterSpec)
47321
+ to: resolveOrRaw(after, afterImporter, name, afterSpec)
47058
47322
  });
47059
47323
  }
47060
47324
  }
@@ -65200,8 +65464,38 @@ function getHeadingLevel(heading) {
65200
65464
  return sequence ? sequence.text.length : 0;
65201
65465
  }
65202
65466
  /**
65467
+ * CommonMark backslash escapes: a backslash is literal unless it precedes an
65468
+ * ASCII punctuation character, in which case the pair denotes that character.
65469
+ */
65470
+ const BACKSLASH_ESCAPE_RE = /\\([!-/:-@[-`{-~])/g;
65471
+ /**
65472
+ * Resolve CommonMark backslash escapes in raw micromark source text.
65473
+ *
65474
+ * @remarks
65475
+ * Every rule in this directory has a sibling remark implementation that reads
65476
+ * the parsed mdast tree, where the parser has already resolved escapes, via
65477
+ * `mdast-util-to-string`. Micromark tokens instead carry RAW source. Comparing
65478
+ * raw text against a value the parsed form would produce makes the two
65479
+ * implementations of one documented rule disagree about the same file
65480
+ * (issue #367).
65481
+ *
65482
+ * Applied at the shared extractors below so both implementations judge the
65483
+ * value a reader actually sees, rather than per-rule where the next extractor
65484
+ * added would silently reintroduce the split.
65485
+ *
65486
+ * @internal
65487
+ */
65488
+ function unescapeMarkdown(raw) {
65489
+ return raw.replace(BACKSLASH_ESCAPE_RE, "$1");
65490
+ }
65491
+ /**
65203
65492
  * Get the plain text content of an `atxHeading` token.
65204
65493
  *
65494
+ * @remarks
65495
+ * Escape-resolved, so a heading compares equal to the same heading as the
65496
+ * remark rules see it. `getHeadingLevel` needs no equivalent — it counts
65497
+ * sequence characters rather than reading text.
65498
+ *
65205
65499
  * @param heading - The `atxHeading` micromark token
65206
65500
  * @returns The heading text, or empty string if no text token found
65207
65501
  *
@@ -65209,7 +65503,7 @@ function getHeadingLevel(heading) {
65209
65503
  */
65210
65504
  function getHeadingText(heading) {
65211
65505
  const textToken = heading.children.find((c) => c.type === "atxHeadingText");
65212
- return textToken ? textToken.text : "";
65506
+ return textToken ? unescapeMarkdown(textToken.text) : "";
65213
65507
  }
65214
65508
  //#endregion
65215
65509
  //#region ../silk-effects/dist/dev/pkg/changesets/markdownlint/rules/content-structure.js
@@ -65334,13 +65628,13 @@ const EXPECTED_HEADERS = [
65334
65628
  * The `tableContent` token has a `.text` property with the cell value.
65335
65629
  *
65336
65630
  * @param cell - A GFM table cell token (header or data)
65337
- * @returns The trimmed text content of the cell, or an empty string
65631
+ * @returns The trimmed, escape-resolved text content of the cell, or an empty string
65338
65632
  *
65339
65633
  * @internal
65340
65634
  */
65341
65635
  function getCellText(cell) {
65342
65636
  const content = cell.children.find((c) => c.type === "tableContent");
65343
- return content ? content.text.trim() : "";
65637
+ return content ? unescapeMarkdown(content.text.trim()) : "";
65344
65638
  }
65345
65639
  /**
65346
65640
  * Extract all cell texts from a `tableRow` token.