@savvy-web/silk 3.2.6 → 3.2.8

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.
@@ -65584,7 +65584,7 @@ function makeShape(inspector, fs) {
65584
65584
  reason: errMsg(e)
65585
65585
  })
65586
65586
  });
65587
- const preview = (root) => previewEffect(root, fs);
65587
+ const preview = (root, options) => previewEffect(root, options?.changelogModules, fs);
65588
65588
  const apply = (root, options) => applyEffect(root, options?.dryRun ?? false, options?.changelogModules, inspector, fs);
65589
65589
  return {
65590
65590
  plan,
@@ -65613,6 +65613,44 @@ function makeReleasePlannerTest(fixed) {
65613
65613
  apply: () => fixed.apply ? effect.Effect.succeed(fixed.apply) : fail("apply")
65614
65614
  });
65615
65615
  }
65616
+ /**
65617
+ * Rewrite the engine config for a caller that supplies its own changelog module
65618
+ * paths: `config.changelog[0]` becomes the mapped absolute path and the engine's
65619
+ * `format` integration is switched off.
65620
+ *
65621
+ * @remarks
65622
+ * Shared by `preview` and `apply` — both hand the result to
65623
+ * `applyReleasePlan`, and both are called from no-`node_modules` contexts where
65624
+ * neither the configured id nor a formatter can be resolved. An unmapped id
65625
+ * fails typed (naming the supported keys) rather than reaching
65626
+ * `import-meta-resolve`, which reports it as `expected to be defined`.
65627
+ *
65628
+ * Exported for tests only — not re-exported from the package index, so it is
65629
+ * not public API. Driving it directly is the only deterministic way to assert
65630
+ * the `format: false` half: every formatter the changesets config accepts
65631
+ * either shells out through `npx` (network) or to an ambient binary, so a
65632
+ * fixture that names one passes or fails on what the machine happens to have
65633
+ * installed rather than on this rewrite.
65634
+ */
65635
+ function withChangelogModules(config, changelogModules, phase) {
65636
+ const unformatted = {
65637
+ ...config,
65638
+ format: false
65639
+ };
65640
+ if (!Array.isArray(config.changelog)) return effect.Effect.succeed(unformatted);
65641
+ const configuredId = config.changelog[0];
65642
+ if (!Object.hasOwn(changelogModules, configuredId)) {
65643
+ const supported = Object.keys(changelogModules).join(", ");
65644
+ return effect.Effect.fail(new ReleasePlanError({
65645
+ phase,
65646
+ reason: `changelog id "${configuredId}" is not in changelogModules (supported: ${supported})`
65647
+ }));
65648
+ }
65649
+ return effect.Effect.succeed({
65650
+ ...unformatted,
65651
+ changelog: [changelogModules[configuredId], config.changelog[1]]
65652
+ });
65653
+ }
65616
65654
  /** Extract the `## <version>` block (down to the next H2 or EOF) from a changelog. */
