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