@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.
@@ -16669,7 +16669,7 @@ var Package = class Package extends effect.Schema.Class("Package")({
16669
16669
  }
16670
16670
  };
16671
16671
  //#endregion
16672
- //#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
16672
+ //#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
16673
16673
  const EMPTY$1 = Object.freeze(Object.create(null));
16674
16674
  const EMPTY_MANIFEST = Object.freeze(Object.create(null));
16675
16675
  /**
@@ -17274,7 +17274,7 @@ const Walker$1 = {
17274
17274
  findRoot: findRoot$1
17275
17275
  };
17276
17276
  //#endregion
17277
- //#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
17277
+ //#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
17278
17278
  /**
17279
17279
  * The marker filenames {@link WorkspaceRoot} probes for, in priority order.
17280
17280
  *
@@ -17461,7 +17461,7 @@ var WorkspaceRoot = class WorkspaceRoot extends effect.Context.Service()("@effec
17461
17461
  static layerTest = (root) => effect.Layer.effect(WorkspaceRoot, WorkspaceRoot.makeTest(root)).pipe(effect.Layer.provide(effect.Path.layer));
17462
17462
  };
17463
17463
  //#endregion
17464
- //#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
17464
+ //#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
17465
17465
  /**
17466
17466
  * Hard ceiling on directories the enumerator will visit for one pattern set.
17467
17467
  * Guards the pathological case a depth cap alone does not: a wide, shallow
@@ -17479,7 +17479,7 @@ const MAX_ENUMERATION_ENTRIES = 1e5;
17479
17479
  */
17480
17480
  const PRUNED_DIRECTORIES = /* @__PURE__ */ new Set([".git", "node_modules"]);
17481
17481
  //#endregion
17482
- //#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
17482
+ //#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
17483
17483
  /** Directory names never descended into. */
17484
17484
  const isPruned = (entry) => PRUNED_DIRECTORIES.has(entry);
17485
17485
  /** Join root-relative POSIX segments; `""` is the root itself. */
@@ -17569,7 +17569,7 @@ var Traversal = class {
17569
17569
  }
17570
17570
  };
17571
17571
  //#endregion
17572
- //#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
17572
+ //#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
17573
17573
  /** Strip a trailing slash from `GlobPattern.enumerationPrefix` to get a relative directory. */
17574
17574
  const baseOf = (pattern) => pattern.enumerationPrefix.replace(/\/$/, "");
17575
17575
  /**
@@ -17639,7 +17639,7 @@ const enumerate = (root, globs, options) => effect.Effect.gen(function* () {
17639
17639
  return results;
17640
17640
  });
17641
17641
  //#endregion
17642
- //#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
17642
+ //#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
17643
17643
  const stringsOf = (value) => Array.isArray(value) ? value.filter((entry) => typeof entry === "string") : void 0;
17644
17644
  /** The `packages:` list of a `pnpm-workspace.yaml` document. Total on a parsed document. */
17645
17645
  const pnpmPatternsOf = (document) => {
@@ -17696,7 +17696,7 @@ const readPatterns = (root) => effect.Effect.gen(function* () {
17696
17696
  return manifestPatternsOf(manifest);
17697
17697
  });
17698
17698
  //#endregion
17699
- //#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
17699
+ //#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
17700
17700
  /**
17701
17701
  * Raised when a workspace member's `package.json` cannot be read, parsed, or
17702
17702
  * used — it is missing, malformed, or lacks a `name` or `version`.
@@ -18130,7 +18130,7 @@ var WorkspaceDiscovery = class WorkspaceDiscovery extends effect.Context.Service
18130
18130
  };
18131
18131
  const isStringRecord$2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value) && Object.values(value).every((entry) => typeof entry === "string");
18132
18132
  //#endregion
18133
- //#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
18133
+ //#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
18134
18134
  /**
18135
18135
  * Raised when the workspace dependency graph cannot be topologically ordered
18136
18136
  * because it contains a cycle.
@@ -19728,7 +19728,7 @@ var Git = class extends effect.Context.Service()("@effected/git/Git") {
19728
19728
  }));
19729
19729
  };
19730
19730
  //#endregion
19731
- //#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
19731
+ //#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
19732
19732
  /**
19733
19733
  * Which git refs to compare, and whether to fold in the working tree.
19734
19734
  *
@@ -19980,7 +19980,7 @@ function resolveFromCatalog(catalogs, wantedDependency) {
19980
19980
  };
19981
19981
  }
19982
19982
  //#endregion
19983
- //#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
19983
+ //#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
19984
19984
  /** Project a pnpm-workspace manifest's `catalog` / `catalogs` fields into a `Catalogs` map. */
19985
19985
  const inlineCatalogs = (manifest) => {
19986
19986
  if (manifest.catalog === void 0 && manifest.catalogs === void 0) return {};
@@ -20044,7 +20044,7 @@ const rangeOf = (catalogs, dependency, specifier) => {
20044
20044
  });
20045
20045
  };
20046
20046
  //#endregion
20047
- //#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
20047
+ //#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
20048
20048
  /** Whether `value` is a non-null, non-array object. */
20049
20049
  const isObject$2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
