@fern-api/replay 0.19.1 → 0.19.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.
package/dist/index.d.cts CHANGED
@@ -884,6 +884,31 @@ declare class ReplayService {
884
884
  */
885
885
  getLastResults(): ReadonlyArray<ReplayResult>;
886
886
  constructor(outputDir: string, _config: ReplayConfig);
887
+ /**
888
+ * Resolve the previous-generation SHA to export on
889
+ * `ReplayPreparation.previousGenerationSha`.
890
+ *
891
+ * `current_generation` is the SHA of a LOCALLY-created `[fern-generated]` commit.
892
+ * generator-cli's signed-commit push (`pushSignedCommit`) recreates that commit under a
893
+ * new remote SHA, and a squash-merge collapses it away, so the recorded value can be
894
+ * unreachable in a later clone (org "Natural": autoVersion then diffed against a phantom
895
+ * baseline and silently reported NO_CHANGE — or, pre-a38bbc6, shipped
896
+ * `0.0.0-fern-placeholder`). Consumers (generator-cli's autoVersion) diff against this
897
+ * baseline, so it MUST resolve to a real commit.
898
+ *
899
+ * Prefer the recorded SHA while it still resolves — the healthy case, and the pristine
900
+ * prior `[fern-generated]` tree. Otherwise re-anchor on the most recent reachable
901
+ * generation boundary in first-parent history: the SAME value the detector already
902
+ * derives for its own scan boundary (`findPreviousGenerationFromHistory`, whose
903
+ * `isGenerationBoundary` matches squash-merge subjects like `SDK Generation (#N)`). Fall
904
+ * back to the recorded SHA only when no boundary is reachable at all — no worse than the
905
+ * prior behavior. ADR 0002 (generator-cli) allows replay to expose this reconciled value;
906
+ * the consumer stays independently resilient.
907
+ *
908
+ * MUST be called before the new `[fern-generated]` commit is created, while HEAD is still
909
+ * the pre-generation (customer) state, so the walk anchors on the PREVIOUS generation.
910
+ */
911
+ resolveReachablePreviousGeneration(recordedSha: string | null): Promise<string | null>;
887
912
  /**
888
913
  * Phase 1 of the two-phase replay flow. Runs preGenerationRebase (when applicable),
889
914
  * detects new patches, and creates the `[fern-generated]` commit. Leaves HEAD at
package/dist/index.d.ts CHANGED
@@ -884,6 +884,31 @@ declare class ReplayService {
884
884
  */
885
885
  getLastResults(): ReadonlyArray<ReplayResult>;
886
886
  constructor(outputDir: string, _config: ReplayConfig);
887
+ /**
888
+ * Resolve the previous-generation SHA to export on
889
+ * `ReplayPreparation.previousGenerationSha`.
890
+ *
891
+ * `current_generation` is the SHA of a LOCALLY-created `[fern-generated]` commit.
892
+ * generator-cli's signed-commit push (`pushSignedCommit`) recreates that commit under a
893
+ * new remote SHA, and a squash-merge collapses it away, so the recorded value can be
894
+ * unreachable in a later clone (org "Natural": autoVersion then diffed against a phantom
895
+ * baseline and silently reported NO_CHANGE — or, pre-a38bbc6, shipped
896
+ * `0.0.0-fern-placeholder`). Consumers (generator-cli's autoVersion) diff against this
897
+ * baseline, so it MUST resolve to a real commit.
898
+ *
899
+ * Prefer the recorded SHA while it still resolves — the healthy case, and the pristine
900
+ * prior `[fern-generated]` tree. Otherwise re-anchor on the most recent reachable
901
+ * generation boundary in first-parent history: the SAME value the detector already
902
+ * derives for its own scan boundary (`findPreviousGenerationFromHistory`, whose
903
+ * `isGenerationBoundary` matches squash-merge subjects like `SDK Generation (#N)`). Fall
904
+ * back to the recorded SHA only when no boundary is reachable at all — no worse than the
905
+ * prior behavior. ADR 0002 (generator-cli) allows replay to expose this reconciled value;
906
+ * the consumer stays independently resilient.
907
+ *
908
+ * MUST be called before the new `[fern-generated]` commit is created, while HEAD is still
909
+ * the pre-generation (customer) state, so the walk anchors on the PREVIOUS generation.
910
+ */
911
+ resolveReachablePreviousGeneration(recordedSha: string | null): Promise<string | null>;
887
912
  /**
888
913
  * Phase 1 of the two-phase replay flow. Runs preGenerationRebase (when applicable),
889
914
  * detects new patches, and creates the `[fern-generated]` commit. Leaves HEAD at
package/dist/index.js CHANGED
@@ -3245,7 +3245,9 @@ var NoPatchesFlow = class {
3245
3245
  }
3246
3246
  async prepare(options) {
3247
3247
  const preLock = this.service.lockManager.read();
3248
- const previousGenerationSha = preLock.current_generation ?? null;
3248
+ const previousGenerationSha = await this.service.resolveReachablePreviousGeneration(
3249
+ preLock.current_generation ?? null
3250
+ );
3249
3251
  let { patches: newPatches, revertedPatchIds } = await this.service.detector.detectNewPatches();
3250
3252
  const detectorWarnings = [...this.service.detector.warnings];
3251
3253
  const detectorDegraded = [...this.service.detector.degradedReasons];
@@ -3383,7 +3385,9 @@ var NormalRegenerationFlow = class {
3383
3385
  }
3384
3386
  async prepare(options) {
3385
3387
  const preLock = this.service.lockManager.read();
3386
- const previousGenerationSha = preLock.current_generation ?? null;
3388
+ const previousGenerationSha = await this.service.resolveReachablePreviousGeneration(
3389
+ preLock.current_generation ?? null
3390
+ );
3387
3391
  if (options?.dryRun) {
3388
3392
  const existingPatches2 = this.service.lockManager.getPatches();
3389
3393
  const { patches: newPatches2, revertedPatchIds: dryRunReverted } = await this.service.detector.detectNewPatches();
@@ -3621,6 +3625,37 @@ var ReplayService = class {
3621
3625
  this.committer = new ReplayCommitter(git, outputDir);
3622
3626
  this.fileOwnership = new FileOwnership(git);
3623
3627
  }
3628
+ /**
3629
+ * Resolve the previous-generation SHA to export on
3630
+ * `ReplayPreparation.previousGenerationSha`.
3631
+ *
3632
+ * `current_generation` is the SHA of a LOCALLY-created `[fern-generated]` commit.
3633
+ * generator-cli's signed-commit push (`pushSignedCommit`) recreates that commit under a
3634
+ * new remote SHA, and a squash-merge collapses it away, so the recorded value can be
3635
+ * unreachable in a later clone (org "Natural": autoVersion then diffed against a phantom
3636
+ * baseline and silently reported NO_CHANGE — or, pre-a38bbc6, shipped
3637
+ * `0.0.0-fern-placeholder`). Consumers (generator-cli's autoVersion) diff against this
3638
+ * baseline, so it MUST resolve to a real commit.
3639
+ *
3640
+ * Prefer the recorded SHA while it still resolves — the healthy case, and the pristine
3641
+ * prior `[fern-generated]` tree. Otherwise re-anchor on the most recent reachable
3642
+ * generation boundary in first-parent history: the SAME value the detector already
3643
+ * derives for its own scan boundary (`findPreviousGenerationFromHistory`, whose
3644
+ * `isGenerationBoundary` matches squash-merge subjects like `SDK Generation (#N)`). Fall
3645
+ * back to the recorded SHA only when no boundary is reachable at all — no worse than the
3646
+ * prior behavior. ADR 0002 (generator-cli) allows replay to expose this reconciled value;
3647
+ * the consumer stays independently resilient.
3648
+ *
3649
+ * MUST be called before the new `[fern-generated]` commit is created, while HEAD is still
3650
+ * the pre-generation (customer) state, so the walk anchors on the PREVIOUS generation.
3651
+ */
3652
+ async resolveReachablePreviousGeneration(recordedSha) {
3653
+ if (recordedSha != null && await this.git.commitExists(recordedSha)) {
3654
+ return recordedSha;
3655
+ }
3656
+ const derived = await this.detector.findPreviousGenerationFromHistory();
3657
+ return derived ?? recordedSha;
3658
+ }
3624
3659
  /**
3625
3660
  * Phase 1 of the two-phase replay flow. Runs preGenerationRebase (when applicable),
3626
3661
  * detects new patches, and creates the `[fern-generated]` commit. Leaves HEAD at