@savvy-web/silk 3.8.0 → 3.8.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.
@@ -5829,7 +5829,7 @@ declare class GlobPattern extends GlobPattern_base {
5829
5829
  static readonly FromString: Schema.Codec<GlobPattern, string>;
5830
5830
  }
5831
5831
  //#endregion
5832
- //#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/index.d.ts
5832
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.6.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_b5e24f85b508eca09bd100b8bd2084bb/node_modules/@effected/lockfiles/index.d.ts
5833
5833
  //#region src/BunExtension.d.ts
5834
5834
  declare const BunExtension_base: Schema.Class<BunExtension, Schema.Struct<{
5835
5835
  readonly _tag: Schema.tag<"bun">;
@@ -5894,7 +5894,7 @@ declare class ImporterDependency extends ImporterDependency_base {}
5894
5894
  //#region src/LockfileFormat.d.ts
5895
5895
  /**
5896
5896
  * The lockfile formats this package parses: bun's `bun.lock` (JSONC), npm's
5897
- * `package-lock.json` (v2/v3 JSON), pnpm's `pnpm-lock.yaml` and yarn Berry's
5897
+ * `package-lock.json` (JSON), pnpm's `pnpm-lock.yaml` and yarn Berry's
5898
5898
  * `yarn.lock` (both YAML).
5899
5899
  *
5900
5900
  * @remarks
@@ -5903,6 +5903,10 @@ declare class ImporterDependency extends ImporterDependency_base {}
5903
5903
  * Berry only; classic (v1) `yarn.lock` is not YAML and fails
5904
5904
  * `Lockfile.parse` with a typed `LockfileParseError`.
5905
5905
  *
5906
+ * The format literal says nothing about which *versions* of that format are
5907
+ * supported: pnpm `lockfileVersion` 9+ and npm `lockfileVersion` 3+ parse,
5908
+ * and older ones fail typed. See `Lockfile.parse`.
5909
+ *
5906
5910
  * @public
5907
5911
  */
5908
5912
  declare const LockfileFormat: Schema.Literals<readonly ["bun", "npm", "pnpm", "yarn"]>;
@@ -5966,6 +5970,7 @@ declare class PnpmExtension extends PnpmExtension_base {}
5966
5970
  declare const ResolvedPackage_base: Schema.Class<ResolvedPackage, Schema.Struct<{
5967
5971
  readonly name: Schema.NonEmptyString;
5968
5972
  readonly version: Schema.String;
5973
+ readonly instanceId: Schema.NonEmptyString;
5969
5974
  readonly integrity: Schema.optionalKey<Schema.brand<Schema.String, "IntegrityHash"> & {
5970
5975
  isSri: (value: string) => boolean;
5971
5976
  isCorepack: (value: string) => boolean;
@@ -5977,6 +5982,12 @@ declare const ResolvedPackage_base: Schema.Class<ResolvedPackage, Schema.Struct<
5977
5982
  readonly isWorkspace: Schema.Boolean;
5978
5983
  readonly relativePath: Schema.optionalKey<Schema.String>;
5979
5984
  readonly dependencies: Schema.withConstructorDefault<Schema.withDecodingDefaultKey<Schema.$Record<Schema.String, Schema.String>, never>>;
5985
+ readonly peerDependencies: Schema.withConstructorDefault<Schema.withDecodingDefaultKey<Schema.$Record<Schema.String, Schema.String>, never>>;
5986
+ readonly peerDependenciesMeta: Schema.withConstructorDefault<Schema.withDecodingDefaultKey<Schema.$Record<Schema.String, Schema.Struct<{
5987
+ readonly optional: Schema.Boolean;
5988
+ }>>, never>>;
5989
+ readonly resolved: Schema.withConstructorDefault<Schema.withDecodingDefaultKey<Schema.$Record<Schema.String, Schema.String>, never>>;
5990
+ readonly unresolvedEdges: Schema.withConstructorDefault<Schema.withDecodingDefaultKey<Schema.$Array<Schema.String>, never>>;
5980
5991
  }>, {}>;
5981
5992
  /**
5982
5993
  * A package resolved from a lockfile.
@@ -5984,6 +5995,13 @@ declare const ResolvedPackage_base: Schema.Class<ResolvedPackage, Schema.Struct<
5984
5995
  * @remarks
5985
5996
  * The common shape every format's entries normalize into:
5986
5997
  *
5998
+ * - `instanceId` — the lockfile-native identity of this *instance*, verbatim:
5999
+ * pnpm's snapshot key (`react-dom@18.3.1(react@17.0.2)`), npm's full entry
6000
+ * key (`node_modules/express/node_modules/debug`), bun's `packages` key
6001
+ * (`@acme/lib/react-dom`) or yarn's locator (`react-dom@npm:18.3.1`). It is
6002
+ * **opaque** — no scheme is synthesized and none should be parsed by a
6003
+ * consumer; it exists so `resolved` can name an instance, and so two
6004
+ * peer-resolved variants of one `name@version` stay distinguishable.
5987
6005
  * - `name` — the resolved package name. For pnpm *workspace* packages
5988
6006
  * straight out of `Lockfile.parse` this is the importer path until
5989
6007
  * `Lockfile#withImporterNames` rewrites it.
@@ -5999,6 +6017,47 @@ declare const ResolvedPackage_base: Schema.Class<ResolvedPackage, Schema.Struct<
5999
6017
  * packages, when the lockfile records one.
6000
6018
  * - `dependencies` — the package's own dependency map, defaulting to `{}`
6001
6019
  * both at construction and when decoding serialized data.
6020
+ * - `peerDependencies` — the package's *declared* peer ranges, keyed by peer
6021
+ * name. Every format records them (pnpm and npm as their own section, bun
6022
+ * inline in the package tuple's info object, yarn Berry as an entry
6023
+ * section), so this is populated across all four. Declarations only: what
6024
+ * the package *asks for*, never what actually resolved.
6025
+ * - `peerDependenciesMeta` — the per-peer flags, normalized to
6026
+ * `{ optional: boolean }`. bun spells optional peers as an `optionalPeers`
6027
+ * array of names rather than a meta object; that spelling is normalized
6028
+ * into this shape so one consumer algorithm serves every format. A peer
6029
+ * with no meta entry is required.
6030
+ * - `resolved` — this instance's *outgoing edges*: dependency (and, where the
6031
+ * format records it, peer) name → the `instanceId` that name actually
6032
+ * resolved to in this instance's context. This is the answer to "which
6033
+ * concrete version of P did X get", which `peerDependencies` deliberately
6034
+ * does not answer.
6035
+ *
6036
+ * Every entry is **verified**: an edge is emitted only when the composed or
6037
+ * walked-up identity matches a real instance in the same lockfile. An edge
6038
+ * that cannot be resolved honestly is *omitted*, never guessed — a wrong
6039
+ * resolved edge is a silent wrong answer, an absent one is a visible gap.
6040
+ * yarn records peer resolution virtually and is therefore dependency-edges
6041
+ * only.
6042
+ *
6043
+ * - `unresolvedEdges` — dependency names whose edge the lockfile **records**
6044
+ * but this model could not name: a `link:` target that is not a workspace
6045
+ * importer, a composed identity matching no instance. It is the companion
6046
+ * `resolved` needs to be honest, because an absent key in `resolved` would
6047
+ * otherwise mean two different things — "nothing is there" and "something is
6048
+ * there that I could not name" — and a consumer reading the first meaning
6049
+ * for the second turns this package's gap into its own false positive.
6050
+ *
6051
+ * A dependency the lockfile simply does not record is **not** an unresolved
6052
+ * edge; it is an absence, and must not appear here. npm and bun contribute
6053
+ * nothing at all: their sections are *declarations* resolved positionally, so
6054
+ * "the walk found nothing" is genuine absence. A fail-closed signal that is
6055
+ * always on is a signal nobody reads.
6056
+ *
6057
+ * All four record fields — `dependencies`, `peerDependencies`,
6058
+ * `peerDependenciesMeta` and `resolved` — default to `{}` at construction and
6059
+ * when decoding, and `unresolvedEdges` defaults to `[]`. An absent section is
6060
+ * therefore an empty collection, never `undefined`.
6002
6061
  *
6003
6062
  * @public
6004
6063
  */
@@ -6844,7 +6903,7 @@ declare class Package extends Package_base {
6844
6903
  toJsonString(options?: PackageFormatOptions): string;
6845
6904
  }
6846
6905
  //#endregion
6847
- //#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/index.d.ts
6906
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/index.d.ts
6848
6907
  //#region src/WorkspacePackage.d.ts
6849
6908
  declare const PublishConfig_base: Schema.Class<PublishConfig, Schema.Struct<{
6850
6909
  /** Scoped-package visibility. Its presence overrides `private`. */
@@ -7512,6 +7571,37 @@ declare class WorkspaceDiscovery extends WorkspaceDiscovery_base {
7512
7571
  }
7513
7572
  //#endregion
7514
7573
  //#region src/ConfigDependencyHooks.d.ts
7574
+ /**
7575
+ * pnpm's `peerDependencyRules` block — the suppression policy pnpm applies
7576
+ * **after** computing peer violations, in pnpm's own shape.
7577
+ *
7578
+ * @remarks
7579
+ * The shape is pnpm's rather than ours because that is what comes back off the
7580
+ * threaded config: measured against `@savvy-web/pnpm-plugin-silk@0.27.0`, a
7581
+ * replayed hook returns `{ allowedVersions, ignoreMissing, allowAny }` intact,
7582
+ * needing no reshaping.
7583
+ *
7584
+ * Two keys are **carried but not yet consumed**. `ignoreMissing` and
7585
+ * `allowAny` are separate suppression axes that have not been measured, and an
7586
+ * unmeasured suppression is precisely what produced the false positives this
7587
+ * seam exists to remove — so they travel through the seam and no kit code acts
7588
+ * on them. Only `allowedVersions` is consumed today.
7589
+ *
7590
+ * `allowedVersions` keys come in two spellings in the wild, and both must be
7591
+ * handled: parent-versioned (`"@effect/ai-anthropic@4.0.0-rc.109>effect"`, as
7592
+ * `pnpm:export` materializes them into `pnpm-workspace.yaml`) and unversioned
7593
+ * (`"@effect/vitest>vitest"`, as a config-dependency plugin injects them).
7594
+ *
7595
+ * @public
7596
+ */
7597
+ interface PeerDependencyRules {
7598
+ /** `parent>peer` → the peer version or range the rule permits. */
7599
+ readonly allowedVersions: Readonly<Record<string, string>>;
7600
+ /** Peer names whose absence pnpm does not report. Carried, not consumed. */
7601
+ readonly ignoreMissing: ReadonlyArray<string>;
7602
+ /** Peer names for which any version is accepted. Carried, not consumed. */
7603
+ readonly allowAny: ReadonlyArray<string>;
7604
+ }
7515
7605
  /**
7516
7606
  * The result of replaying a workspace's `configDependencies` hooks: the catalogs
7517
7607
  * the hooks yield, and the release-age gate contribution they leave on the
@@ -7531,6 +7621,24 @@ interface HookInjection {
7531
7621
  readonly catalogs: Readonly<Record<string, Readonly<Record<string, string>>>>;
7532
7622
  /** The release-age gate contribution the replayed hooks leave on the config. */
7533
7623
  readonly releaseAge: PartialReleaseAgeGate;
7624
+ /**
7625
+ * The **effective** peer-dependency rules: the seeded workspace-file rules
7626
+ * with every replayed hook's contribution threaded over them.
7627
+ *
7628
+ * @remarks
7629
+ * Effective rather than hook-only because the rules are **seeded** into the
7630
+ * threaded config and the hooks merge onto them, exactly as pnpm seeds its
7631
+ * own config and takes back what the hooks return. That is deliberate: a
7632
+ * kit-owned merge function would be a second implementation of a rule this
7633
+ * seam already enforces, and the two would drift the first time pnpm changed
7634
+ * its threading.
7635
+ *
7636
+ * Measured caveat, and **not a bug to fix**: this repo's plugin *merges*
7637
+ * onto the seeded rules; another plugin could overwrite them. Under seeding
7638
+ * that is pnpm's own behaviour reproduced — a hook that overwrites
7639
+ * overwrites for pnpm too — so do not "repair" it into a merger.
7640
+ */
7641
+ readonly peerDependencyRules: PeerDependencyRules;
7534
7642
  }
7535
7643
  /**
7536
7644
  * The {@link ConfigDependencyHooks} service shape.
@@ -7568,8 +7676,12 @@ interface ConfigDependencyHooksShape {
7568
7676
  * @param configDependencies - The `configDependencies` map (name →
7569
7677
  * version+integrity) declared in `pnpm-workspace.yaml`.
7570
7678
  * @param seed - The inline catalogs, as `catalog name → dependency → range`.
7679
+ * @param rules - The workspace file's `peerDependencyRules`, seeded into the
7680
+ * threaded config so hooks merge onto them rather than replacing them.
7681
+ * Omitted means "the workspace file declares none", which is different
7682
+ * from "nobody looked" — the caller owns that distinction.
7571
7683
  */
7572
- readonly inject: (root: string, configDependencies: Readonly<Record<string, string>>, seed: Readonly<Record<string, Readonly<Record<string, string>>>>) => Effect.Effect<HookInjection, CatalogAssemblyError>;
7684
+ readonly inject: (root: string, configDependencies: Readonly<Record<string, string>>, seed: Readonly<Record<string, Readonly<Record<string, string>>>>, rules?: PeerDependencyRules) => Effect.Effect<HookInjection, CatalogAssemblyError>;
7573
7685
  }
7574
7686
  declare const ConfigDependencyHooks_base: Context.ServiceClass<ConfigDependencyHooks, "@effected/workspaces/ConfigDependencyHooks", ConfigDependencyHooksShape>;
7575
7687
  /**
@@ -8048,7 +8160,16 @@ declare class PublishTarget extends PublishTarget_base {}
8048
8160
  * @public
8049
8161
  */
8050
8162
  interface PublishabilityDetectorShape {
8051
- /** The publish targets for a package; empty means it does not publish. */
8163
+ /**
8164
+ * The publish targets for a package; empty means it does not publish.
8165
+ *
8166
+ * @remarks
8167
+ * `VersioningStrategy.detect` probes a whole workspace by invoking this
8168
+ * concurrently — up to ten packages in flight at once, in no guaranteed
8169
+ * order. An overriding implementation backed by shared mutable state or a
8170
+ * rate-limited client must tolerate that interleaving itself; the caller
8171
+ * does not serialize on its behalf.
8172
+ */
8052
8173
  readonly detect: (pkg: WorkspacePackage) => Effect.Effect<ReadonlyArray<PublishTarget>>;
8053
8174
  }
8054
8175
  declare const PublishabilityDetector_base: Context.ServiceClass<PublishabilityDetector, "@effected/workspaces/PublishabilityDetector", PublishabilityDetectorShape>;
@@ -8333,6 +8454,26 @@ interface WorkspaceCatalogsShape {
8333
8454
  * workspace) has no release-age keys, so the gate is the inert zero gate.
8334
8455
  */
8335
8456
  readonly releaseAgeGate: () => Effect.Effect<ReleaseAgeGate, CatalogAssemblyFailure>;
8457
+ /**
8458
+ * The workspace's **effective** `peerDependencyRules` — pnpm's post-hoc
8459
+ * suppression policy, which the lockfile does not record at all.
8460
+ *
8461
+ * @remarks
8462
+ * Assembled from the same single read and hook replay as `set`, and memoized
8463
+ * with it. The `pnpm-workspace.yaml` block (what `pnpm:export` materializes)
8464
+ * is **seeded** into the replayed config and the config-dependency hooks
8465
+ * merge onto it, so one object carries both sources — the kit never merges
8466
+ * them itself, because that would be a second implementation of a rule the
8467
+ * hook seam already enforces.
8468
+ *
8469
+ * A consumer needs these to avoid **reporting** what pnpm suppresses: pnpm
8470
+ * computes the same peer violations and then hides the ones a rule allows,
8471
+ * so a checker without them reports findings pnpm calls clean.
8472
+ *
8473
+ * `ignoreMissing` and `allowAny` are carried but unmeasured — no kit code
8474
+ * acts on them today.
8475
+ */
8476
+ readonly peerDependencyRules: () => Effect.Effect<PeerDependencyRules, CatalogAssemblyFailure>;
8336
8477
  /**
8337
8478
  * Each importer's dependency-name → resolved-version map, as the manager's
8338
8479
  * lockfile records it. Read from the same single lockfile read as `set`, and
@@ -5829,7 +5829,7 @@ declare class GlobPattern extends GlobPattern_base {
5829
5829
  static readonly FromString: Schema.Codec<GlobPattern, string>;
5830
5830
  }
5831
5831
  //#endregion
5832
- //#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/index.d.ts
5832
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.6.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__@effected+npm@0.11_b5e24f85b508eca09bd100b8bd2084bb/node_modules/@effected/lockfiles/index.d.ts
5833
5833
  //#region src/BunExtension.d.ts
5834
5834
  declare const BunExtension_base: Schema.Class<BunExtension, Schema.Struct<{
5835
5835
  readonly _tag: Schema.tag<"bun">;
@@ -5894,7 +5894,7 @@ declare class ImporterDependency extends ImporterDependency_base {}
5894
5894
  //#region src/LockfileFormat.d.ts
5895
5895
  /**
5896
5896
  * The lockfile formats this package parses: bun's `bun.lock` (JSONC), npm's
5897
- * `package-lock.json` (v2/v3 JSON), pnpm's `pnpm-lock.yaml` and yarn Berry's
5897
+ * `package-lock.json` (JSON), pnpm's `pnpm-lock.yaml` and yarn Berry's
5898
5898
  * `yarn.lock` (both YAML).
5899
5899
  *
5900
5900
  * @remarks
@@ -5903,6 +5903,10 @@ declare class ImporterDependency extends ImporterDependency_base {}
5903
5903
  * Berry only; classic (v1) `yarn.lock` is not YAML and fails
5904
5904
  * `Lockfile.parse` with a typed `LockfileParseError`.
5905
5905
  *
5906
+ * The format literal says nothing about which *versions* of that format are
5907
+ * supported: pnpm `lockfileVersion` 9+ and npm `lockfileVersion` 3+ parse,
5908
+ * and older ones fail typed. See `Lockfile.parse`.
5909
+ *
5906
5910
  * @public
5907
5911
  */
5908
5912
  declare const LockfileFormat: Schema.Literals<readonly ["bun", "npm", "pnpm", "yarn"]>;
@@ -5966,6 +5970,7 @@ declare class PnpmExtension extends PnpmExtension_base {}
5966
5970
  declare const ResolvedPackage_base: Schema.Class<ResolvedPackage, Schema.Struct<{
5967
5971
  readonly name: Schema.NonEmptyString;
5968
5972
  readonly version: Schema.String;
5973
+ readonly instanceId: Schema.NonEmptyString;
5969
5974
  readonly integrity: Schema.optionalKey<Schema.brand<Schema.String, "IntegrityHash"> & {
5970
5975
  isSri: (value: string) => boolean;
5971
5976
  isCorepack: (value: string) => boolean;
@@ -5977,6 +5982,12 @@ declare const ResolvedPackage_base: Schema.Class<ResolvedPackage, Schema.Struct<
5977
5982
  readonly isWorkspace: Schema.Boolean;
5978
5983
  readonly relativePath: Schema.optionalKey<Schema.String>;
5979
5984
  readonly dependencies: Schema.withConstructorDefault<Schema.withDecodingDefaultKey<Schema.$Record<Schema.String, Schema.String>, never>>;
5985
+ readonly peerDependencies: Schema.withConstructorDefault<Schema.withDecodingDefaultKey<Schema.$Record<Schema.String, Schema.String>, never>>;
5986
+ readonly peerDependenciesMeta: Schema.withConstructorDefault<Schema.withDecodingDefaultKey<Schema.$Record<Schema.String, Schema.Struct<{
5987
+ readonly optional: Schema.Boolean;
5988
+ }>>, never>>;
5989
+ readonly resolved: Schema.withConstructorDefault<Schema.withDecodingDefaultKey<Schema.$Record<Schema.String, Schema.String>, never>>;
5990
+ readonly unresolvedEdges: Schema.withConstructorDefault<Schema.withDecodingDefaultKey<Schema.$Array<Schema.String>, never>>;
5980
5991
  }>, {}>;
5981
5992
  /**
5982
5993
  * A package resolved from a lockfile.
@@ -5984,6 +5995,13 @@ declare const ResolvedPackage_base: Schema.Class<ResolvedPackage, Schema.Struct<
5984
5995
  * @remarks
5985
5996
  * The common shape every format's entries normalize into:
5986
5997
  *
5998
+ * - `instanceId` — the lockfile-native identity of this *instance*, verbatim:
5999
+ * pnpm's snapshot key (`react-dom@18.3.1(react@17.0.2)`), npm's full entry
6000
+ * key (`node_modules/express/node_modules/debug`), bun's `packages` key
6001
+ * (`@acme/lib/react-dom`) or yarn's locator (`react-dom@npm:18.3.1`). It is
6002
+ * **opaque** — no scheme is synthesized and none should be parsed by a
6003
+ * consumer; it exists so `resolved` can name an instance, and so two
6004
+ * peer-resolved variants of one `name@version` stay distinguishable.
5987
6005
  * - `name` — the resolved package name. For pnpm *workspace* packages
5988
6006
  * straight out of `Lockfile.parse` this is the importer path until
5989
6007
  * `Lockfile#withImporterNames` rewrites it.
@@ -5999,6 +6017,47 @@ declare const ResolvedPackage_base: Schema.Class<ResolvedPackage, Schema.Struct<
5999
6017
  * packages, when the lockfile records one.
6000
6018
  * - `dependencies` — the package's own dependency map, defaulting to `{}`
6001
6019
  * both at construction and when decoding serialized data.
6020
+ * - `peerDependencies` — the package's *declared* peer ranges, keyed by peer
6021
+ * name. Every format records them (pnpm and npm as their own section, bun
6022
+ * inline in the package tuple's info object, yarn Berry as an entry
6023
+ * section), so this is populated across all four. Declarations only: what
6024
+ * the package *asks for*, never what actually resolved.
6025
+ * - `peerDependenciesMeta` — the per-peer flags, normalized to
6026
+ * `{ optional: boolean }`. bun spells optional peers as an `optionalPeers`
6027
+ * array of names rather than a meta object; that spelling is normalized
6028
+ * into this shape so one consumer algorithm serves every format. A peer
6029
+ * with no meta entry is required.
6030
+ * - `resolved` — this instance's *outgoing edges*: dependency (and, where the
6031
+ * format records it, peer) name → the `instanceId` that name actually
6032
+ * resolved to in this instance's context. This is the answer to "which
6033
+ * concrete version of P did X get", which `peerDependencies` deliberately
6034
+ * does not answer.
6035
+ *
6036
+ * Every entry is **verified**: an edge is emitted only when the composed or
6037
+ * walked-up identity matches a real instance in the same lockfile. An edge
6038
+ * that cannot be resolved honestly is *omitted*, never guessed — a wrong
6039
+ * resolved edge is a silent wrong answer, an absent one is a visible gap.
6040
+ * yarn records peer resolution virtually and is therefore dependency-edges
6041
+ * only.
6042
+ *
6043
+ * - `unresolvedEdges` — dependency names whose edge the lockfile **records**
6044
+ * but this model could not name: a `link:` target that is not a workspace
6045
+ * importer, a composed identity matching no instance. It is the companion
6046
+ * `resolved` needs to be honest, because an absent key in `resolved` would
6047
+ * otherwise mean two different things — "nothing is there" and "something is
6048
+ * there that I could not name" — and a consumer reading the first meaning
6049
+ * for the second turns this package's gap into its own false positive.
6050
+ *
6051
+ * A dependency the lockfile simply does not record is **not** an unresolved
6052
+ * edge; it is an absence, and must not appear here. npm and bun contribute
6053
+ * nothing at all: their sections are *declarations* resolved positionally, so
6054
+ * "the walk found nothing" is genuine absence. A fail-closed signal that is
6055
+ * always on is a signal nobody reads.
6056
+ *
6057
+ * All four record fields — `dependencies`, `peerDependencies`,
6058
+ * `peerDependenciesMeta` and `resolved` — default to `{}` at construction and
6059
+ * when decoding, and `unresolvedEdges` defaults to `[]`. An absent section is
6060
+ * therefore an empty collection, never `undefined`.
6002
6061
  *
6003
6062
  * @public
6004
6063
  */
@@ -6844,7 +6903,7 @@ declare class Package extends Package_base {
6844
6903
  toJsonString(options?: PackageFormatOptions): string;
6845
6904
  }
6846
6905
  //#endregion
6847
- //#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/index.d.ts
6906
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.15.1_@effected+jsonc@0.7.0_effect@4.0.0-rc.109__effect@4.0.0-rc.109/node_modules/@effected/workspaces/index.d.ts
6848
6907
  //#region src/WorkspacePackage.d.ts
6849
6908
  declare const PublishConfig_base: Schema.Class<PublishConfig, Schema.Struct<{
6850
6909
  /** Scoped-package visibility. Its presence overrides `private`. */
@@ -7512,6 +7571,37 @@ declare class WorkspaceDiscovery extends WorkspaceDiscovery_base {
7512
7571
  }
7513
7572
  //#endregion
7514
7573
  //#region src/ConfigDependencyHooks.d.ts
7574
+ /**
7575
+ * pnpm's `peerDependencyRules` block — the suppression policy pnpm applies
7576
+ * **after** computing peer violations, in pnpm's own shape.
7577
+ *
7578
+ * @remarks
7579
+ * The shape is pnpm's rather than ours because that is what comes back off the
7580
+ * threaded config: measured against `@savvy-web/pnpm-plugin-silk@0.27.0`, a
7581
+ * replayed hook returns `{ allowedVersions, ignoreMissing, allowAny }` intact,
7582
+ * needing no reshaping.
7583
+ *
7584
+ * Two keys are **carried but not yet consumed**. `ignoreMissing` and
7585
+ * `allowAny` are separate suppression axes that have not been measured, and an
7586
+ * unmeasured suppression is precisely what produced the false positives this
7587
+ * seam exists to remove — so they travel through the seam and no kit code acts
7588
+ * on them. Only `allowedVersions` is consumed today.
7589
+ *
7590
+ * `allowedVersions` keys come in two spellings in the wild, and both must be
7591
+ * handled: parent-versioned (`"@effect/ai-anthropic@4.0.0-rc.109>effect"`, as
7592
+ * `pnpm:export` materializes them into `pnpm-workspace.yaml`) and unversioned
7593
+ * (`"@effect/vitest>vitest"`, as a config-dependency plugin injects them).
7594
+ *
7595
+ * @public
7596
+ */
7597
+ interface PeerDependencyRules {
7598
+ /** `parent>peer` → the peer version or range the rule permits. */
7599
+ readonly allowedVersions: Readonly<Record<string, string>>;
7600
+ /** Peer names whose absence pnpm does not report. Carried, not consumed. */
7601
+ readonly ignoreMissing: ReadonlyArray<string>;
7602
+ /** Peer names for which any version is accepted. Carried, not consumed. */
7603
+ readonly allowAny: ReadonlyArray<string>;
7604
+ }
7515
7605
  /**
7516
7606
  * The result of replaying a workspace's `configDependencies` hooks: the catalogs
7517
7607
  * the hooks yield, and the release-age gate contribution they leave on the
@@ -7531,6 +7621,24 @@ interface HookInjection {
7531
7621
  readonly catalogs: Readonly<Record<string, Readonly<Record<string, string>>>>;
7532
7622
  /** The release-age gate contribution the replayed hooks leave on the config. */
7533
7623
  readonly releaseAge: PartialReleaseAgeGate;
7624
+ /**
7625
+ * The **effective** peer-dependency rules: the seeded workspace-file rules
7626
+ * with every replayed hook's contribution threaded over them.
7627
+ *
7628
+ * @remarks
7629
+ * Effective rather than hook-only because the rules are **seeded** into the
7630
+ * threaded config and the hooks merge onto them, exactly as pnpm seeds its
7631
+ * own config and takes back what the hooks return. That is deliberate: a
7632
+ * kit-owned merge function would be a second implementation of a rule this
7633
+ * seam already enforces, and the two would drift the first time pnpm changed
7634
+ * its threading.
7635
+ *
7636
+ * Measured caveat, and **not a bug to fix**: this repo's plugin *merges*
7637
+ * onto the seeded rules; another plugin could overwrite them. Under seeding
7638
+ * that is pnpm's own behaviour reproduced — a hook that overwrites
7639
+ * overwrites for pnpm too — so do not "repair" it into a merger.
7640
+ */
7641
+ readonly peerDependencyRules: PeerDependencyRules;
7534
7642
  }
7535
7643
  /**
7536
7644
  * The {@link ConfigDependencyHooks} service shape.
@@ -7568,8 +7676,12 @@ interface ConfigDependencyHooksShape {
7568
7676
  * @param configDependencies - The `configDependencies` map (name →
7569
7677
  * version+integrity) declared in `pnpm-workspace.yaml`.
7570
7678
  * @param seed - The inline catalogs, as `catalog name → dependency → range`.
7679
+ * @param rules - The workspace file's `peerDependencyRules`, seeded into the
7680
+ * threaded config so hooks merge onto them rather than replacing them.
7681
+ * Omitted means "the workspace file declares none", which is different
7682
+ * from "nobody looked" — the caller owns that distinction.
7571
7683
  */
7572
- readonly inject: (root: string, configDependencies: Readonly<Record<string, string>>, seed: Readonly<Record<string, Readonly<Record<string, string>>>>) => Effect.Effect<HookInjection, CatalogAssemblyError>;
7684
+ readonly inject: (root: string, configDependencies: Readonly<Record<string, string>>, seed: Readonly<Record<string, Readonly<Record<string, string>>>>, rules?: PeerDependencyRules) => Effect.Effect<HookInjection, CatalogAssemblyError>;
7573
7685
  }
7574
7686
  declare const ConfigDependencyHooks_base: Context.ServiceClass<ConfigDependencyHooks, "@effected/workspaces/ConfigDependencyHooks", ConfigDependencyHooksShape>;
7575
7687
  /**
@@ -8048,7 +8160,16 @@ declare class PublishTarget extends PublishTarget_base {}
8048
8160
  * @public
8049
8161
  */
8050
8162
  interface PublishabilityDetectorShape {
8051
- /** The publish targets for a package; empty means it does not publish. */
8163
+ /**
8164
+ * The publish targets for a package; empty means it does not publish.
8165
+ *
8166
+ * @remarks
8167
+ * `VersioningStrategy.detect` probes a whole workspace by invoking this
8168
+ * concurrently — up to ten packages in flight at once, in no guaranteed
8169
+ * order. An overriding implementation backed by shared mutable state or a
8170
+ * rate-limited client must tolerate that interleaving itself; the caller
8171
+ * does not serialize on its behalf.
8172
+ */
8052
8173
  readonly detect: (pkg: WorkspacePackage) => Effect.Effect<ReadonlyArray<PublishTarget>>;
8053
8174
  }
8054
8175
  declare const PublishabilityDetector_base: Context.ServiceClass<PublishabilityDetector, "@effected/workspaces/PublishabilityDetector", PublishabilityDetectorShape>;
@@ -8333,6 +8454,26 @@ interface WorkspaceCatalogsShape {
8333
8454
  * workspace) has no release-age keys, so the gate is the inert zero gate.
8334
8455
  */
8335
8456
  readonly releaseAgeGate: () => Effect.Effect<ReleaseAgeGate, CatalogAssemblyFailure>;
8457
+ /**
8458
+ * The workspace's **effective** `peerDependencyRules` — pnpm's post-hoc
8459
+ * suppression policy, which the lockfile does not record at all.
8460
+ *
8461
+ * @remarks
8462
+ * Assembled from the same single read and hook replay as `set`, and memoized
8463
+ * with it. The `pnpm-workspace.yaml` block (what `pnpm:export` materializes)
8464
+ * is **seeded** into the replayed config and the config-dependency hooks
8465
+ * merge onto it, so one object carries both sources — the kit never merges
8466
+ * them itself, because that would be a second implementation of a rule the
8467
+ * hook seam already enforces.
8468
+ *
8469
+ * A consumer needs these to avoid **reporting** what pnpm suppresses: pnpm
8470
+ * computes the same peer violations and then hides the ones a rule allows,
8471
+ * so a checker without them reports findings pnpm calls clean.
8472
+ *
8473
+ * `ignoreMissing` and `allowAny` are carried but unmeasured — no kit code
8474
+ * acts on them today.
8475
+ */
8476
+ readonly peerDependencyRules: () => Effect.Effect<PeerDependencyRules, CatalogAssemblyFailure>;
8336
8477
  /**
8337
8478
  * Each importer's dependency-name → resolved-version map, as the manager's
8338
8479
  * lockfile records it. Read from the same single lockfile read as `set`, and