20050
20050
  /**
@@ -20230,7 +20230,7 @@ var ConfigDependencyHooks = class ConfigDependencyHooks extends effect.Context.S
20230
20230
  }) });
20231
20231
  };
20232
20232
  //#endregion
20233
- //#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
20233
+ //#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
20234
20234
  /**
20235
20235
  * The four package managers this package understands.
20236
20236
  *
@@ -20472,7 +20472,7 @@ var PackageManagerDetector = class PackageManagerDetector extends effect.Context
20472
20472
  static layer = effect.Layer.effect(PackageManagerDetector, PackageManagerDetector.make);
20473
20473
  };
20474
20474
  //#endregion
20475
- //#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
20475
+ //#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
20476
20476
  /**
20477
20477
  * Raised when the workspace's lockfile cannot be read off disk.
20478
20478
  *
@@ -20582,7 +20582,7 @@ var LockfileReader = class LockfileReader extends effect.Context.Service()("@eff
20582
20582
  static layer = (options) => effect.Layer.effect(LockfileReader, LockfileReader.make(options));
20583
20583
  };
20584
20584
  //#endregion
20585
- //#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
20585
+ //#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
20586
20586
  /** The public npm registry, used when `publishConfig.registry` says nothing. */
20587
20587
  const DEFAULT_REGISTRY = "https://registry.npmjs.org/";
