@fern-api/replay 0.5.0 → 0.6.1

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.
Files changed (78) hide show
  1. package/dist/cli.cjs +16642 -0
  2. package/dist/cli.cjs.map +1 -0
  3. package/dist/index.cjs +2014 -0
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.d.cts +463 -0
  6. package/dist/index.d.ts +463 -12
  7. package/dist/index.js +1968 -10
  8. package/dist/index.js.map +1 -1
  9. package/package.json +16 -6
  10. package/dist/FernignoreMigrator.d.ts +0 -65
  11. package/dist/FernignoreMigrator.d.ts.map +0 -1
  12. package/dist/FernignoreMigrator.js +0 -237
  13. package/dist/FernignoreMigrator.js.map +0 -1
  14. package/dist/LockfileManager.d.ts +0 -31
  15. package/dist/LockfileManager.d.ts.map +0 -1
  16. package/dist/LockfileManager.js +0 -124
  17. package/dist/LockfileManager.js.map +0 -1
  18. package/dist/ReplayApplicator.d.ts +0 -62
  19. package/dist/ReplayApplicator.d.ts.map +0 -1
  20. package/dist/ReplayApplicator.js +0 -533
  21. package/dist/ReplayApplicator.js.map +0 -1
  22. package/dist/ReplayCommitter.d.ts +0 -39
  23. package/dist/ReplayCommitter.d.ts.map +0 -1
  24. package/dist/ReplayCommitter.js +0 -84
  25. package/dist/ReplayCommitter.js.map +0 -1
  26. package/dist/ReplayDetector.d.ts +0 -27
  27. package/dist/ReplayDetector.d.ts.map +0 -1
  28. package/dist/ReplayDetector.js +0 -150
  29. package/dist/ReplayDetector.js.map +0 -1
  30. package/dist/ReplayService.d.ts +0 -113
  31. package/dist/ReplayService.d.ts.map +0 -1
  32. package/dist/ReplayService.js +0 -579
  33. package/dist/ReplayService.js.map +0 -1
  34. package/dist/ThreeWayMerge.d.ts +0 -11
  35. package/dist/ThreeWayMerge.d.ts.map +0 -1
  36. package/dist/ThreeWayMerge.js +0 -48
  37. package/dist/ThreeWayMerge.js.map +0 -1
  38. package/dist/cli.d.ts +0 -3
  39. package/dist/cli.d.ts.map +0 -1
  40. package/dist/cli.js +0 -462
  41. package/dist/cli.js.map +0 -1
  42. package/dist/commands/bootstrap.d.ts +0 -46
  43. package/dist/commands/bootstrap.d.ts.map +0 -1
  44. package/dist/commands/bootstrap.js +0 -262
  45. package/dist/commands/bootstrap.js.map +0 -1
  46. package/dist/commands/forget.d.ts +0 -26
  47. package/dist/commands/forget.d.ts.map +0 -1
  48. package/dist/commands/forget.js +0 -37
  49. package/dist/commands/forget.js.map +0 -1
  50. package/dist/commands/index.d.ts +0 -6
  51. package/dist/commands/index.d.ts.map +0 -1
  52. package/dist/commands/index.js +0 -6
  53. package/dist/commands/index.js.map +0 -1
  54. package/dist/commands/reset.d.ts +0 -28
  55. package/dist/commands/reset.d.ts.map +0 -1
  56. package/dist/commands/reset.js +0 -37
  57. package/dist/commands/reset.js.map +0 -1
  58. package/dist/commands/resolve.d.ts +0 -16
  59. package/dist/commands/resolve.d.ts.map +0 -1
  60. package/dist/commands/resolve.js +0 -28
  61. package/dist/commands/resolve.js.map +0 -1
  62. package/dist/commands/status.d.ts +0 -34
  63. package/dist/commands/status.d.ts.map +0 -1
  64. package/dist/commands/status.js +0 -32
  65. package/dist/commands/status.js.map +0 -1
  66. package/dist/git/CommitDetection.d.ts +0 -11
  67. package/dist/git/CommitDetection.d.ts.map +0 -1
  68. package/dist/git/CommitDetection.js +0 -25
  69. package/dist/git/CommitDetection.js.map +0 -1
  70. package/dist/git/GitClient.d.ts +0 -33
  71. package/dist/git/GitClient.d.ts.map +0 -1
  72. package/dist/git/GitClient.js +0 -118
  73. package/dist/git/GitClient.js.map +0 -1
  74. package/dist/index.d.ts.map +0 -1
  75. package/dist/types.d.ts +0 -78
  76. package/dist/types.d.ts.map +0 -1
  77. package/dist/types.js +0 -3
  78. package/dist/types.js.map +0 -1