65617
65655
  function extractVersionBlock(changelog, version) {
65618
65656
  const lines = changelog.split("\n");
@@ -65640,7 +65678,7 @@ function maintenanceReasons(plan, config) {
65640
65678
  * scope-managed temp directory (cleaned up automatically when the scope
65641
65679
  * closes) and reading the generated CHANGELOG blocks back.
65642
65680
  */
65643
- function previewEffect(root, fs) {
65681
+ function previewEffect(root, changelogModules, fs) {
65644
65682
  const program = effect.Effect.gen(function* () {
65645
65683
  const [plan, packages] = yield* effect.Effect.tryPromise({
65646
65684
  try: () => Promise.all([getReleasePlan(root), getPackages(root)]),
@@ -65663,6 +65701,7 @@ function previewEffect(root, fs) {
65663
65701
  });
65664
65702
  yield* effect.Effect.forEach(warnings, (w) => effect.Effect.logWarning(w));
65665
65703
  const reasonByName = maintenanceReasons(plan, config);
65704
+ const engineConfig = changelogModules ? yield* withChangelogModules(config, changelogModules, "preview") : config;
65666
65705
  const preMode = plan.preState ? plan.preState.mode : null;
65667
65706
  const changesets = plan.changesets.map((cs) => ({
65668
65707
  id: cs.id,
@@ -65715,7 +65754,7 @@ function previewEffect(root, fs) {
65715
65754
  const rootCl = (0, node_path.join)(packages.rootDir, "CHANGELOG.md");
65716
65755
  if (yield* fs.exists(rootCl)) yield* fs.copyFile(rootCl, (0, node_path.join)(tempRoot, "CHANGELOG.md"));
65717
65756
  yield* effect.Effect.tryPromise({
65718
- try: () => applyReleasePlan(plan, tempPackages, config, void 0, root),
65757
+ try: () => applyReleasePlan(plan, tempPackages, engineConfig, void 0, root),
65719
65758
  catch: (e) => new ReleasePlanError({
65720
65759
  phase: "preview",
65721
65760
  reason: errMsg(e)
@@ -65785,28 +65824,7 @@ function applyEffect(root, dryRun, changelogModules, inspector, fs) {
65785
65824
  })
65786
65825
  });
65787
65826
  yield* effect.Effect.forEach(warnings, (w) => effect.Effect.logWarning(w));
65788
- let engineConfig = config;
65789
- if (changelogModules) {
65790
- engineConfig = {
65791
- ...config,
65792
- format: false
65793
- };
65794
- if (Array.isArray(config.changelog)) {
65795
- const configuredId = config.changelog[0];
65796
- const mapped = changelogModules[configuredId];
65797
- if (mapped === void 0) {
65798
- const supported = Object.keys(changelogModules).join(", ");
65799
- return yield* effect.Effect.fail(new ReleasePlanError({
65800
- phase: "apply",
65801
- reason: `changelog id "${configuredId}" is not in changelogModules (supported: ${supported})`
65802
- }));
65803
- }
65804
- engineConfig = {
65805
- ...engineConfig,
65806
- changelog: [mapped, config.changelog[1]]
65807
- };
65808
- }
65809
- }
65827
+ const engineConfig = changelogModules ? yield* withChangelogModules(config, changelogModules, "apply") : config;
65810
65828
  const releases = plan.releases.filter((r) => r.type !== "none").map((r) => ({
65811
65829
  name: r.name,
65812
65830
  type: r.type,
@@ -11628,8 +11628,22 @@ type AppliedRelease = Schema.Schema.Type<typeof AppliedReleaseSchema>;
11628
11628
  interface ReleasePlannerShape {
11629
11629
  /** Compute the in-memory release plan (read-only). */
11630
11630
  readonly plan: (root: string) => Effect.Effect<ReleasePlan, ReleasePlanError>;
11631
- /** Render a non-destructive preview of the next release. */
11632
- readonly preview: (root: string) => Effect.Effect<ChangesetPreview, ReleasePlanError>;
11631
+ /**
11632
+ * Render a non-destructive preview of the next release.
11633
+ *
11634
+ * @remarks
11635
+ * Rendering `changelogEntry` means resolving the configured changelog module,
11636
+ * so `changelogModules` matters here for the same reason it does on `apply`.
11637
+ */
11638
+ readonly preview: (root: string, options?: {
11639
+ /**
11640
+ * Map configured changelog ids to absolute module paths. When set,
11641
+ * `config.changelog[0]` must be a key of this map (rewritten before the
11642
+ * engine call; unmapped ids fail) and the engine's `format` integration
11643
+ * is disabled — callers in no-`node_modules` contexts own formatting.
11644
+ */
11645
+ readonly changelogModules?: Readonly<Record<string, string>>;
11646
+ }) => Effect.Effect<ChangesetPreview, ReleasePlanError>;
11633
11647
  /** Natively apply the release (destructive unless `dryRun`). */
11634
11648
  readonly apply: (root: string, options?: {
11635
11649
  readonly dryRun?: boolean;
@@ -11628,8 +11628,22 @@ type AppliedRelease = Schema.Schema.Type<typeof AppliedReleaseSchema>;
11628
11628
  interface ReleasePlannerShape {
11629
11629
  /** Compute the in-memory release plan (read-only). */
11630
11630
  readonly plan: (root: string) => Effect.Effect<ReleasePlan, ReleasePlanError>;
11631
- /** Render a non-destructive preview of the next release. */
11632
- readonly preview: (root: string) => Effect.Effect<ChangesetPreview, ReleasePlanError>;
11631
+ /**
11632
+ * Render a non-destructive preview of the next release.
11633
+ *
11634
+ * @remarks
11635
+ * Rendering `changelogEntry` means resolving the configured changelog module,
11636
+ * so `changelogModules` matters here for the same reason it does on `apply`.
11637
+ */
11638
+ readonly preview: (root: string, options?: {
11639
+ /**
11640
+ * Map configured changelog ids to absolute module paths. When set,
11641
+ * `config.changelog[0]` must be a key of this map (rewritten before the
11642
+ * engine call; unmapped ids fail) and the engine's `format` integration
11643
+ * is disabled — callers in no-`node_modules` contexts own formatting.
11644
+ */
11645
+ readonly changelogModules?: Readonly<Record<string, string>>;
11646
+ }) => Effect.Effect<ChangesetPreview, ReleasePlanError>;
11633
11647
  /** Natively apply the release (destructive unless `dryRun`). */
11634
11648
  readonly apply: (root: string, options?: {
11635
11649
  readonly dryRun?: boolean;
@@ -66285,7 +66285,7 @@ function makeShape(inspector, fs) {
66285
66285
  reason: errMsg(e)
66286
66286
  })
66287
66287
  });
66288
- const preview = (root) => previewEffect(root, fs);
66288
+ const preview = (root, options) => previewEffect(root, options?.changelogModules, fs);
66289
66289
  const apply = (root, options) => applyEffect(root, options?.dryRun ?? false, options?.changelogModules, inspector, fs);
66290
66290
  return {
66291
66291
  plan,
@@ -66314,6 +66314,44 @@ function makeReleasePlannerTest(fixed) {
66314
66314
  apply: () => fixed.apply ? Effect.succeed(fixed.apply) : fail("apply")
66315
66315
  });
66316
66316
  }
66317
+ /**
66318
+ * Rewrite the engine config for a caller that supplies its own changelog module
66319
+ * paths: `config.changelog[0]` becomes the mapped absolute path and the engine's
66320
+ * `format` integration is switched off.
66321
+ *
66322
+ * @remarks
66323
+ * Shared by `preview` and `apply` — both hand the result to
66324
+ * `applyReleasePlan`, and both are called from no-`node_modules` contexts where
66325
+ * neither the configured id nor a formatter can be resolved. An unmapped id
66326
+ * fails typed (naming the supported keys) rather than reaching
66327
+ * `import-meta-resolve`, which reports it as `expected to be defined`.
66328
+ *
66329
+ * Exported for tests only — not re-exported from the package index, so it is
66330
+ * not public API. Driving it directly is the only deterministic way to assert
66331
+ * the `format: false` half: every formatter the changesets config accepts
66332
+ * either shells out through `npx` (network) or to an ambient binary, so a
66333
+ * fixture that names one passes or fails on what the machine happens to have
66334
+ * installed rather than on this rewrite.
66335
+ */
66336
+ function withChangelogModules(config, changelogModules, phase) {
66337
+ const unformatted = {
66338
+ ...config,
66339
+ format: false
66340
+ };
66341
+ if (!Array.isArray(config.changelog)) return Effect.succeed(unformatted);
66342
+ const configuredId = config.changelog[0];
66343
+ if (!Object.hasOwn(changelogModules, configuredId)) {
66344
+ const supported = Object.keys(changelogModules).join(", ");
66345
+ return Effect.fail(new ReleasePlanError({
66346
+ phase,
66347
+ reason: `changelog id "${configuredId}" is not in changelogModules (supported: ${supported})`
66348
+ }));
66349
+ }
66350
+ return Effect.succeed({
66351
+ ...unformatted,
66352
+ changelog: [changelogModules[configuredId], config.changelog[1]]
66353
+ });
66354
+ }
66317
66355
  /** Extract the `## <version>` block (down to the next H2 or EOF) from a changelog. */
66318
66356
  function extractVersionBlock(changelog, version) {
66319
66357
  const lines = changelog.split("\n");
@@ -66341,7 +66379,7 @@ function maintenanceReasons(plan, config) {
66341
66379
  * scope-managed temp directory (cleaned up automatically when the scope
66342
66380
  * closes) and reading the generated CHANGELOG blocks back.
66343
66381
  */
66344
- function previewEffect(root, fs) {
66382
+ function previewEffect(root, changelogModules, fs) {
66345
66383
  const program = Effect.gen(function* () {
66346
66384
  const [plan, packages] = yield* Effect.tryPromise({
66347
66385
  try: () => Promise.all([getReleasePlan(root), getPackages(root)]),
@@ -66364,6 +66402,7 @@ function previewEffect(root, fs) {
66364
66402
  });
66365
66403
  yield* Effect.forEach(warnings, (w) => Effect.logWarning(w));
66366
66404
  const reasonByName = maintenanceReasons(plan, config);
66405
+ const engineConfig = changelogModules ? yield* withChangelogModules(config, changelogModules, "preview") : config;
66367
66406
  const preMode = plan.preState ? plan.preState.mode : null;
66368
66407
  const changesets = plan.changesets.map((cs) => ({
66369
66408
  id: cs.id,
@@ -66416,7 +66455,7 @@ function previewEffect(root, fs) {
66416
66455
  const rootCl = join(packages.rootDir, "CHANGELOG.md");
66417
66456
  if (yield* fs.exists(rootCl)) yield* fs.copyFile(rootCl, join(tempRoot, "CHANGELOG.md"));
66418
66457
  yield* Effect.tryPromise({
66419
- try: () => applyReleasePlan(plan, tempPackages, config, void 0, root),
66458
+ try: () => applyReleasePlan(plan, tempPackages, engineConfig, void 0, root),
66420
66459
  catch: (e) => new ReleasePlanError({
66421
66460
  phase: "preview",
66422
66461
  reason: errMsg(e)
@@ -66486,28 +66525,7 @@ function applyEffect(root, dryRun, changelogModules, inspector, fs) {
66486
66525
  })
66487
66526
  });
66488
66527
  yield* Effect.forEach(warnings, (w) => Effect.logWarning(w));
66489
- let engineConfig = config;
66490
- if (changelogModules) {
66491
- engineConfig = {
66492
- ...config,
66493
- format: false
66494
- };
66495
- if (Array.isArray(config.changelog)) {
66496
- const configuredId = config.changelog[0];
66497
- const mapped = changelogModules[configuredId];
66498
- if (mapped === void 0) {
66499
- const supported = Object.keys(changelogModules).join(", ");
66500
- return yield* Effect.fail(new ReleasePlanError({
66501
- phase: "apply",
66502
- reason: `changelog id "${configuredId}" is not in changelogModules (supported: ${supported})`
66503
- }));
66504
- }
66505
- engineConfig = {
66506
- ...engineConfig,
66507
- changelog: [mapped, config.changelog[1]]
66508
- };
66509
- }
66510
- }
66528
+ const engineConfig = changelogModules ? yield* withChangelogModules(config, changelogModules, "apply") : config;
66511
66529
  const releases = plan.releases.filter((r) => r.type !== "none").map((r) => ({
66512
66530
  name: r.name,
66513
66531
  type: r.type,
@@ -65588,7 +65588,7 @@ function makeShape(inspector, fs) {
65588
65588
  reason: errMsg(e)
65589
65589
  })
65590
65590
  });
65591
- const preview = (root) => previewEffect(root, fs);
65591
+ const preview = (root, options) => previewEffect(root, options?.changelogModules, fs);
65592
65592
  const apply = (root, options) => applyEffect(root, options?.dryRun ?? false, options?.changelogModules, inspector, fs);
65593
65593
  return {
65594
65594
  plan,
@@ -65617,6 +65617,44 @@ function makeReleasePlannerTest(fixed) {
65617
65617
  apply: () => fixed.apply ? effect.Effect.succeed(fixed.apply) : fail("apply")
65618
65618
  });
65619
65619
  }
65620
+ /**
65621
+ * Rewrite the engine config for a caller that supplies its own changelog module
65622
+ * paths: `config.changelog[0]` becomes the mapped absolute path and the engine's
65623
+ * `format` integration is switched off.
65624
+ *
65625
+ * @remarks
65626
+ * Shared by `preview` and `apply` — both hand the result to
65627
+ * `applyReleasePlan`, and both are called from no-`node_modules` contexts where
65628
+ * neither the configured id nor a formatter can be resolved. An unmapped id
65629
+ * fails typed (naming the supported keys) rather than reaching
65630
+ * `import-meta-resolve`, which reports it as `expected to be defined`.
65631
+ *
65632
+ * Exported for tests only — not re-exported from the package index, so it is
65633
+ * not public API. Driving it directly is the only deterministic way to assert
65634
+ * the `format: false` half: every formatter the changesets config accepts
65635
+ * either shells out through `npx` (network) or to an ambient binary, so a
65636
+ * fixture that names one passes or fails on what the machine happens to have
65637
+ * installed rather than on this rewrite.
65638
+ */
65639
+ function withChangelogModules(config, changelogModules, phase) {
65640
+ const unformatted = {
65641
+ ...config,
65642
+ format: false
65643
+ };
65644
+ if (!Array.isArray(config.changelog)) return effect.Effect.succeed(unformatted);
65645
+ const configuredId = config.changelog[0];
65646
+ if (!Object.hasOwn(changelogModules, configuredId)) {
65647
+ const supported = Object.keys(changelogModules).join(", ");
65648
+ return effect.Effect.fail(new ReleasePlanError({
65649
+ phase,
65650
+ reason: `changelog id "${configuredId}" is not in changelogModules (supported: ${supported})`
65651
+ }));
65652
+ }
65653
+ return effect.Effect.succeed({
65654
+ ...unformatted,
65655
+ changelog: [changelogModules[configuredId], config.changelog[1]]
65656
+ });
65657
+ }
65620
65658
  /** Extract the `## <version>` block (down to the next H2 or EOF) from a changelog. */
65621
65659
  function extractVersionBlock(changelog, version) {
65622
65660
  const lines = changelog.split("\n");
@@ -65644,7 +65682,7 @@ function maintenanceReasons(plan, config) {
65644
65682
  * scope-managed temp directory (cleaned up automatically when the scope
65645
65683
  * closes) and reading the generated CHANGELOG blocks back.
65646
65684
  */
65647
- function previewEffect(root, fs) {
65685
+ function previewEffect(root, changelogModules, fs) {
65648
65686
  const program = effect.Effect.gen(function* () {
65649
65687
  const [plan, packages] = yield* effect.Effect.tryPromise({
65650
65688
  try: () => Promise.all([getReleasePlan(root), getPackages(root)]),
@@ -65667,6 +65705,7 @@ function previewEffect(root, fs) {
65667
65705
  });
65668
65706
  yield* effect.Effect.forEach(warnings, (w) => effect.Effect.logWarning(w));
65669
65707
  const reasonByName = maintenanceReasons(plan, config);
65708
+ const engineConfig = changelogModules ? yield* withChangelogModules(config, changelogModules, "preview") : config;
65670
65709
  const preMode = plan.preState ? plan.preState.mode : null;
65671
65710
  const changesets = plan.changesets.map((cs) => ({
65672
65711
  id: cs.id,
@@ -65719,7 +65758,7 @@ function previewEffect(root, fs) {
65719
65758
  const rootCl = (0, node_path.join)(packages.rootDir, "CHANGELOG.md");
65720
65759
  if (yield* fs.exists(rootCl)) yield* fs.copyFile(rootCl, (0, node_path.join)(tempRoot, "CHANGELOG.md"));
65721
65760
  yield* effect.Effect.tryPromise({
65722
- try: () => applyReleasePlan(plan, tempPackages, config, void 0, root),
65761
+ try: () => applyReleasePlan(plan, tempPackages, engineConfig, void 0, root),
65723
65762
  catch: (e) => new ReleasePlanError({
65724
65763
  phase: "preview",
65725
65764
  reason: errMsg(e)
@@ -65789,28 +65828,7 @@ function applyEffect(root, dryRun, changelogModules, inspector, fs) {
65789
65828
  })
65790
65829
  });
65791
65830
  yield* effect.Effect.forEach(warnings, (w) => effect.Effect.logWarning(w));
65792
- let engineConfig = config;
65793
- if (changelogModules) {
65794
- engineConfig = {
65795
- ...config,
65796
- format: false
65797
- };
65798
- if (Array.isArray(config.changelog)) {
65799
- const configuredId = config.changelog[0];
65800
- const mapped = changelogModules[configuredId];
65801
- if (mapped === void 0) {
65802
- const supported = Object.keys(changelogModules).join(", ");
65803
- return yield* effect.Effect.fail(new ReleasePlanError({
65804
- phase: "apply",
65805
- reason: `changelog id "${configuredId}" is not in changelogModules (supported: ${supported})`
65806
- }));
65807
- }
65808
- engineConfig = {
65809
- ...engineConfig,
65810
- changelog: [mapped, config.changelog[1]]
65811
- };
65812
- }
65813
- }
65831
+ const engineConfig = changelogModules ? yield* withChangelogModules(config, changelogModules, "apply") : config;
65814
65832
  const releases = plan.releases.filter((r) => r.type !== "none").map((r) => ({
65815
65833
  name: r.name,
65816
65834
  type: r.type,
@@ -11628,8 +11628,22 @@ type AppliedRelease = Schema.Schema.Type<typeof AppliedReleaseSchema>;
11628
11628
  interface ReleasePlannerShape {
11629
11629
  /** Compute the in-memory release plan (read-only). */
11630
11630
  readonly plan: (root: string) => Effect.Effect<ReleasePlan, ReleasePlanError>;
11631
- /** Render a non-destructive preview of the next release. */
11632
- readonly preview: (root: string) => Effect.Effect<ChangesetPreview, ReleasePlanError>;
11631
+ /**
11632
+ * Render a non-destructive preview of the next release.
11633
+ *
11634
+ * @remarks
11635
+ * Rendering `changelogEntry` means resolving the configured changelog module,
11636
+ * so `changelogModules` matters here for the same reason it does on `apply`.
11637
+ */
11638
+ readonly preview: (root: string, options?: {
11639
+ /**
11640
+ * Map configured changelog ids to absolute module paths. When set,
11641
+ * `config.changelog[0]` must be a key of this map (rewritten before the
11642
+ * engine call; unmapped ids fail) and the engine's `format` integration
11643
+ * is disabled — callers in no-`node_modules` contexts own formatting.
11644
+ */
11645
+ readonly changelogModules?: Readonly<Record<string, string>>;
11646
+ }) => Effect.Effect<ChangesetPreview, ReleasePlanError>;
11633
11647
  /** Natively apply the release (destructive unless `dryRun`). */
11634
11648
  readonly apply: (root: string, options?: {
11635
11649
  readonly dryRun?: boolean;
@@ -11628,8 +11628,22 @@ type AppliedRelease = Schema.Schema.Type<typeof AppliedReleaseSchema>;
11628
11628
  interface ReleasePlannerShape {
11629
11629
  /** Compute the in-memory release plan (read-only). */
11630
11630
  readonly plan: (root: string) => Effect.Effect<ReleasePlan, ReleasePlanError>;
11631
- /** Render a non-destructive preview of the next release. */
11632
- readonly preview: (root: string) => Effect.Effect<ChangesetPreview, ReleasePlanError>;
11631
+ /**
11632
+ * Render a non-destructive preview of the next release.
11633
+ *
11634
+ * @remarks
11635
+ * Rendering `changelogEntry` means resolving the configured changelog module,
11636
+ * so `changelogModules` matters here for the same reason it does on `apply`.
11637
+ */
11638
+ readonly preview: (root: string, options?: {
11639
+ /**
11640
+ * Map configured changelog ids to absolute module paths. When set,
11641
+ * `config.changelog[0]` must be a key of this map (rewritten before the
11642
+ * engine call; unmapped ids fail) and the engine's `format` integration
11643
+ * is disabled — callers in no-`node_modules` contexts own formatting.
11644
+ */
11645
+ readonly changelogModules?: Readonly<Record<string, string>>;
11646
+ }) => Effect.Effect<ChangesetPreview, ReleasePlanError>;
11633
11647
  /** Natively apply the release (destructive unless `dryRun`). */
11634
11648
  readonly apply: (root: string, options?: {
11635
11649
  readonly dryRun?: boolean;
@@ -66285,7 +66285,7 @@ function makeShape(inspector, fs) {
66285
66285
  reason: errMsg(e)
66286
66286
  })
66287
66287
  });
66288
- const preview = (root) => previewEffect(root, fs);
66288
+ const preview = (root, options) => previewEffect(root, options?.changelogModules, fs);
66289
66289
  const apply = (root, options) => applyEffect(root, options?.dryRun ?? false, options?.changelogModules, inspector, fs);
66290
66290
  return {
66291
66291
  plan,
@@ -66314,6 +66314,44 @@ function makeReleasePlannerTest(fixed) {
66314
66314
  apply: () => fixed.apply ? Effect.succeed(fixed.apply) : fail("apply")
66315
66315
  });
66316
66316
  }
66317
+ /**
66318
+ * Rewrite the engine config for a caller that supplies its own changelog module
66319
+ * paths: `config.changelog[0]` becomes the mapped absolute path and the engine's
66320
+ * `format` integration is switched off.
66321
+ *
66322
+ * @remarks
66323
+ * Shared by `preview` and `apply` — both hand the result to
66324
+ * `applyReleasePlan`, and both are called from no-`node_modules` contexts where
66325
+ * neither the configured id nor a formatter can be resolved. An unmapped id
66326
+ * fails typed (naming the supported keys) rather than reaching
66327
+ * `import-meta-resolve`, which reports it as `expected to be defined`.
66328
+ *
66329
+ * Exported for tests only — not re-exported from the package index, so it is
66330
+ * not public API. Driving it directly is the only deterministic way to assert
66331
+ * the `format: false` half: every formatter the changesets config accepts
66332
+ * either shells out through `npx` (network) or to an ambient binary, so a
66333
+ * fixture that names one passes or fails on what the machine happens to have
66334
+ * installed rather than on this rewrite.
66335
+ */
66336
+ function withChangelogModules(config, changelogModules, phase) {
66337
+ const unformatted = {
66338
+ ...config,
66339
+ format: false
66340
+ };
66341
+ if (!Array.isArray(config.changelog)) return Effect.succeed(unformatted);
66342
+ const configuredId = config.changelog[0];
66343
+ if (!Object.hasOwn(changelogModules, configuredId)) {
66344
+ const supported = Object.keys(changelogModules).join(", ");
66345
+ return Effect.fail(new ReleasePlanError({
66346
+ phase,
66347
+ reason: `changelog id "${configuredId}" is not in changelogModules (supported: ${supported})`
66348
+ }));
66349
+ }
66350
+ return Effect.succeed({
66351
+ ...unformatted,
66352
+ changelog: [changelogModules[configuredId], config.changelog[1]]
66353
+ });
66354
+ }
66317
66355
  /** Extract the `## <version>` block (down to the next H2 or EOF) from a changelog. */
66318
66356
  function extractVersionBlock(changelog, version) {
66319
66357
  const lines = changelog.split("\n");
@@ -66341,7 +66379,7 @@ function maintenanceReasons(plan, config) {
66341
66379
  * scope-managed temp directory (cleaned up automatically when the scope
66342
66380
  * closes) and reading the generated CHANGELOG blocks back.
66343
66381
  */
66344
- function previewEffect(root, fs) {
66382
+ function previewEffect(root, changelogModules, fs) {
66345
66383
  const program = Effect.gen(function* () {
66346
66384
  const [plan, packages] = yield* Effect.tryPromise({
66347
66385
  try: () => Promise.all([getReleasePlan(root), getPackages(root)]),
@@ -66364,6 +66402,7 @@ function previewEffect(root, fs) {
66364
66402
  });
66365
66403
  yield* Effect.forEach(warnings, (w) => Effect.logWarning(w));
66366
66404
  const reasonByName = maintenanceReasons(plan, config);
66405
+ const engineConfig = changelogModules ? yield* withChangelogModules(config, changelogModules, "preview") : config;
66367
66406
  const preMode = plan.preState ? plan.preState.mode : null;
66368
66407
  const changesets = plan.changesets.map((cs) => ({
66369
66408
  id: cs.id,
@@ -66416,7 +66455,7 @@ function previewEffect(root, fs) {
66416
66455
  const rootCl = join(packages.rootDir, "CHANGELOG.md");
66417
66456
  if (yield* fs.exists(rootCl)) yield* fs.copyFile(rootCl, join(tempRoot, "CHANGELOG.md"));
66418
66457
  yield* Effect.tryPromise({
66419
- try: () => applyReleasePlan(plan, tempPackages, config, void 0, root),
66458
+ try: () => applyReleasePlan(plan, tempPackages, engineConfig, void 0, root),
66420
66459
  catch: (e) => new ReleasePlanError({
66421
66460
  phase: "preview",
66422
66461
  reason: errMsg(e)
@@ -66486,28 +66525,7 @@ function applyEffect(root, dryRun, changelogModules, inspector, fs) {
66486
66525
  })
66487
66526
  });
66488
66527
  yield* Effect.forEach(warnings, (w) => Effect.logWarning(w));
66489
- let engineConfig = config;
66490
- if (changelogModules) {
66491
- engineConfig = {
66492
- ...config,
66493
- format: false
66494
- };
66495
- if (Array.isArray(config.changelog)) {
66496
- const configuredId = config.changelog[0];
66497
- const mapped = changelogModules[configuredId];
66498
- if (mapped === void 0) {
66499
- const supported = Object.keys(changelogModules).join(", ");
66500
- return yield* Effect.fail(new ReleasePlanError({
66501
- phase: "apply",
66502
- reason: `changelog id "${configuredId}" is not in changelogModules (supported: ${supported})`
66503
- }));
66504
- }
66505
- engineConfig = {
66506
- ...engineConfig,
66507
- changelog: [mapped, config.changelog[1]]
66508
- };
66509
- }
66510
- }
66528
+ const engineConfig = changelogModules ? yield* withChangelogModules(config, changelogModules, "apply") : config;
66511
66529
  const releases = plan.releases.filter((r) => r.type !== "none").map((r) => ({
66512
66530
  name: r.name,
66513
66531
  type: r.type,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@savvy-web/silk",
3
- "version": "3.2.6",
3
+ "version": "3.2.8",
4
4
  "private": false,
5
5
  "description": "The single Silk Suite dev-tooling package — changeset, commitlint, lint, and biome conventions",
6
6
  "homepage": "https://github.com/savvy-web/systems/tree/main/packages/silk",
@@ -76,9 +76,9 @@
76
76
  "dependencies": {
77
77
  "@effected/templates": "^0.1.0",
78
78
  "@savvy-web/changelog": "0.1.1",
79
- "@savvy-web/cli": "2.1.10",
80
- "@savvy-web/mcp": "2.0.11",
81
- "@savvy-web/silk-effects": "5.0.1",
79
+ "@savvy-web/cli": "2.1.12",
80
+ "@savvy-web/mcp": "2.0.13",
81
+ "@savvy-web/silk-effects": "5.1.1",
82
82
  "effect": "4.0.0-beta.101",
83
83
  "semver": "^7.8.5"
84
84
  },