20588
20588
  /**
@@ -20682,7 +20682,93 @@ var PublishabilityDetector = class PublishabilityDetector extends effect.Context
20682
20682
  }) });
20683
20683
  };
20684
20684
  //#endregion
20685
- //#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
20685
+ //#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
20686
+ /**
20687
+ * Strip pnpm's peer-disambiguation suffix from a recorded importer version.
20688
+ *
20689
+ * pnpm records an importer version as the resolved version followed by the peer
20690
+ * 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))`.
20691
+ * `@effected/lockfiles` stores that string verbatim (its `packages:` key parser
20692
+ * strips the suffix; the importer entries deliberately keep it), so the raw
20693
+ * value must never reach a consumer's dependency table — it would render the
20694
+ * whole parenthesized chain as the "version" a dependency moved to.
20695
+ *
20696
+ * Everything from the first `(` is dropped; a version with no suffix passes
20697
+ * through untouched.
20698
+ */
20699
+ const stripPeerSuffix = (version) => {
20700
+ const paren = version.indexOf("(");
20701
+ return paren === -1 ? version : version.slice(0, paren);
20702
+ };
20703
+ /**
20704
+ * Whether a recorded importer version is a concrete version usable as a
20705
+ * resolution answer.
20706
+ *
20707
+ * A `link:` / `file:` entry records a filesystem edge rather than a version, and
20708
+ * an empty string is pnpm's "specifier only, nothing installed" marker. Both
20709
+ * would be worse than no answer at all: the fallback exists to report a concrete
20710
+ * version movement, and reporting `link:../foo` as a version is noise a
20711
+ * changeset would carry into release notes.
20712
+ */
20713
+ const isConcreteVersion = (version) => version.length > 0 && !version.startsWith("link:") && !version.startsWith("file:");
20714
+ /**
20715
+ * Build the importer-path → dependency-name → version index a snapshot uses to
20716
+ * answer `catalog:` specifiers its catalog set cannot resolve.
20717
+ *
20718
+ * @remarks
20719
+ * Keyed by **name only** within each importer, deliberately across every
20720
+ * dependency field. The bug this fixes is a peer declared `catalog:effect:peers`
20721
+ * whose importer records no `peerDependencies` entry at all — pnpm writes peer
20722
+ * declarations into the importer block only when they are also installed, so the
20723
+ * concrete version lives on the package's `devDependencies` row for the same
20724
+ * name. Joining by name across fields is what finds it; joining by field, or by
20725
+ * matching the recorded specifier, would not.
20726
+ *
20727
+ * Only pnpm populates importer versions; bun and npm record resolved versions on
20728
+ * their package entries instead, so those formats yield an empty index and the
20729
+ * fallback is inert for them.
20730
+ */
20731
+ const importerVersionsOf = (lockfile) => {
20732
+ const index = Object.create(null);
20733
+ for (const importer of lockfile.importers) {
20734
+ const versions = Object.create(null);
20735
+ for (const dependency of importer.dependencies) {
20736
+ const recorded = dependency.version;
20737
+ if (recorded === void 0) continue;
20738
+ const version = stripPeerSuffix(recorded);
20739
+ if (!isConcreteVersion(version)) continue;
20740
+ versions[dependency.name] ??= version;
20741
+ }
20742
+ index[importer.path] = versions;
20743
+ }
20744
+ return index;
20745
+ };
20746
+ /**
20747
+ * The version every importer agrees `dependency` resolved to, or `undefined`
20748
+ * when they disagree or none record it.
20749
+ *
20750
+ * @remarks
20751
+ * The unambiguity rule is what makes a workspace-wide answer safe from a
20752
+ * snapshot method that receives no importer context. Two packages in one
20753
+ * monorepo may legitimately hold different versions of the same dependency; in
20754
+ * that case there is no single correct answer, so this yields nothing and the
20755
+ * caller keeps today's behavior (no row) rather than inventing a wrong one.
20756
+ */
20757
+ const unanimousVersionOf = (index, dependency) => {
20758
+ let agreed;
20759
+ for (const versions of Object.values(index)) {
20760
+ const version = versions[dependency];
20761
+ if (version === void 0) continue;
20762
+ if (agreed === void 0) {
20763
+ agreed = version;
20764
+ continue;
20765
+ }
20766
+ if (agreed !== version) return void 0;
20767
+ }
20768
+ return agreed;
20769
+ };
20770
+ //#endregion
20771
+ //#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
20686
20772
  /**
20687
20773
  * An immutable, fully-normalized catalog collection — the one catalog
20688
20774
  * resolution semantic in the package.
@@ -21001,7 +21087,15 @@ var WorkspaceCatalogs = class WorkspaceCatalogs extends effect.Context.Service()
21001
21087
  }));
21002
21088
  const assemble = effect.Effect.gen(function* () {
21003
21089
  const root = yield* effect.Effect.suspend(() => roots.find(options?.cwd ?? process.cwd()));
21004
- const fromLockfile = yield* lockfiles.read().pipe(effect.Effect.map(CatalogSet.fromLockfile), effect.Effect.catch((_failure) => effect.Effect.succeed(CatalogSet.empty())));
21090
+ const lockfileOutputs = yield* lockfiles.read().pipe(effect.Effect.map((lockfile) => ({
21091
+ catalogs: CatalogSet.fromLockfile(lockfile),
21092
+ importerVersions: importerVersionsOf(lockfile)
21093
+ })), effect.Effect.catch((_failure) => effect.Effect.succeed({
21094
+ catalogs: CatalogSet.empty(),
21095
+ importerVersions: {}
21096
+ })));
21097
+ const fromLockfile = lockfileOutputs.catalogs;
21098
+ const importerVersions = lockfileOutputs.importerVersions;
21005
21099
  const workspaceYaml = path.join(root, "pnpm-workspace.yaml");
21006
21100
  const hasPnpmWorkspace = yield* probeExists(workspaceYaml);
21007
21101
  let inline;
@@ -21029,7 +21123,8 @@ var WorkspaceCatalogs = class WorkspaceCatalogs extends effect.Context.Service()
21029
21123
  const manifestPath = path.join(root, "package.json");
21030
21124
  if (!(yield* probeExists(manifestPath))) return {
21031
21125
  catalogs: fromLockfile,
21032
- releaseAgeGate: ReleaseAgeGate.combine()
21126
+ releaseAgeGate: ReleaseAgeGate.combine(),
21127
+ importerVersions
21033
21128
  };
21034
21129
  const text = yield* fs.readFileString(manifestPath).pipe(effect.Effect.mapError((cause) => new CatalogAssemblyError({
21035
21130
  source: "manifest",
@@ -21048,7 +21143,8 @@ var WorkspaceCatalogs = class WorkspaceCatalogs extends effect.Context.Service()
21048
21143
  }));
21049
21144
  return {
21050
21145
  catalogs: assembled,
21051
- releaseAgeGate
21146
+ releaseAgeGate,
21147
+ importerVersions
21052
21148
  };
21053
21149
  });
21054
21150
  const [resolveOnce, invalidate] = yield* effect.Effect.cachedInvalidateWithTTL(assemble, effect.Duration.infinity);
@@ -21062,6 +21158,9 @@ var WorkspaceCatalogs = class WorkspaceCatalogs extends effect.Context.Service()
21062
21158
  }),
21063
21159
  releaseAgeGate: effect.Effect.fn("WorkspaceCatalogs.releaseAgeGate")(function* () {
21064
21160
  return (yield* memo).releaseAgeGate;
21161
+ }),
21162
+ importerVersions: effect.Effect.fn("WorkspaceCatalogs.importerVersions")(function* () {
21163
+ return (yield* memo).importerVersions;
21065
21164
  })
21066
21165
  };
21067
21166
  });
@@ -21112,7 +21211,7 @@ var WorkspaceCatalogs = class WorkspaceCatalogs extends effect.Context.Service()
21112
21211
  }));
21113
21212
  };
21114
21213
  //#endregion
21115
- //#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
21214
+ //#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
21116
21215
  const EMPTY = Object.freeze(Object.create(null));
21117
21216
  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)));
21118
21217
  /**
@@ -21196,7 +21295,19 @@ var WorkspaceStateSnapshot = class extends effect.Schema.Class("WorkspaceStateSn
21196
21295
  /** Every workspace package captured at this moment. */
21197
21296
  packages: effect.Schema.Array(PackageStateSnapshot),
21198
21297
  /** The catalog set assembled at this moment. */
