@fern-api/replay 0.15.1 → 0.16.0
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/cli.cjs +92 -189
- package/dist/cli.cjs.map +1 -1
- package/dist/index.cjs +92 -189
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -47
- package/dist/index.d.ts +25 -47
- package/dist/index.js +92 -189
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -12,8 +12,6 @@ interface GenerationRecord {
|
|
|
12
12
|
timestamp: string;
|
|
13
13
|
cli_version: string;
|
|
14
14
|
generator_versions: Record<string, string>;
|
|
15
|
-
/** SHA of the base branch HEAD before replay ran. Always on main's lineage. */
|
|
16
|
-
base_branch_head?: string;
|
|
17
15
|
}
|
|
18
16
|
interface StoredPatch {
|
|
19
17
|
id: string;
|
|
@@ -259,22 +257,24 @@ declare class ReplayDetector {
|
|
|
259
257
|
private sdkOutputDir;
|
|
260
258
|
readonly warnings: string[];
|
|
261
259
|
constructor(git: GitClient, lockManager: LockfileManager, sdkOutputDir: string);
|
|
262
|
-
detectNewPatches(): Promise<DetectionResult>;
|
|
263
260
|
/**
|
|
264
|
-
*
|
|
261
|
+
* Derive the previous-generation SHA from git history instead of trusting
|
|
262
|
+
* `lock.current_generation`.
|
|
263
|
+
*
|
|
264
|
+
* Walks `git log HEAD --first-parent` and returns the SHA of the most recent
|
|
265
|
+
* commit that `isGenerationBoundary` classifies as a customization-baseline
|
|
266
|
+
* boundary, or null if no such commit is reachable from HEAD on the mainline.
|
|
265
267
|
*
|
|
266
|
-
*
|
|
267
|
-
* `[fern-
|
|
268
|
-
*
|
|
269
|
-
*
|
|
270
|
-
*
|
|
271
|
-
* the bug class where pipeline-driven changes (autoversion, replay,
|
|
272
|
-
* generation) get bundled as customer customizations.
|
|
268
|
+
* `isGenerationBoundary` is intentionally narrower than `isGenerationCommit`:
|
|
269
|
+
* it excludes `[fern-autoversion]` (lightweight bumps that don't reset the
|
|
270
|
+
* baseline) and the GitHub merge-commit subject for fern-bot regen PRs
|
|
271
|
+
* (which sits on first-parent but where the customer fix-up commits live
|
|
272
|
+
* on second-parent — stopping at the merge would hide them).
|
|
273
273
|
*
|
|
274
|
-
*
|
|
275
|
-
* (truly disjoint history — orphan branches with no shared root).
|
|
274
|
+
* See docs/adr/0001-derived-scan-boundary.md.
|
|
276
275
|
*/
|
|
277
|
-
|
|
276
|
+
findPreviousGenerationFromHistory(): Promise<string | null>;
|
|
277
|
+
detectNewPatches(): Promise<DetectionResult>;
|
|
278
278
|
/**
|
|
279
279
|
* Walk `${rangeStart}..HEAD`, classify each commit, emit one
|
|
280
280
|
* `StoredPatch` per customer commit. Body shared by the linear path
|
|
@@ -308,9 +308,7 @@ declare class ReplayDetector {
|
|
|
308
308
|
* within the current linear detection window, and are absent from
|
|
309
309
|
* HEAD at the end of the window.
|
|
310
310
|
*
|
|
311
|
-
* Rationale:
|
|
312
|
-
* firstParent..mergeCommit so net-zero files never enter the composite. On
|
|
313
|
-
* linear history each commit becomes its own patch, so a file that was
|
|
311
|
+
* Rationale: each commit becomes its own patch, so a file that was
|
|
314
312
|
* briefly added and later removed survives as a create+delete pair whose
|
|
315
313
|
* cumulative diff is empty. We drop such patches before they reach the
|
|
316
314
|
* lockfile.
|
|
@@ -341,13 +339,6 @@ declare class ReplayDetector {
|
|
|
341
339
|
* more aggressively. On typical SDK repos this is a single sub-10ms call.
|
|
342
340
|
*/
|
|
343
341
|
private listHeadFiles;
|
|
344
|
-
/**
|
|
345
|
-
* Create a single composite patch for a merge commit by diffing the merge
|
|
346
|
-
* commit against its first parent. This captures the net change of the
|
|
347
|
-
* entire merged branch as one patch, eliminating accumulator chaining and
|
|
348
|
-
* zero-net-change ghost conflicts.
|
|
349
|
-
*/
|
|
350
|
-
private createMergeCompositePatch;
|
|
351
342
|
/**
|
|
352
343
|
* Detect patches via tree diff for non-linear history. Returns a composite patch.
|
|
353
344
|
* Revert reconciliation is skipped here because tree-diff produces a single composite
|
|
@@ -377,6 +368,13 @@ declare class ReplayDetector {
|
|
|
377
368
|
private resolveDiffBase;
|
|
378
369
|
private parseGitLog;
|
|
379
370
|
private getLastGeneration;
|
|
371
|
+
/**
|
|
372
|
+
* Build a transient `GenerationRecord` from a SHA derived by walking git
|
|
373
|
+
* history. Only `commit_sha` (and `tree_hash` when needed downstream) is
|
|
374
|
+
* load-bearing here; the rest are filled with defensible placeholders.
|
|
375
|
+
* This record is consumed by `detectPatchesInRange` and is never persisted.
|
|
376
|
+
*/
|
|
377
|
+
private synthesizeGenerationRecord;
|
|
380
378
|
}
|
|
381
379
|
|
|
382
380
|
/**
|
|
@@ -477,7 +475,6 @@ declare class ReplayApplicator {
|
|
|
477
475
|
interface CommitOptions {
|
|
478
476
|
cliVersion: string;
|
|
479
477
|
generatorVersions: Record<string, string>;
|
|
480
|
-
baseBranchHead?: string;
|
|
481
478
|
}
|
|
482
479
|
declare class ReplayCommitter {
|
|
483
480
|
private git;
|
|
@@ -596,12 +593,10 @@ interface ReplayOptions {
|
|
|
596
593
|
generatorVersions?: Record<string, string>;
|
|
597
594
|
/** Commit generation + update lockfile, skip detection/application */
|
|
598
595
|
skipApplication?: boolean;
|
|
599
|
-
/** SHA of the base branch HEAD before replay runs. Stored in lockfile for squash merge recovery. */
|
|
600
|
-
baseBranchHead?: string;
|
|
601
596
|
}
|
|
602
597
|
/**
|
|
603
598
|
* Options honored by `applyPreparedReplay()`. `cliVersion`, `generatorVersions`,
|
|
604
|
-
* `
|
|
599
|
+
* `dryRun`, and `skipApplication` were all captured in phase 1
|
|
605
600
|
* and re-supplying them here is meaningless.
|
|
606
601
|
*/
|
|
607
602
|
interface ApplyOptions {
|
|
@@ -621,8 +616,8 @@ interface ApplyOptions {
|
|
|
621
616
|
* respected. `rebasePatches` uses `currentGenerationSha` (the pure `[fern-generated]`
|
|
622
617
|
* SHA), NOT HEAD — mid-phase commits do not retarget patches' `base_generation`.
|
|
623
618
|
* - The service instance is single-use across the phase boundary: do not call
|
|
624
|
-
*
|
|
625
|
-
*
|
|
619
|
+
* another `prepareReplay()` between phases. In-memory lockfile and warning
|
|
620
|
+
* state would be corrupted.
|
|
626
621
|
* - If the caller's mid-phase work throws or `applyPreparedReplay` is never called,
|
|
627
622
|
* the repo is left with the new `[fern-generated]` commit but a stale lockfile.
|
|
628
623
|
* Consumers MUST either (a) still call `applyPreparedReplay` so the lockfile
|
|
@@ -637,8 +632,6 @@ interface ReplayPreparation {
|
|
|
637
632
|
previousGenerationSha: string | null;
|
|
638
633
|
/** SHA of the new [fern-generated] commit created by prepareReplay (or HEAD for dry-run terminals) */
|
|
639
634
|
currentGenerationSha: string;
|
|
640
|
-
/** options.baseBranchHead passed through */
|
|
641
|
-
baseBranchHead: string | null;
|
|
642
635
|
/** @internal Opaque state consumed by applyPreparedReplay */
|
|
643
636
|
readonly _prepared: InternalPreparationState;
|
|
644
637
|
}
|
|
@@ -758,21 +751,6 @@ declare class ReplayService {
|
|
|
758
751
|
* Behavior is byte-identical to the pre-split implementation for all existing callers.
|
|
759
752
|
*/
|
|
760
753
|
runReplay(options?: ReplayOptions): Promise<ReplayReport>;
|
|
761
|
-
/**
|
|
762
|
-
* Sync the lockfile after a divergent PR was squash-merged.
|
|
763
|
-
* Call this BEFORE runReplay() when the CLI detects a merged divergent PR.
|
|
764
|
-
*
|
|
765
|
-
* After updating the generation record, re-detects customer patches via
|
|
766
|
-
* tree diff between the generation tag (pure generation tree) and HEAD
|
|
767
|
-
* (which includes customer customizations after squash merge). This ensures
|
|
768
|
-
* patches survive the squash merge → regenerate cycle even when the lockfile
|
|
769
|
-
* was restored from the base branch during conflict PR creation.
|
|
770
|
-
*/
|
|
771
|
-
syncFromDivergentMerge(generationCommitSha: string, options?: {
|
|
772
|
-
cliVersion?: string;
|
|
773
|
-
generatorVersions?: Record<string, string>;
|
|
774
|
-
baseBranchHead?: string;
|
|
775
|
-
}): Promise<void>;
|
|
776
754
|
private determineFlow;
|
|
777
755
|
/**
|
|
778
756
|
* Rebase cleanly applied patches so they are relative to the current generation.
|
package/dist/index.d.ts
CHANGED
|
@@ -12,8 +12,6 @@ interface GenerationRecord {
|
|
|
12
12
|
timestamp: string;
|
|
13
13
|
cli_version: string;
|
|
14
14
|
generator_versions: Record<string, string>;
|
|
15
|
-
/** SHA of the base branch HEAD before replay ran. Always on main's lineage. */
|
|
16
|
-
base_branch_head?: string;
|
|
17
15
|
}
|
|
18
16
|
interface StoredPatch {
|
|
19
17
|
id: string;
|
|
@@ -259,22 +257,24 @@ declare class ReplayDetector {
|
|
|
259
257
|
private sdkOutputDir;
|
|
260
258
|
readonly warnings: string[];
|
|
261
259
|
constructor(git: GitClient, lockManager: LockfileManager, sdkOutputDir: string);
|
|
262
|
-
detectNewPatches(): Promise<DetectionResult>;
|
|
263
260
|
/**
|
|
264
|
-
*
|
|
261
|
+
* Derive the previous-generation SHA from git history instead of trusting
|
|
262
|
+
* `lock.current_generation`.
|
|
263
|
+
*
|
|
264
|
+
* Walks `git log HEAD --first-parent` and returns the SHA of the most recent
|
|
265
|
+
* commit that `isGenerationBoundary` classifies as a customization-baseline
|
|
266
|
+
* boundary, or null if no such commit is reachable from HEAD on the mainline.
|
|
265
267
|
*
|
|
266
|
-
*
|
|
267
|
-
* `[fern-
|
|
268
|
-
*
|
|
269
|
-
*
|
|
270
|
-
*
|
|
271
|
-
* the bug class where pipeline-driven changes (autoversion, replay,
|
|
272
|
-
* generation) get bundled as customer customizations.
|
|
268
|
+
* `isGenerationBoundary` is intentionally narrower than `isGenerationCommit`:
|
|
269
|
+
* it excludes `[fern-autoversion]` (lightweight bumps that don't reset the
|
|
270
|
+
* baseline) and the GitHub merge-commit subject for fern-bot regen PRs
|
|
271
|
+
* (which sits on first-parent but where the customer fix-up commits live
|
|
272
|
+
* on second-parent — stopping at the merge would hide them).
|
|
273
273
|
*
|
|
274
|
-
*
|
|
275
|
-
* (truly disjoint history — orphan branches with no shared root).
|
|
274
|
+
* See docs/adr/0001-derived-scan-boundary.md.
|
|
276
275
|
*/
|
|
277
|
-
|
|
276
|
+
findPreviousGenerationFromHistory(): Promise<string | null>;
|
|
277
|
+
detectNewPatches(): Promise<DetectionResult>;
|
|
278
278
|
/**
|
|
279
279
|
* Walk `${rangeStart}..HEAD`, classify each commit, emit one
|
|
280
280
|
* `StoredPatch` per customer commit. Body shared by the linear path
|
|
@@ -308,9 +308,7 @@ declare class ReplayDetector {
|
|
|
308
308
|
* within the current linear detection window, and are absent from
|
|
309
309
|
* HEAD at the end of the window.
|
|
310
310
|
*
|
|
311
|
-
* Rationale:
|
|
312
|
-
* firstParent..mergeCommit so net-zero files never enter the composite. On
|
|
313
|
-
* linear history each commit becomes its own patch, so a file that was
|
|
311
|
+
* Rationale: each commit becomes its own patch, so a file that was
|
|
314
312
|
* briefly added and later removed survives as a create+delete pair whose
|
|
315
313
|
* cumulative diff is empty. We drop such patches before they reach the
|
|
316
314
|
* lockfile.
|
|
@@ -341,13 +339,6 @@ declare class ReplayDetector {
|
|
|
341
339
|
* more aggressively. On typical SDK repos this is a single sub-10ms call.
|
|
342
340
|
*/
|
|
343
341
|
private listHeadFiles;
|
|
344
|
-
/**
|
|
345
|
-
* Create a single composite patch for a merge commit by diffing the merge
|
|
346
|
-
* commit against its first parent. This captures the net change of the
|
|
347
|
-
* entire merged branch as one patch, eliminating accumulator chaining and
|
|
348
|
-
* zero-net-change ghost conflicts.
|
|
349
|
-
*/
|
|
350
|
-
private createMergeCompositePatch;
|
|
351
342
|
/**
|
|
352
343
|
* Detect patches via tree diff for non-linear history. Returns a composite patch.
|
|
353
344
|
* Revert reconciliation is skipped here because tree-diff produces a single composite
|
|
@@ -377,6 +368,13 @@ declare class ReplayDetector {
|
|
|
377
368
|
private resolveDiffBase;
|
|
378
369
|
private parseGitLog;
|
|
379
370
|
private getLastGeneration;
|
|
371
|
+
/**
|
|
372
|
+
* Build a transient `GenerationRecord` from a SHA derived by walking git
|
|
373
|
+
* history. Only `commit_sha` (and `tree_hash` when needed downstream) is
|
|
374
|
+
* load-bearing here; the rest are filled with defensible placeholders.
|
|
375
|
+
* This record is consumed by `detectPatchesInRange` and is never persisted.
|
|
376
|
+
*/
|
|
377
|
+
private synthesizeGenerationRecord;
|
|
380
378
|
}
|
|
381
379
|
|
|
382
380
|
/**
|
|
@@ -477,7 +475,6 @@ declare class ReplayApplicator {
|
|
|
477
475
|
interface CommitOptions {
|
|
478
476
|
cliVersion: string;
|
|
479
477
|
generatorVersions: Record<string, string>;
|
|
480
|
-
baseBranchHead?: string;
|
|
481
478
|
}
|
|
482
479
|
declare class ReplayCommitter {
|
|
483
480
|
private git;
|
|
@@ -596,12 +593,10 @@ interface ReplayOptions {
|
|
|
596
593
|
generatorVersions?: Record<string, string>;
|
|
597
594
|
/** Commit generation + update lockfile, skip detection/application */
|
|
598
595
|
skipApplication?: boolean;
|
|
599
|
-
/** SHA of the base branch HEAD before replay runs. Stored in lockfile for squash merge recovery. */
|
|
600
|
-
baseBranchHead?: string;
|
|
601
596
|
}
|
|
602
597
|
/**
|
|
603
598
|
* Options honored by `applyPreparedReplay()`. `cliVersion`, `generatorVersions`,
|
|
604
|
-
* `
|
|
599
|
+
* `dryRun`, and `skipApplication` were all captured in phase 1
|
|
605
600
|
* and re-supplying them here is meaningless.
|
|
606
601
|
*/
|
|
607
602
|
interface ApplyOptions {
|
|
@@ -621,8 +616,8 @@ interface ApplyOptions {
|
|
|
621
616
|
* respected. `rebasePatches` uses `currentGenerationSha` (the pure `[fern-generated]`
|
|
622
617
|
* SHA), NOT HEAD — mid-phase commits do not retarget patches' `base_generation`.
|
|
623
618
|
* - The service instance is single-use across the phase boundary: do not call
|
|
624
|
-
*
|
|
625
|
-
*
|
|
619
|
+
* another `prepareReplay()` between phases. In-memory lockfile and warning
|
|
620
|
+
* state would be corrupted.
|
|
626
621
|
* - If the caller's mid-phase work throws or `applyPreparedReplay` is never called,
|
|
627
622
|
* the repo is left with the new `[fern-generated]` commit but a stale lockfile.
|
|
628
623
|
* Consumers MUST either (a) still call `applyPreparedReplay` so the lockfile
|
|
@@ -637,8 +632,6 @@ interface ReplayPreparation {
|
|
|
637
632
|
previousGenerationSha: string | null;
|
|
638
633
|
/** SHA of the new [fern-generated] commit created by prepareReplay (or HEAD for dry-run terminals) */
|
|
639
634
|
currentGenerationSha: string;
|
|
640
|
-
/** options.baseBranchHead passed through */
|
|
641
|
-
baseBranchHead: string | null;
|
|
642
635
|
/** @internal Opaque state consumed by applyPreparedReplay */
|
|
643
636
|
readonly _prepared: InternalPreparationState;
|
|
644
637
|
}
|
|
@@ -758,21 +751,6 @@ declare class ReplayService {
|
|
|
758
751
|
* Behavior is byte-identical to the pre-split implementation for all existing callers.
|
|
759
752
|
*/
|
|
760
753
|
runReplay(options?: ReplayOptions): Promise<ReplayReport>;
|
|
761
|
-
/**
|
|
762
|
-
* Sync the lockfile after a divergent PR was squash-merged.
|
|
763
|
-
* Call this BEFORE runReplay() when the CLI detects a merged divergent PR.
|
|
764
|
-
*
|
|
765
|
-
* After updating the generation record, re-detects customer patches via
|
|
766
|
-
* tree diff between the generation tag (pure generation tree) and HEAD
|
|
767
|
-
* (which includes customer customizations after squash merge). This ensures
|
|
768
|
-
* patches survive the squash merge → regenerate cycle even when the lockfile
|
|
769
|
-
* was restored from the base branch during conflict PR creation.
|
|
770
|
-
*/
|
|
771
|
-
syncFromDivergentMerge(generationCommitSha: string, options?: {
|
|
772
|
-
cliVersion?: string;
|
|
773
|
-
generatorVersions?: Record<string, string>;
|
|
774
|
-
baseBranchHead?: string;
|
|
775
|
-
}): Promise<void>;
|
|
776
754
|
private determineFlow;
|
|
777
755
|
/**
|
|
778
756
|
* Rebase cleanly applied patches so they are relative to the current generation.
|