@@ -1,533 +0,0 @@
1
- import { readFile, writeFile, mkdtemp, rm, mkdir } from "node:fs/promises";
2
- import { join, dirname, extname } from "node:path";
3
- import { tmpdir } from "node:os";
4
- import { minimatch } from "minimatch";
5
- import { threeWayMerge } from "./ThreeWayMerge.js";
6
- const BINARY_EXTENSIONS = new Set([
7
- ".png", ".jpg", ".jpeg", ".gif", ".bmp", ".ico", ".webp", ".svg",
8
- ".pdf", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx",
9
- ".zip", ".gz", ".tar", ".bz2", ".7z", ".rar",
10
- ".jar", ".war", ".ear", ".class",
11
- ".exe", ".dll", ".so", ".dylib", ".o", ".a",
12
- ".woff", ".woff2", ".ttf", ".eot", ".otf",
13
- ".mp3", ".mp4", ".avi", ".mov", ".wav", ".flac",
14
- ".sqlite", ".db",
15
- ".pyc", ".pyo",
16
- ".DS_Store",
17
- ]);
18
- export class ReplayApplicator {
19
- git;
20
- lockManager;
21
- outputDir;
22
- renameCache = new Map();
23
- fileTheirsAccumulator = new Map();
24
- constructor(git, lockManager, outputDir) {
25
- this.git = git;
26
- this.lockManager = lockManager;
27
- this.outputDir = outputDir;
28
- }
29
- /** Reset inter-patch accumulator for a new cycle. */
30
- resetAccumulator() {
31
- this.fileTheirsAccumulator.clear();
32
- }
33
- /**
34
- * Apply all patches, returning results for each.
35
- * Skips patches that match exclude patterns in replay.yml
36
- */
37
- async applyPatches(patches) {
38
- this.resetAccumulator(); // Clear accumulator for this apply cycle
39
- const results = [];
40
- for (const patch of patches) {
41
- if (this.isExcluded(patch)) {
42
- results.push({
43
- patch,
44
- status: "skipped",
45
- method: "git-am",
46
- });
47
- continue;
48
- }
49
- const result = await this.applyPatchWithFallback(patch);
50
- results.push(result);
51
- }
52
- return results;
53
- }
54
- /** Populate accumulator after git apply succeeds. */
55
- async populateAccumulatorForPatch(patch, baseGen, currentTreeHash) {
56
- if (!baseGen)
57
- return;
58
- // Create temp git repo to apply patches to base content
59
- const tempDir = await mkdtemp(join(tmpdir(), "replay-acc-"));
60
- const { GitClient } = await import("./git/GitClient.js");
61
- const tempGit = new GitClient(tempDir);
62
- await tempGit.exec(["init"]);
63
- await tempGit.exec(["config", "user.email", "replay@fern.com"]);
64
- await tempGit.exec(["config", "user.name", "Fern Replay"]);
65
- try {
66
- for (const filePath of patch.files) {
67
- if (isBinaryFile(filePath))
68
- continue;
69
- const resolvedPath = await this.resolveFilePath(filePath, baseGen.tree_hash, currentTreeHash);
70
- const base = await this.git.showFile(baseGen.tree_hash, filePath);
71
- const theirs = await this.applyPatchToContent(base, patch.patch_content, filePath, tempGit, tempDir);
72
- if (theirs && base) {
73
- this.fileTheirsAccumulator.set(resolvedPath, {
74
- content: theirs,
75
- baseGeneration: patch.base_generation,
76
- });
77
- }
78
- }
79
- }
80
- finally {
81
- await rm(tempDir, { recursive: true }).catch(() => { });
82
- }
83
- }
84
- /** Apply patch: try git apply --3way, fall back to per-file 3-way merge. */
85
- async applyPatchWithFallback(patch) {
86
- // Resolve all file paths to check accumulator (need baseGen for resolution)
87
- const baseGen = this.lockManager.getGeneration(patch.base_generation);
88
- const lock = this.lockManager.read();
89
- const currentGen = lock.generations.find((g) => g.commit_sha === lock.current_generation);
90
- const currentTreeHash = currentGen?.tree_hash ?? baseGen?.tree_hash ?? "";
91
- // Check if any file in this patch needs accumulation
92
- // If so, skip fast path to ensure we benefit from pre-merge logic
93
- const needsAccumulation = await Promise.all(patch.files.map(async (f) => {
94
- if (!baseGen)
95
- return false;
96
- const resolved = await this.resolveFilePath(f, baseGen.tree_hash, currentTreeHash);
97
- return this.fileTheirsAccumulator.has(resolved);
98
- })).then((results) => results.some(Boolean));
99
- // Strategy 1: Try git apply --3way (skip if accumulation needed)
100
- if (!needsAccumulation) {
101
- // Snapshot files before git apply (may leave conflict markers on failure)
102
- const snapshots = new Map();
103
- const resolvedFiles = {};
104
- for (const filePath of patch.files) {
105
- const resolvedPath = baseGen
106
- ? await this.resolveFilePath(filePath, baseGen.tree_hash, currentTreeHash)
107
- : filePath;
108
- if (resolvedPath !== filePath) {
109
- resolvedFiles[filePath] = resolvedPath;
110
- }
111
- const fullPath = join(this.outputDir, resolvedPath);
112
- snapshots.set(resolvedPath, await readFile(fullPath, "utf-8").catch(() => null));
113
- }
114
- try {
115
- await this.git.execWithInput(["apply", "--3way"], patch.patch_content);
116
- // Success! Populate accumulator so subsequent patches on these files
117
- // will skip fast path and use the pre-merge logic instead
118
- await this.populateAccumulatorForPatch(patch, baseGen, currentTreeHash);
119
- return {
120
- patch, status: "applied", method: "git-am",
121
- ...(Object.keys(resolvedFiles).length > 0 && { resolvedFiles }),
122
- };
123
- }
124
- catch {
125
- // git apply --3way failed and may have left conflict markers on disk
126
- // Restore files from snapshot to undo any corruption before fallback
127
- for (const [resolvedPath, content] of snapshots) {
128
- if (content != null) {
129
- await writeFile(join(this.outputDir, resolvedPath), content);
130
- }
131
- }
132
- }
133
- }
134
- // Strategy 2: Fall back to file-by-file 3-way merge (uses accumulator)
135
- return this.applyWithThreeWayMerge(patch);
136
- }
137
- /**
138
- * Manual 3-way merge for when git am fails.
139
- * Creates a single shared temp git repo for all files in the patch.
140
- */
141
- async applyWithThreeWayMerge(patch) {
142
- const fileResults = [];
143
- const resolvedFiles = {};
144
- const tempDir = await mkdtemp(join(tmpdir(), "replay-"));
145
- const { GitClient } = await import("./git/GitClient.js");
146
- const tempGit = new GitClient(tempDir);
147
- await tempGit.exec(["init"]);
148
- await tempGit.exec(["config", "user.email", "replay@fern.com"]);
149
- await tempGit.exec(["config", "user.name", "Fern Replay"]);
150
- try {
151
- for (const filePath of patch.files) {
152
- if (isBinaryFile(filePath)) {
153
- fileResults.push({
154
- file: filePath,
155
- status: "skipped",
156
- reason: "binary-file",
157
- });
158
- continue;
159
- }
160
- const result = await this.mergeFile(patch, filePath, tempGit, tempDir);
161
- if (result.file !== filePath) {
162
- resolvedFiles[filePath] = result.file;
163
- }
164
- fileResults.push(result);
165
- }
166
- }
167
- finally {
168
- await rm(tempDir, { recursive: true }).catch(() => { });
169
- }
170
- const conflictFiles = fileResults.filter((r) => r.status === "conflict");
171
- const hasConflicts = conflictFiles.length > 0;
172
- // Aggregate conflict reason from file-level to patch-level
173
- const conflictReason = hasConflicts
174
- ? (conflictFiles.some((f) => f.conflictReason === "base-generation-mismatch")
175
- ? "base-generation-mismatch"
176
- : conflictFiles[0]?.conflictReason)
177
- : undefined;
178
- return {
179
- patch,
180
- status: hasConflicts ? "conflict" : "applied",
181
- method: "3way-merge",
182
- fileResults,
183
- conflictReason,
184
- ...(Object.keys(resolvedFiles).length > 0 && { resolvedFiles }),
185
- };
186
- }
187
- /**
188
- * Merge a single file using 3-way merge.
189
- */
190
- async mergeFile(patch, filePath, tempGit, tempDir) {
191
- try {
192
- const baseGen = this.lockManager.getGeneration(patch.base_generation);
193
- if (!baseGen) {
194
- return { file: filePath, status: "skipped", reason: "base-generation-not-found" };
195
- }
196
- // Resolve file path in case the generator renamed it between generations
197
- const lock = this.lockManager.read();
198
- const currentGen = lock.generations.find((g) => g.commit_sha === lock.current_generation);
199
- const currentTreeHash = currentGen?.tree_hash ?? baseGen.tree_hash;
200
- const resolvedPath = await this.resolveFilePath(filePath, baseGen.tree_hash, currentTreeHash);
201
- // Build conflict metadata for this file (used if conflict occurs)
202
- const metadata = {
203
- patchId: patch.id,
204
- patchMessage: patch.original_message,
205
- baseGeneration: patch.base_generation,
206
- currentGeneration: lock.current_generation,
207
- };
208
- // BASE: pristine state from when user made their edit (old path)
209
- let base = await this.git.showFile(baseGen.tree_hash, filePath);
210
- // If BASE is null, check if this file is the target of a rename in the patch.
211
- // Rename diffs (e.g., git mv old new) have the content at the old path.
212
- let renameSourcePath;
213
- if (!base) {
214
- const renameSource = this.extractRenameSource(patch.patch_content, filePath);
215
- if (renameSource) {
216
- base = await this.git.showFile(baseGen.tree_hash, renameSource);
217
- renameSourcePath = renameSource;
218
- }
219
- }
220
- // OURS: current generated state on disk (resolved/new path)
221
- const oursPath = join(this.outputDir, resolvedPath);
222
- const ours = await readFile(oursPath, "utf-8").catch(() => null);
223
- // THEIRS: user's version (apply patch to base using original path)
224
- let theirs = await this.applyPatchToContent(base, patch.patch_content, filePath, tempGit, tempDir, renameSourcePath);
225
- // Fall back to accumulator as merge base for incremental patches.
226
- let useAccumulatorAsMergeBase = false;
227
- const accumulatorEntry = this.fileTheirsAccumulator.get(resolvedPath);
228
- if (!theirs && base && accumulatorEntry) {
229
- theirs = await this.applyPatchToContent(accumulatorEntry.content, patch.patch_content, filePath, tempGit, tempDir);
230
- if (theirs) {
231
- useAccumulatorAsMergeBase = true;
232
- }
233
- }
234
- // Pre-merge with accumulated customizations (skip when accumulator is merge base).
235
- let effective_theirs = theirs;
236
- let baseMismatchSkipped = false;
237
- if (theirs && base && !useAccumulatorAsMergeBase) {
238
- if (accumulatorEntry && accumulatorEntry.baseGeneration === patch.base_generation) {
239
- // Pre-merge: combine previous customizations with current patch
240
- try {
241
- const preMerged = threeWayMerge(base, accumulatorEntry.content, theirs);
242
- if (!preMerged.hasConflicts) {
243
- // Clean merge - use the combined result
244
- effective_theirs = preMerged.content;
245
- }
246
- else {
247
- // Pre-merge has conflicts - skip accumulator for this patch
248
- // to avoid nested conflict markers. User patches conflict
249
- // with each other and require manual resolution.
250
- effective_theirs = theirs;
251
- }
252
- }
253
- catch {
254
- // If pre-merge fails unexpectedly, fall back to current_theirs
255
- effective_theirs = theirs;
256
- }
257
- }
258
- else if (accumulatorEntry) {
259
- // Base generations differ - accumulator pre-merge skipped.
260
- // The main merge below will still run, but if it conflicts
261
- // we flag it as a base-generation-mismatch.
262
- baseMismatchSkipped = true;
263
- }
264
- }
265
- // Handle new files (user created, didn't exist in generation)
266
- if (!base && !ours && effective_theirs) {
267
- const outDir = dirname(oursPath);
268
- await mkdir(outDir, { recursive: true });
269
- await writeFile(oursPath, effective_theirs);
270
- return { file: resolvedPath, status: "merged", reason: "new-file" };
271
- }
272
- // Handle new file created by both user and generator (conflict)
273
- if (!base && ours && effective_theirs) {
274
- const merged = threeWayMerge("", ours, effective_theirs);
275
- const outDir = dirname(oursPath);
276
- await mkdir(outDir, { recursive: true });
277
- await writeFile(oursPath, merged.content);
278
- if (merged.hasConflicts) {
279
- return {
280
- file: resolvedPath,
281
- status: "conflict",
282
- conflicts: merged.conflicts,
283
- conflictReason: "new-file-both",
284
- conflictMetadata: metadata,
285
- };
286
- }
287
- return { file: resolvedPath, status: "merged" };
288
- }
289
- if (!effective_theirs) {
290
- return {
291
- file: resolvedPath,
292
- status: "skipped",
293
- reason: "missing-content",
294
- };
295
- }
296
- if (!base || !ours) {
297
- return {
298
- file: resolvedPath,
299
- status: "skipped",
300
- reason: "missing-content",
301
- };
302
- }
303
- // Perform 3-way merge.
304
- // For incremental patches, use the accumulated state as the merge base
305
- // so the diff is computed relative to prior patches, not the raw generation.
306
- const mergeBase = useAccumulatorAsMergeBase && accumulatorEntry
307
- ? accumulatorEntry.content : base;
308
- const merged = threeWayMerge(mergeBase, ours, effective_theirs);
309
- // Write result to the resolved (current) path
310
- const outDir = dirname(oursPath);
311
- await mkdir(outDir, { recursive: true });
312
- await writeFile(oursPath, merged.content);
313
- // Update accumulator after successful merge
314
- // This allows subsequent patches on the same file to benefit from pre-merge
315
- if (effective_theirs && base) {
316
- this.fileTheirsAccumulator.set(resolvedPath, {
317
- content: effective_theirs,
318
- baseGeneration: patch.base_generation,
319
- });
320
- }
321
- if (merged.hasConflicts) {
322
- return {
323
- file: resolvedPath,
324
- status: "conflict",
325
- conflicts: merged.conflicts,
326
- conflictReason: baseMismatchSkipped ? "base-generation-mismatch" : "same-line-edit",
327
- conflictMetadata: metadata,
328
- };
329
- }
330
- return { file: resolvedPath, status: "merged" };
331
- }
332
- catch (error) {
333
- return {
334
- file: filePath,
335
- status: "skipped",
336
- reason: `error: ${error instanceof Error ? error.message : String(error)}`,
337
- };
338
- }
339
- }
340
- /**
341
- * Check if patch should be skipped based on exclude patterns in replay.yml
342
- */
343
- isExcluded(patch) {
344
- const config = this.lockManager.getCustomizationsConfig();
345
- if (!config.exclude)
346
- return false;
347
- return patch.files.some((file) => config.exclude.some((pattern) => minimatch(file, pattern)));
348
- }
349
- /**
350
- * Resolve a file path that may have been renamed between generations.
351
- * Checks manual moves in replay.yml first, then git rename detection.
352
- */
353
- async resolveFilePath(filePath, baseTreeHash, currentTreeHash) {
354
- // Priority 1: Manual moves from replay.yml
355
- const config = this.lockManager.getCustomizationsConfig();
356
- if (config.moves) {
357
- for (const move of config.moves) {
358
- if (minimatch(filePath, move.from) || filePath === move.from) {
359
- // For exact matches, replace directly
360
- if (filePath === move.from) {
361
- return move.to;
362
- }
363
- // For glob matches, replace the matching prefix
364
- // e.g., from: "src/api/**" to: "src/resources/**"
365
- // filePath: "src/api/client.ts" → "src/resources/client.ts"
366
- const fromBase = move.from.replace(/\*\*.*$/, "");
367
- const toBase = move.to.replace(/\*\*.*$/, "");
368
- if (filePath.startsWith(fromBase)) {
369
- return toBase + filePath.slice(fromBase.length);
370
- }
371
- }
372
- }
373
- }
374
- // Priority 2: Git rename detection (cached per tree pair)
375
- const cacheKey = `${baseTreeHash}:${currentTreeHash}`;
376
- let renames = this.renameCache.get(cacheKey);
377
- if (!renames) {
378
- renames = await this.git.detectRenames(baseTreeHash, currentTreeHash);
379
- this.renameCache.set(cacheKey, renames);
380
- }
381
- const gitRename = renames.find((r) => r.from === filePath);
382
- if (gitRename) {
383
- return gitRename.to;
384
- }
385
- // Priority 3: No rename detected
386
- return filePath;
387
- }
388
- /**
389
- * Apply patch content to base to reconstruct user's version.
390
- * Uses the shared temp repo + git apply.
391
- */
392
- async applyPatchToContent(base, patchContent, filePath, tempGit, tempDir, sourceFilePath) {
393
- if (!base) {
394
- // New file - extract content directly from patch
395
- return this.extractNewFileFromPatch(patchContent, filePath);
396
- }
397
- // Extract only the diff for this specific file
398
- const fileDiff = this.extractFileDiff(patchContent, filePath);
399
- if (!fileDiff)
400
- return null;
401
- try {
402
- if (sourceFilePath) {
403
- // Rename case: write base at the OLD path, apply the rename diff,
404
- // then read from the NEW path (filePath).
405
- const tempSourcePath = join(tempDir, sourceFilePath);
406
- await mkdir(dirname(tempSourcePath), { recursive: true });
407
- await writeFile(tempSourcePath, base);
408
- await tempGit.exec(["add", sourceFilePath]);
409
- await tempGit.exec(["commit", "-m", `base for rename ${sourceFilePath} -> ${filePath}`, "--allow-empty"]);
410
- await tempGit.execWithInput(["apply", "--allow-empty"], fileDiff);
411
- const tempTargetPath = join(tempDir, filePath);
412
- return await readFile(tempTargetPath, "utf-8");
413
- }
414
- // Normal case: write base at filePath, apply diff, read back
415
- const tempFilePath = join(tempDir, filePath);
416
- await mkdir(dirname(tempFilePath), { recursive: true });
417
- await writeFile(tempFilePath, base);
418
- // Stage and commit so git apply has a clean base
419
- await tempGit.exec(["add", filePath]);
420
- await tempGit.exec(["commit", "-m", `base for ${filePath}`, "--allow-empty"]);
421
- // Apply this file's diff
422
- await tempGit.execWithInput(["apply", "--allow-empty"], fileDiff);
423
- return await readFile(tempFilePath, "utf-8");
424
- }
425
- catch {
426
- return null;
427
- }
428
- }
429
- /**
430
- * Extract the diff for a single file from a multi-file patch.
431
- * Returns just the `diff --git ...` block for the target file.
432
- */
433
- extractFileDiff(patchContent, filePath) {
434
- const lines = patchContent.split("\n");
435
- const diffLines = [];
436
- let inTargetFile = false;
437
- for (const line of lines) {
438
- if (line.startsWith("diff --git")) {
439
- if (inTargetFile) {
440
- // Hit the next file's diff, stop collecting
441
- break;
442
- }
443
- if (isDiffLineForFile(line, filePath)) {
444
- inTargetFile = true;
445
- diffLines.push(line);
446
- }
447
- continue;
448
- }
449
- if (inTargetFile) {
450
- diffLines.push(line);
451
- }
452
- }
453
- return diffLines.length > 0 ? diffLines.join("\n") + "\n" : null;
454
- }
455
- /**
456
- * Extract the rename source path from a patch for a given target file.
457
- * Returns the original path if the diff block for targetFilePath is a rename,
458
- * or null if it's not a rename.
459
- */
460
- extractRenameSource(patchContent, targetFilePath) {
461
- const lines = patchContent.split("\n");
462
- let inTargetFile = false;
463
- for (const line of lines) {
464
- if (line.startsWith("diff --git")) {
465
- if (inTargetFile)
466
- break; // past the target block
467
- inTargetFile = isDiffLineForFile(line, targetFilePath);
468
- continue;
469
- }
470
- if (!inTargetFile)
471
- continue;
472
- // Stop at first hunk — rename headers appear before @@
473
- if (line.startsWith("@@"))
474
- break;
475
- if (line.startsWith("rename from ")) {
476
- return line.slice("rename from ".length);
477
- }
478
- }
479
- return null;
480
- }
481
- /**
482
- * Extract new file content from a patch (when base is null).
483
- * Parses the unified diff to get the added lines.
484
- */
485
- extractNewFileFromPatch(patchContent, filePath) {
486
- const lines = patchContent.split("\n");
487
- const addedLines = [];
488
- let inTargetFile = false;
489
- let inHunk = false;
490
- let noTrailingNewline = false;
491
- for (const line of lines) {
492
- if (line.startsWith("diff --git")) {
493
- if (inTargetFile)
494
- break; // hit next file's diff
495
- inTargetFile = isDiffLineForFile(line, filePath);
496
- inHunk = false;
497
- continue;
498
- }
499
- if (!inTargetFile)
500
- continue;
501
- if (line.startsWith("@@")) {
502
- inHunk = true;
503
- continue;
504
- }
505
- if (!inHunk)
506
- continue;
507
- if (line === "\") {
508
- noTrailingNewline = true;
509
- continue;
510
- }
511
- if (line.startsWith("+") && !line.startsWith("+++")) {
512
- addedLines.push(line.slice(1));
513
- }
514
- }
515
- if (addedLines.length === 0)
516
- return null;
517
- return addedLines.join("\n") + (noTrailingNewline ? "" : "\n");
518
- }
519
- }
520
- function isBinaryFile(filePath) {
521
- const ext = extname(filePath).toLowerCase();
522
- return BINARY_EXTENSIONS.has(ext);
523
- }
524
- /**
525
- * Check if a `diff --git` line targets the given file path.
526
- * Uses a regex anchored to the line format to avoid substring false positives
527
- * (e.g., `lib/foo.ts` matching `b/lib/foo.ts-backup`).
528
- */
529
- function isDiffLineForFile(diffLine, filePath) {
530
- const match = diffLine.match(/^diff --git a\/.+ b\/(.+)$/);
531
- return match !== null && match[1] === filePath;
532
- }
533
- //# sourceMappingURL=ReplayApplicator.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ReplayApplicator.js","sourceRoot":"","sources":["../src/ReplayApplicator.ts"],"names":[],"mappings":"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"}
@@ -1,39 +0,0 @@
1
- import type { GitClient } from "./git/GitClient.js";
2
- import type { GenerationRecord, StoredPatch } from "./types.js";
3
- export interface CommitOptions {
4
- cliVersion: string;
5
- generatorVersions: Record<string, string>;
6
- }
7
- export declare class ReplayCommitter {
8
- private git;
9
- private outputDir;
10
- constructor(git: GitClient, outputDir: string);
11
- /**
12
- * Commit the generation output (after generator runs, before replay).
13
- * Uses [fern-generated] prefix for detection.
14
- */
15
- commitGeneration(message: string, options?: CommitOptions): Promise<string>;
16
- /**
17
- * Commit the replay result (after patches applied).
18
- * Uses [fern-replay] prefix for detection.
19
- */
20
- commitReplay(patchCount: number, patches?: StoredPatch[]): Promise<string>;
21
- /**
22
- * Create a GenerationRecord for the current state.
23
- * Captures commit SHA and tree hash for future 3-way merges.
24
- */
25
- createGenerationRecord(options?: CommitOptions): Promise<GenerationRecord>;
26
- /**
27
- * Stage all changes in output directory.
28
- */
29
- stageAll(): Promise<void>;
30
- /**
31
- * Check if there are staged changes to commit.
32
- */
33
- hasStagedChanges(): Promise<boolean>;
34
- /**
35
- * Get the tree hash for a commit.
36
- */
37
- getTreeHash(commitSha: string): Promise<string>;
38
- }
39
- //# sourceMappingURL=ReplayCommitter.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ReplayCommitter.d.ts","sourceRoot":"","sources":["../src/ReplayCommitter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEhE,MAAM,WAAW,aAAa;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7C;AAED,qBAAa,eAAe;IACxB,OAAO,CAAC,GAAG,CAAY;IACvB,OAAO,CAAC,SAAS,CAAS;gBAEd,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM;IAK7C;;;OAGG;IACG,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC;IAwBjF;;;OAGG;IACG,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAoBhF;;;OAGG;IACG,sBAAsB,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAahF;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAI/B;;OAEG;IACG,gBAAgB,IAAI,OAAO,CAAC,OAAO,CAAC;IAK1C;;OAEG;IACG,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAGxD"}