21199
- catalogs: CatalogSet
21298
+ catalogs: CatalogSet,
21299
+ /**
21300
+ * Each importer's dependency-name → resolved-version map, as the manager's
21301
+ * lockfile recorded it at this moment.
21302
+ *
21303
+ * @remarks
21304
+ * Defaults to `{}`, so a `WorkspaceStateSnapshot` serialized before this field
21305
+ * existed still decodes — and an empty index simply makes the `catalog:`
21306
+ * fallback in {@link WorkspaceStateSnapshot.resolve} inert, which is exactly
21307
+ * the behavior those older values were captured under. Only pnpm records
21308
+ * importer versions; bun and npm yield an empty index.
21309
+ */
21310
+ importerVersions: effect.Schema.optionalKey(effect.Schema.Record(effect.Schema.String, effect.Schema.Record(effect.Schema.String, effect.Schema.String)))
21200
21311
  }) {
21201
21312
  #versionIndex;
21202
21313
  #packageIndex;
@@ -21231,16 +21342,62 @@ var WorkspaceStateSnapshot = class extends effect.Schema.Class("WorkspaceStateSn
21231
21342
  * unparseable string — is `Option.none()`, because there is no indirection to
21232
21343
  * resolve. Total.
21233
21344
  *
21345
+ * A `catalog:` specifier the catalog set cannot resolve falls back to this
21346
+ * snapshot's `importerVersions` — but only to a version
21347
+ * **every** importer recording that dependency agrees on. A catalog injected
21348
+ * by a config-dependency pnpmfile hook appears in no committed catalog source,
21349
+ * so without this fallback both sides of a before/after diff resolve it to the
21350
+ * same raw string and a real version movement produces no row. When importers
21351
+ * disagree there is no single correct answer, so this stays `Option.none()`
21352
+ * rather than inventing one; {@link WorkspaceStateSnapshot.resolveIn} answers
21353
+ * precisely for callers that know which importer is asking.
21354
+ *
21234
21355
  * @param dependency - The dependency's package name (what `workspace:` /
21235
21356
  * `catalog:` resolve for).
21236
21357
  * @param specifier - The raw specifier string.
21237
21358
  */
21238
21359
  resolve(dependency, specifier) {
21360
+ return this.#resolveWith(dependency, specifier, () => effect.Option.fromUndefinedOr(unanimousVersionOf(this.importerVersions ?? {}, dependency)));
21361
+ }
21362
+ /**
21363
+ * The concrete range or version a specifier resolved to AS OF this snapshot,
21364
+ * scoped to the importer that declared it.
21365
+ *
21366
+ * @remarks
21367
+ * Identical to {@link WorkspaceStateSnapshot.resolve} except in how an
21368
+ * unresolvable `catalog:` specifier falls back: this consults **only**
21369
+ * `importerPath`'s own recorded versions, so a monorepo whose packages hold
21370
+ * different versions of one dependency still gets an exact answer where
21371
+ * `resolve` must abstain. Prefer this whenever the caller knows the importer —
21372
+ * a consumer iterating `packages` has `relativePath` in hand, which is the
21373
+ * importer key (`"."` for the root package).
21374
+ *
21375
+ * An unknown `importerPath`, or one recording nothing for `dependency`, is
21376
+ * `Option.none()`. Total.
21377
+ *
21378
+ * @param importerPath - The importer's path relative to the workspace root,
21379
+ * `"."` for the root package — `PackageStateSnapshot.relativePath`.
21380
+ * @param dependency - The dependency's package name.
21381
+ * @param specifier - The raw specifier string.
21382
+ */
21383
+ resolveIn(importerPath, dependency, specifier) {
21384
+ return this.#resolveWith(dependency, specifier, () => effect.Option.fromUndefinedOr(this.importerVersions?.[importerPath]?.[dependency]));
21385
+ }
21386
+ /**
21387
+ * The shared resolution path: classify, answer from the captured state, and
21388
+ * consult `onUnresolvedCatalog` only for a `catalog:` specifier the catalog set
21389
+ * could not answer. A plain range is already its own answer and must keep
21390
+ * resolving to `Option.none()` so the caller falls back to the raw string.
21391
+ */
21392
+ #resolveWith(dependency, specifier, onUnresolvedCatalog) {
21239
21393
  const exit = effect.Schema.decodeUnknownExit(DependencySpecifier.FromString)(specifier);
21240
21394
  if (!effect.Exit.isSuccess(exit)) return effect.Option.none();
21241
21395
  const classified = exit.value;
21242
21396
  switch (classified._tag) {
21243
- case "catalog": return this.catalogs.rangeOf(dependency, classified.name);
21397
+ case "catalog": {
21398
+ const fromCatalogs = this.catalogs.rangeOf(dependency, classified.name);
21399
+ return effect.Option.isSome(fromCatalogs) ? fromCatalogs : onUnresolvedCatalog();
21400
+ }
21244
21401
  case "workspace": return effect.Option.fromUndefinedOr(this.#versions().get(dependency));
21245
21402
  default: return effect.Option.none();
21246
21403
  }
@@ -21277,7 +21434,7 @@ var WorkspaceStateSnapshot = class extends effect.Schema.Class("WorkspaceStateSn
21277
21434
  }
21278
21435
  };
21279
21436
  //#endregion
21280
- //#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
21437
+ //#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
21281
21438
  /** Whether `value` is a non-null, non-array object. */
21282
21439
  const isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
21283
21440
  /** Whether every value in a record is a string — a usable dependency map. */
@@ -21331,6 +21488,11 @@ const bunInlineCatalogs = (manifest) => {
21331
21488
  catalogs: workspaces.catalogs
21332
21489
  });
21333
21490
  };
21491
+ /** The contribution of an absent or malformed lockfile: nothing, on both counts. */
21492
+ const EMPTY_LOCKFILE_RECORD = {
21493
+ catalogs: CatalogSet.empty(),
21494
+ importerVersions: {}
21495
+ };
21334
21496
  /**
21335
21497
  * Reads workspace state at a git ref with no checkout, and the live worktree.
21336
21498
  *
@@ -21363,10 +21525,17 @@ var WorkspaceSnapshots = class WorkspaceSnapshots extends effect.Context.Service
21363
21525
  const roots = yield* WorkspaceRoot;
21364
21526
  const discovery = yield* WorkspaceDiscovery;
21365
21527
  const catalogsService = yield* WorkspaceCatalogs;
21366
- /** The catalog set a manager's lockfile records at the ref, or empty when absent/malformed. */
21367
- const lockfileCatalogs = (root, ref, format) => git.show(root, ref, `./${filenameFor(format)}`).pipe(effect.Effect.flatMap((content) => effect.Option.match(content, {
21368
- onNone: () => effect.Effect.succeed(CatalogSet.empty()),
21369
- onSome: (text) => Lockfile.parse(text, { format }).pipe(effect.Effect.map(CatalogSet.fromLockfile), effect.Effect.catch(() => effect.Effect.succeed(CatalogSet.empty())))
21528
+ /**
21529
+ * What a manager's lockfile records at the ref: its catalog set and its
21530
+ * importer versions, from ONE parse. Empty on both counts when the
21531
+ * lockfile is absent or malformed.
21532
+ */
21533
+ const lockfileRecord = (root, ref, format) => git.show(root, ref, `./${filenameFor(format)}`).pipe(effect.Effect.flatMap((content) => effect.Option.match(content, {
21534
+ onNone: () => effect.Effect.succeed(EMPTY_LOCKFILE_RECORD),
21535
+ onSome: (text) => Lockfile.parse(text, { format }).pipe(effect.Effect.map((lockfile) => ({
21536
+ catalogs: CatalogSet.fromLockfile(lockfile),
21537
+ importerVersions: importerVersionsOf(lockfile)
21538
+ })), effect.Effect.catch(() => effect.Effect.succeed(EMPTY_LOCKFILE_RECORD)))
21370
21539
  })));
21371
21540
  const computeAt = (root, ref) => effect.Effect.gen(function* () {
21372
21541
  const pnpmWorkspaceText = yield* git.show(root, ref, "./pnpm-workspace.yaml");
@@ -21377,7 +21546,7 @@ var WorkspaceSnapshots = class WorkspaceSnapshots extends effect.Context.Service
21377
21546
  });
21378
21547
  let patterns;
21379
21548
  let inline;
21380
- let fromLockfile;
21549
+ let recorded;
21381
21550
  if (effect.Option.isSome(pnpmWorkspaceText)) {
21382
21551
  const pnpmPatterns = pnpmPatternsOf(yield* Yaml.parse(pnpmWorkspaceText.value).pipe(effect.Effect.mapError((cause) => new CatalogAssemblyError({
21383
21552
  source: "manifest",
@@ -21386,13 +21555,13 @@ var WorkspaceSnapshots = class WorkspaceSnapshots extends effect.Context.Service
21386
21555
  }))));
21387
21556
  patterns = pnpmPatterns.length > 0 ? pnpmPatterns : manifestPatternsOf(rootManifest);
21388
21557
  inline = yield* CatalogSet.fromWorkspaceYaml(pnpmWorkspaceText.value);
21389
- fromLockfile = yield* lockfileCatalogs(root, ref, "pnpm");
21558
+ recorded = yield* lockfileRecord(root, ref, "pnpm");
21390
21559
  } else {
21391
21560
  patterns = manifestPatternsOf(rootManifest);
21392
21561
  inline = bunInlineCatalogs(rootManifest);
21393
- fromLockfile = yield* lockfileCatalogs(root, ref, "bun");
21562
+ recorded = yield* lockfileRecord(root, ref, "bun");
21394
21563
  }
21395
- const catalogs = CatalogSet.merge(fromLockfile, inline);
21564
+ const catalogs = CatalogSet.merge(recorded.catalogs, inline);
21396
21565
  const globs = yield* GlobSet.compile(patterns).pipe(effect.Effect.mapError((error) => new CatalogAssemblyError({
21397
21566
  source: "manifest",
21398
21567
  path: error.pattern,
@@ -21419,7 +21588,8 @@ var WorkspaceSnapshots = class WorkspaceSnapshots extends effect.Context.Service
21419
21588
  for (const member of members) if (effect.Option.isSome(member)) packages.push(member.value);
21420
21589
  return WorkspaceStateSnapshot.make({
21421
21590
  packages,
21422
- catalogs
21591
+ catalogs,
21592
+ importerVersions: recorded.importerVersions
21423
21593
  });
21424
21594
  });
21425
21595
  const atCaches = /* @__PURE__ */ new Map();
@@ -21443,6 +21613,7 @@ var WorkspaceSnapshots = class WorkspaceSnapshots extends effect.Context.Service
21443
21613
  worktree: effect.Effect.fn("WorkspaceSnapshots.worktree")(function* () {
21444
21614
  const packages = yield* discovery.listPackages();
21445
21615
  const catalogs = yield* catalogsService.set();
21616
+ const importerVersions = yield* catalogsService.importerVersions();
21446
21617
  const snapshotPackages = packages.map((pkg) => PackageStateSnapshot.make({
21447
21618
  name: pkg.name,
21448
21619
  version: pkg.version,
@@ -21454,7 +21625,8 @@ var WorkspaceSnapshots = class WorkspaceSnapshots extends effect.Context.Service
21454
21625
  }));
21455
21626
  return WorkspaceStateSnapshot.make({
21456
21627
  packages: snapshotPackages,
21457
- catalogs
21628
+ catalogs,
21629
+ importerVersions
21458
21630
  });
21459
21631
  })
21460
21632
  };
@@ -21469,7 +21641,7 @@ var WorkspaceSnapshots = class WorkspaceSnapshots extends effect.Context.Service
21469
21641
  static layer = (options) => effect.Layer.effect(WorkspaceSnapshots, WorkspaceSnapshots.make(options));
21470
21642
  };
21471
21643
  //#endregion
21472
- //#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
21644
+ //#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
21473
21645
  /**
21474
21646
  * Every service that needs only a filesystem: root, package-manager detection,
21475
21647
  * discovery, lockfile reading, catalogs and publishability.
@@ -43160,6 +43332,80 @@ function isUint8Array(value) {
43160
43332
  //#endregion
43161
43333
  //#region ../silk-effects/dist/dev/pkg/changesets/utils/remark-pipeline.js
43162
43334
  /**
43335
+ * Marker set on the `data` of a text node whose value must be written to
43336
+ * markdown verbatim rather than escaped.
43337
+ *
43338
+ * @remarks
43339
+ * `remark-stringify` escapes any character that could open a markdown
43340
+ * construct. Inside a dependency table that is always wrong: with
43341
+ * `remark-gfm` enabled `~` is the strikethrough delimiter, so the specifier
43342
+ * `~0.2.1` is written as `\~0.2.1`, and `_` in a package name becomes `\_`.
43343
+ * The corruption compounds on every re-serialization, and dependency-table
43344
+ * cells round-trip through consolidation and PR-body reconstruction.
43345
+ *
43346
+ * The marker is deliberately narrow. It is set only by the dependency-table
43347
+ * cell builder, whose cell vocabulary is closed — package name, dependency
43348
+ * type, action, version specifier, and the em-dash sentinel — and none of
43349
+ * those can legitimately carry markdown. Prose elsewhere in a changeset keeps
43350
+ * the default escaping.
43351
+ *
43352
+ * @internal
43353
+ */
43354
+ const LITERAL_TEXT_MARKER = "silkLiteralText";
43355
+ /**
43356
+ * Mark a text node so {@link createRemarkProcessor} writes it verbatim.
43357
+ *
43358
+ * @param value - The literal cell text
43359
+ * @returns An MDAST `Text` node carrying the literal marker
43360
+ *
43361
+ * @internal
43362
+ */
43363
+ function literalText(value) {
43364
+ return {
43365
+ type: "text",
43366
+ value,
43367
+ data: { [LITERAL_TEXT_MARKER]: true }
43368
+ };
43369
+ }
43370
+ /**
43371
+ * Whether a text node was marked by {@link literalText}.
43372
+ *
43373
+ * @internal
43374
+ */
43375
+ function isLiteralText(node) {
43376
+ return node.data?.[LITERAL_TEXT_MARKER] === true;
43377
+ }
43378
+ /**
43379
+ * Escape the two characters that would otherwise corrupt the table grid.
43380
+ *
43381
+ * @remarks
43382
+ * A `|` would close the cell early and a `\` would be read as an escape
43383
+ * introducer, so both are escaped to keep the written cell parseable back to
43384
+ * its exact input. Every other character is emitted as-is. Because parsing
43385
+ * consumes the backslash, a value that already carries a legacy `\~` from the
43386
+ * old escaping path re-parses to its clean form rather than accumulating
43387
+ * another layer.
43388
+ *
43389
+ * @internal
43390
+ */
43391
+ function escapeCellLiteral(value) {
43392
+ return value.replace(/[\\|]/g, "\\$&");
43393
+ }
43394
+ /**
43395
+ * `mdast-util-to-markdown` handler overrides used by the shared processor.
43396
+ *
43397
+ * @remarks
43398
+ * Replaces the default `text` handler — which is `state.safe(node.value, info)`
43399
+ * — with one that bypasses escaping for nodes marked by {@link literalText}
43400
+ * and delegates to the default behavior for everything else.
43401
+ *
43402
+ * @internal
43403
+ */
43404
+ const literalTextHandlers = { text: (node, _parent, state, info) => {
43405
+ const text = node;
43406
+ return isLiteralText(text) ? escapeCellLiteral(text.value) : state.safe(text.value, info);
43407
+ } };
43408
+ /**
43163
43409
  * Create a unified processor configured with remark-parse, remark-gfm,
43164
43410
  * and remark-stringify.
43165
43411
  *
@@ -43167,7 +43413,8 @@ function isUint8Array(value) {
43167
43413
  * Each call creates a fresh processor instance. The plugin chain is:
43168
43414
  * 1. `remark-parse` — markdown to MDAST
43169
43415
  * 2. `remark-gfm` — GitHub Flavored Markdown extensions (tables, etc.)
43170
- * 3. `remark-stringify` — MDAST back to markdown
43416
+ * 3. `remark-stringify` — MDAST back to markdown, with the
43417
+ * {@link literalText} handler override
43171
43418
  *
43172
43419
  * @privateRemarks
43173
43420
  * Return type is intentionally inferred because the unified `Processor`
@@ -43178,7 +43425,7 @@ function isUint8Array(value) {
43178
43425
  * @internal
43179
43426
  */
43180
43427
  function createRemarkProcessor() {
43181
- return unified().use(remarkParse).use(remarkGfm).use(remarkStringify);
43428
+ return unified().use(remarkParse).use(remarkGfm).use(remarkStringify, { handlers: literalTextHandlers });
43182
43429
  }
43183
43430
  /**
43184
43431
  * Parse a markdown string into an MDAST AST synchronously.
@@ -43686,6 +43933,12 @@ function parseDependencyTable(table) {
43686
43933
  /**
43687
43934
  * Create a table cell with a text node.
43688
43935
  *
43936
+ * @remarks
43937
+ * The cell text is marked literal, so stringification writes it verbatim
43938
+ * instead of escaping characters that could open a markdown construct. See
43939
+ * {@link literalText} — without it `~0.2.1` is written as `\~0.2.1` and
43940
+ * `some_pkg` as `some\_pkg`.
43941
+ *
43689
43942
  * @param text - The cell text content
43690
43943
  * @returns An MDAST `TableCell` node
43691
43944
  *
@@ -43694,10 +43947,7 @@ function parseDependencyTable(table) {
43694
43947
  function makeCell(text) {
43695
43948
  return {
43696
43949
  type: "tableCell",
43697
- children: [{
43698
- type: "text",
43699
- value: text
43700
- }]
43950
+ children: [literalText(text)]
43701
43951
  };
43702
43952
  }
43703
43953
  /**
@@ -43772,11 +44022,10 @@ function serializeDependencyTable(rows) {
43772
44022
  * @internal
43773
44023
  */
43774
44024
  function serializeDependencyTableToMarkdown(rows) {
43775
- const tree = {
44025
+ return stringifyMarkdown({
43776
44026
  type: "root",
43777
44027
  children: [serializeDependencyTable(rows)]
43778
- };
43779
- return unified().use(remarkGfm).use(remarkStringify).stringify(tree).trim();
44028
+ }).trim();
43780
44029
  }
43781
44030
  /**
43782
44031
  * Sort priority for dependency actions: removed first, then updated, then added.
@@ -46968,10 +47217,23 @@ const DEP_TYPE_MAP = [
46968
47217
  ["optionalDependencies", "optionalDependency"]
46969
47218
  ];
46970
47219
  /**
46971
- * Resolve a specifier against the snapshot it belongs to, falling back to
46972
- * the raw specifier string when the snapshot cannot resolve it.
46973
- */
46974
- const resolveOrRaw = (snapshot, dep, spec) => effect.Option.getOrElse(snapshot.resolve(dep, spec), () => spec);
47220
+ * Resolve a specifier against the snapshot it belongs to, scoped to the
47221
+ * importer that declared it, falling back to the raw specifier string when
47222
+ * the snapshot cannot resolve it.
47223
+ *
47224
+ * @remarks
47225
+ * Uses `resolveIn` rather than the workspace-wide `resolve`. Both consult the
47226
+ * ref's own lockfile importer entries when a `catalog:` specifier is not in the
47227
+ * catalog set — which is what makes hook-injected catalogs (`catalog:effect:peers`,
47228
+ * injected by a config-dependency pnpmfile and recorded in neither
47229
+ * `pnpm-workspace.yaml` nor the lockfile's `catalogs:` block) resolvable at all.
47230
+ * The workspace-wide form abstains whenever two importers disagree on a
47231
+ * dependency's version, which in a multi-package repo reproduces the original
47232
+ * defect: both sides fall back to the identical raw specifier, compare equal,
47233
+ * and emit no row. Scoping to the declaring importer answers precisely where
47234
+ * the workspace-wide form cannot.
47235
+ */
47236
+ const resolveOrRaw = (snapshot, importerPath, dep, spec) => effect.Option.getOrElse(snapshot.resolveIn(importerPath, dep, spec), () => spec);
46975
47237
  /**
46976
47238
  * Drop no-net-change field moves: the same dependency removed from one field
46977
47239
  * and added to another with an equal resolved version (e.g. a dep promoted
@@ -47016,13 +47278,15 @@ function computeWorkspaceDependencyDiffs(before, after) {
47016
47278
  for (const afterPkg of after.packages) {
47017
47279
  const beforePkg = effect.Option.getOrNull(before.package(afterPkg.name));
47018
47280
  const rows = [];
47281
+ const afterImporter = afterPkg.relativePath;
47282
+ const beforeImporter = beforePkg?.relativePath ?? afterImporter;
47019
47283
  for (const [field, type] of DEP_TYPE_MAP) {
47020
47284
  const beforeRecord = beforePkg?.[field] ?? {};
47021
47285
  const afterRecord = afterPkg[field];
47022
47286
  const seen = /* @__PURE__ */ new Set();
47023
47287
  for (const [name, beforeSpec] of Object.entries(beforeRecord)) {
47024
47288
  seen.add(name);
47025
- const from = resolveOrRaw(before, name, beforeSpec);
47289
+ const from = resolveOrRaw(before, beforeImporter, name, beforeSpec);
47026
47290
  const afterSpec = afterRecord[name];
47027
47291
  if (afterSpec === void 0) {
47028
47292
  rows.push({
@@ -47034,7 +47298,7 @@ function computeWorkspaceDependencyDiffs(before, after) {
47034
47298
  });
47035
47299
  continue;
47036
47300
  }
47037
- const to = resolveOrRaw(after, name, afterSpec);
47301
+ const to = resolveOrRaw(after, afterImporter, name, afterSpec);
47038
47302
  if (from !== to) rows.push({
47039
47303
  dependency: name,
47040
47304
  type,
@@ -47050,7 +47314,7 @@ function computeWorkspaceDependencyDiffs(before, after) {
47050
47314
  type,
47051
47315
  action: "added",
47052
47316
  from: EM_DASH$1,
47053
- to: resolveOrRaw(after, name, afterSpec)
47317
+ to: resolveOrRaw(after, afterImporter, name, afterSpec)
47054
47318
  });
47055
47319
  }
47056
47320
  }
@@ -65196,8 +65460,38 @@ function getHeadingLevel(heading) {
65196
65460
  return sequence ? sequence.text.length : 0;
65197
65461
  }
65198
65462
  /**
65463
+ * CommonMark backslash escapes: a backslash is literal unless it precedes an
65464
+ * ASCII punctuation character, in which case the pair denotes that character.
65465
+ */
65466
+ const BACKSLASH_ESCAPE_RE = /\\([!-/:-@[-`{-~])/g;
65467
+ /**
65468
+ * Resolve CommonMark backslash escapes in raw micromark source text.
65469
+ *
65470
+ * @remarks
65471
+ * Every rule in this directory has a sibling remark implementation that reads
65472
+ * the parsed mdast tree, where the parser has already resolved escapes, via
65473
+ * `mdast-util-to-string`. Micromark tokens instead carry RAW source. Comparing
65474
+ * raw text against a value the parsed form would produce makes the two
65475
+ * implementations of one documented rule disagree about the same file
65476
+ * (issue #367).
65477
+ *
65478
+ * Applied at the shared extractors below so both implementations judge the
65479
+ * value a reader actually sees, rather than per-rule where the next extractor
65480
+ * added would silently reintroduce the split.
65481
+ *
65482
+ * @internal
65483
+ */
65484
+ function unescapeMarkdown(raw) {
65485
+ return raw.replace(BACKSLASH_ESCAPE_RE, "$1");
65486
+ }
65487
+ /**
65199
65488
  * Get the plain text content of an `atxHeading` token.
65200
65489
  *
65490
+ * @remarks
65491
+ * Escape-resolved, so a heading compares equal to the same heading as the
65492
+ * remark rules see it. `getHeadingLevel` needs no equivalent — it counts
65493
+ * sequence characters rather than reading text.
65494
+ *
65201
65495
  * @param heading - The `atxHeading` micromark token
65202
65496
  * @returns The heading text, or empty string if no text token found
65203
65497
  *
@@ -65205,7 +65499,7 @@ function getHeadingLevel(heading) {
65205
65499
  */
65206
65500
  function getHeadingText(heading) {
65207
65501
  const textToken = heading.children.find((c) => c.type === "atxHeadingText");
65208
- return textToken ? textToken.text : "";
65502
+ return textToken ? unescapeMarkdown(textToken.text) : "";
65209
65503
  }
65210
65504
  //#endregion
65211
65505
  //#region ../silk-effects/dist/dev/pkg/changesets/markdownlint/rules/content-structure.js
@@ -65330,13 +65624,13 @@ const EXPECTED_HEADERS = [
65330
65624
  * The `tableContent` token has a `.text` property with the cell value.
65331
65625
  *
65332
65626
  * @param cell - A GFM table cell token (header or data)
65333
- * @returns The trimmed text content of the cell, or an empty string
65627
+ * @returns The trimmed, escape-resolved text content of the cell, or an empty string
65334
65628
  *
65335
65629
  * @internal
65336
65630
  */
65337
65631
  function getCellText(cell) {
65338
65632
  const content = cell.children.find((c) => c.type === "tableContent");
65339
- return content ? content.text.trim() : "";
65633
+ return content ? unescapeMarkdown(content.text.trim()) : "";
65340
65634
  }
65341
65635
  /**
65342
65636
  * Extract all cell texts from a `tableRow` token.