@fern-api/replay 0.1.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.
Files changed (86) hide show
  1. package/README.md +33 -0
  2. package/dist/ConflictPrompt.d.ts +13 -0
  3. package/dist/ConflictPrompt.d.ts.map +1 -0
  4. package/dist/ConflictPrompt.js +38 -0
  5. package/dist/ConflictPrompt.js.map +1 -0
  6. package/dist/ConflictResolver.d.ts +11 -0
  7. package/dist/ConflictResolver.d.ts.map +1 -0
  8. package/dist/ConflictResolver.js +53 -0
  9. package/dist/ConflictResolver.js.map +1 -0
  10. package/dist/FernignoreMigrator.d.ts +71 -0
  11. package/dist/FernignoreMigrator.d.ts.map +1 -0
  12. package/dist/FernignoreMigrator.js +243 -0
  13. package/dist/FernignoreMigrator.js.map +1 -0
  14. package/dist/LockfileManager.d.ts +27 -0
  15. package/dist/LockfileManager.d.ts.map +1 -0
  16. package/dist/LockfileManager.js +108 -0
  17. package/dist/LockfileManager.js.map +1 -0
  18. package/dist/ReplayApplicator.d.ts +68 -0
  19. package/dist/ReplayApplicator.d.ts.map +1 -0
  20. package/dist/ReplayApplicator.js +492 -0
  21. package/dist/ReplayApplicator.js.map +1 -0
  22. package/dist/ReplayCommitter.d.ts +39 -0
  23. package/dist/ReplayCommitter.d.ts.map +1 -0
  24. package/dist/ReplayCommitter.js +84 -0
  25. package/dist/ReplayCommitter.js.map +1 -0
  26. package/dist/ReplayDetector.d.ts +25 -0
  27. package/dist/ReplayDetector.d.ts.map +1 -0
  28. package/dist/ReplayDetector.js +110 -0
  29. package/dist/ReplayDetector.js.map +1 -0
  30. package/dist/ReplayService.d.ts +103 -0
  31. package/dist/ReplayService.d.ts.map +1 -0
  32. package/dist/ReplayService.js +457 -0
  33. package/dist/ReplayService.js.map +1 -0
  34. package/dist/ThreeWayMerge.d.ts +11 -0
  35. package/dist/ThreeWayMerge.d.ts.map +1 -0
  36. package/dist/ThreeWayMerge.js +48 -0
  37. package/dist/ThreeWayMerge.js.map +1 -0
  38. package/dist/cli.d.ts +3 -0
  39. package/dist/cli.d.ts.map +1 -0
  40. package/dist/cli.js +464 -0
  41. package/dist/cli.js.map +1 -0
  42. package/dist/commands/bootstrap.d.ts +44 -0
  43. package/dist/commands/bootstrap.d.ts.map +1 -0
  44. package/dist/commands/bootstrap.js +268 -0
  45. package/dist/commands/bootstrap.js.map +1 -0
  46. package/dist/commands/forget.d.ts +26 -0
  47. package/dist/commands/forget.d.ts.map +1 -0
  48. package/dist/commands/forget.js +37 -0
  49. package/dist/commands/forget.js.map +1 -0
  50. package/dist/commands/index.d.ts +6 -0
  51. package/dist/commands/index.d.ts.map +1 -0
  52. package/dist/commands/index.js +6 -0
  53. package/dist/commands/index.js.map +1 -0
  54. package/dist/commands/reset.d.ts +28 -0
  55. package/dist/commands/reset.d.ts.map +1 -0
  56. package/dist/commands/reset.js +37 -0
  57. package/dist/commands/reset.js.map +1 -0
  58. package/dist/commands/resolve.d.ts +16 -0
  59. package/dist/commands/resolve.d.ts.map +1 -0
  60. package/dist/commands/resolve.js +28 -0
  61. package/dist/commands/resolve.js.map +1 -0
  62. package/dist/commands/status.d.ts +34 -0
  63. package/dist/commands/status.d.ts.map +1 -0
  64. package/dist/commands/status.js +32 -0
  65. package/dist/commands/status.js.map +1 -0
  66. package/dist/environment.d.ts +5 -0
  67. package/dist/environment.d.ts.map +1 -0
  68. package/dist/environment.js +14 -0
  69. package/dist/environment.js.map +1 -0
  70. package/dist/git/CommitDetection.d.ts +17 -0
  71. package/dist/git/CommitDetection.d.ts.map +1 -0
  72. package/dist/git/CommitDetection.js +33 -0
  73. package/dist/git/CommitDetection.js.map +1 -0
  74. package/dist/git/GitClient.d.ts +28 -0
  75. package/dist/git/GitClient.d.ts.map +1 -0
  76. package/dist/git/GitClient.js +104 -0
  77. package/dist/git/GitClient.js.map +1 -0
  78. package/dist/index.d.ts +15 -0
  79. package/dist/index.d.ts.map +1 -0
  80. package/dist/index.js +14 -0
  81. package/dist/index.js.map +1 -0
  82. package/dist/types.d.ts +80 -0
  83. package/dist/types.d.ts.map +1 -0
  84. package/dist/types.js +9 -0
  85. package/dist/types.js.map +1 -0
  86. package/package.json +45 -0
@@ -0,0 +1,457 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { minimatch } from "minimatch";
4
+ import { GitClient } from "./git/GitClient.js";
5
+ import { LockfileManager } from "./LockfileManager.js";
6
+ import { ReplayDetector } from "./ReplayDetector.js";
7
+ import { ReplayApplicator } from "./ReplayApplicator.js";
8
+ import { ReplayCommitter } from "./ReplayCommitter.js";
9
+ import { resolveConflictMarkers } from "./ConflictResolver.js";
10
+ import { promptForConflictResolution } from "./ConflictPrompt.js";
11
+ import { isCI } from "./environment.js";
12
+ export class ReplayConflictError extends Error {
13
+ report;
14
+ constructor(report) {
15
+ super(`Replay produced ${report.patchesWithConflicts} patch conflict(s)`);
16
+ this.name = "ReplayConflictError";
17
+ this.report = report;
18
+ }
19
+ }
20
+ export class ReplayService {
21
+ git;
22
+ config;
23
+ detector;
24
+ applicator;
25
+ committer;
26
+ lockManager;
27
+ outputDir;
28
+ constructor(outputDir, config) {
29
+ const git = new GitClient(outputDir);
30
+ this.git = git;
31
+ this.config = config;
32
+ this.outputDir = outputDir;
33
+ this.lockManager = new LockfileManager(outputDir);
34
+ this.detector = new ReplayDetector(git, this.lockManager, outputDir);
35
+ this.applicator = new ReplayApplicator(git, this.lockManager, outputDir);
36
+ this.committer = new ReplayCommitter(git, outputDir);
37
+ }
38
+ /**
39
+ * Run the full replay flow.
40
+ */
41
+ async runReplay(options) {
42
+ const flow = this.determineFlow();
43
+ switch (flow) {
44
+ case "first-generation":
45
+ return this.handleFirstGeneration(options);
46
+ case "no-patches":
47
+ return this.handleNoPatchesRegeneration(options);
48
+ case "normal-regeneration":
49
+ return this.handleNormalRegeneration(options);
50
+ }
51
+ }
52
+ /**
53
+ * Determine which flow to use based on lockfile state.
54
+ */
55
+ determineFlow() {
56
+ if (!this.lockManager.exists()) {
57
+ return "first-generation";
58
+ }
59
+ const lock = this.lockManager.read();
60
+ if (lock.patches.length === 0) {
61
+ return "no-patches";
62
+ }
63
+ return "normal-regeneration";
64
+ }
65
+ /**
66
+ * First generation - just create lockfile, no patches to apply.
67
+ */
68
+ async handleFirstGeneration(options) {
69
+ if (options?.dryRun) {
70
+ return {
71
+ flow: "first-generation",
72
+ patchesDetected: 0,
73
+ patchesApplied: 0,
74
+ patchesWithConflicts: 0,
75
+ patchesSkipped: 0,
76
+ conflicts: [],
77
+ };
78
+ }
79
+ const commitOpts = options ? {
80
+ cliVersion: options.cliVersion ?? "unknown",
81
+ generatorVersions: options.generatorVersions ?? {},
82
+ } : undefined;
83
+ await this.committer.commitGeneration("Initial SDK generation", commitOpts);
84
+ const genRecord = await this.committer.createGenerationRecord(commitOpts);
85
+ this.lockManager.initialize(genRecord);
86
+ return {
87
+ flow: "first-generation",
88
+ patchesDetected: 0,
89
+ patchesApplied: 0,
90
+ patchesWithConflicts: 0,
91
+ patchesSkipped: 0,
92
+ conflicts: [],
93
+ };
94
+ }
95
+ /**
96
+ * No existing patches - detect new ones and apply if any.
97
+ */
98
+ async handleNoPatchesRegeneration(options) {
99
+ const newPatches = await this.detector.detectNewPatches();
100
+ const warnings = [...this.detector.warnings];
101
+ if (options?.dryRun) {
102
+ return {
103
+ flow: "no-patches",
104
+ patchesDetected: newPatches.length,
105
+ patchesApplied: 0,
106
+ patchesWithConflicts: 0,
107
+ patchesSkipped: 0,
108
+ conflicts: [],
109
+ wouldApply: newPatches,
110
+ warnings: warnings.length > 0 ? warnings : undefined,
111
+ };
112
+ }
113
+ const commitOpts = options ? {
114
+ cliVersion: options.cliVersion ?? "unknown",
115
+ generatorVersions: options.generatorVersions ?? {},
116
+ } : undefined;
117
+ await this.committer.commitGeneration("Update SDK", commitOpts);
118
+ const genRecord = await this.committer.createGenerationRecord(commitOpts);
119
+ let results = [];
120
+ if (newPatches.length > 0) {
121
+ results = await this.applicator.applyPatches(newPatches);
122
+ }
123
+ // Phase 1: Resolve conflict markers on disk BEFORE rebasing.
124
+ // This ensures rebasePatches() captures clean file content, not
125
+ // content with conflict markers baked in.
126
+ await this.resolveConflictsOnDisk(results, newPatches, "no-patches", options, warnings);
127
+ // Rebase cleanly applied patches to the current generation.
128
+ // This prevents recurring conflicts on subsequent regenerations.
129
+ const rebaseCounts = await this.rebasePatches(results, genRecord.commit_sha);
130
+ // Save lockfile BEFORE commit — lockfile is source of truth.
131
+ this.lockManager.addGeneration(genRecord);
132
+ for (const patch of newPatches) {
133
+ if (!rebaseCounts.absorbedPatchIds.has(patch.id)) {
134
+ this.lockManager.addPatch(patch);
135
+ }
136
+ }
137
+ this.lockManager.save();
138
+ // Phase 2: For "fail" policy, throw AFTER lockfile save so patches
139
+ // aren't lost, but BEFORE replay commit so broken code isn't committed.
140
+ this.enforceConflictFailPolicy(results, newPatches, "no-patches", options, warnings, rebaseCounts);
141
+ if (newPatches.length > 0) {
142
+ if (!options?.stageOnly) {
143
+ const appliedCount = results.filter((r) => r.status === "applied" || r.status === "conflict").length;
144
+ if (appliedCount > 0) {
145
+ await this.committer.commitReplay(appliedCount, newPatches);
146
+ }
147
+ }
148
+ else {
149
+ await this.committer.stageAll();
150
+ }
151
+ }
152
+ return this.buildReport("no-patches", newPatches, results, options, warnings, rebaseCounts);
153
+ }
154
+ /**
155
+ * Normal flow - apply existing patches + detect new ones.
156
+ */
157
+ async handleNormalRegeneration(options) {
158
+ const existingPatches = this.lockManager.getPatches();
159
+ const newPatches = await this.detector.detectNewPatches();
160
+ const warnings = [...this.detector.warnings];
161
+ const allPatches = [...existingPatches, ...newPatches];
162
+ if (options?.dryRun) {
163
+ return {
164
+ flow: "normal-regeneration",
165
+ patchesDetected: allPatches.length,
166
+ patchesApplied: 0,
167
+ patchesWithConflicts: 0,
168
+ patchesSkipped: 0,
169
+ conflicts: [],
170
+ wouldApply: allPatches,
171
+ warnings: warnings.length > 0 ? warnings : undefined,
172
+ };
173
+ }
174
+ const commitOpts = options ? {
175
+ cliVersion: options.cliVersion ?? "unknown",
176
+ generatorVersions: options.generatorVersions ?? {},
177
+ } : undefined;
178
+ await this.committer.commitGeneration("Update SDK", commitOpts);
179
+ const genRecord = await this.committer.createGenerationRecord(commitOpts);
180
+ const results = await this.applicator.applyPatches(allPatches);
181
+ // Phase 1: Resolve conflict markers on disk BEFORE rebasing.
182
+ await this.resolveConflictsOnDisk(results, allPatches, "normal-regeneration", options, warnings);
183
+ // Rebase cleanly applied patches to the current generation.
184
+ const rebaseCounts = await this.rebasePatches(results, genRecord.commit_sha);
185
+ // Save lockfile BEFORE commit — lockfile is source of truth.
186
+ this.lockManager.addGeneration(genRecord);
187
+ for (const patch of newPatches) {
188
+ if (!rebaseCounts.absorbedPatchIds.has(patch.id)) {
189
+ this.lockManager.addPatch(patch);
190
+ }
191
+ }
192
+ this.lockManager.save();
193
+ // Phase 2: For "fail" policy, throw AFTER lockfile save.
194
+ this.enforceConflictFailPolicy(results, allPatches, "normal-regeneration", options, warnings, rebaseCounts);
195
+ if (options?.stageOnly) {
196
+ await this.committer.stageAll();
197
+ }
198
+ else {
199
+ const appliedCount = results.filter((r) => r.status === "applied" || r.status === "conflict").length;
200
+ if (appliedCount > 0) {
201
+ await this.committer.commitReplay(appliedCount, allPatches);
202
+ }
203
+ }
204
+ return this.buildReport("normal-regeneration", allPatches, results, options, warnings, rebaseCounts);
205
+ }
206
+ /**
207
+ * Get the active conflict policy based on config and environment.
208
+ * Returns undefined when on_conflict is not configured (backwards-compatible).
209
+ */
210
+ getConflictPolicy() {
211
+ const onConflict = this.config.on_conflict;
212
+ if (!onConflict)
213
+ return undefined;
214
+ return isCI() ? onConflict.ci : onConflict.local;
215
+ }
216
+ /**
217
+ * Auto-resolve all conflict markers in conflicted files.
218
+ * "ours" = keep generated code, "theirs" = keep user customization.
219
+ */
220
+ async autoResolveConflicts(results, strategy) {
221
+ const { join } = await import("node:path");
222
+ for (const result of results) {
223
+ if (result.status !== "conflict" || !result.fileResults)
224
+ continue;
225
+ for (const fileResult of result.fileResults) {
226
+ if (fileResult.status !== "conflict")
227
+ continue;
228
+ const filePath = join(this.outputDir, fileResult.file);
229
+ await resolveConflictMarkers(filePath, strategy);
230
+ fileResult.status = "merged";
231
+ fileResult.reason = `auto-resolved (${strategy === "ours" ? "keep-generated" : "keep-mine"})`;
232
+ }
233
+ // If all files resolved, mark the patch as applied
234
+ const allResolved = result.fileResults.every((f) => f.status !== "conflict");
235
+ if (allResolved) {
236
+ result.status = "applied";
237
+ }
238
+ }
239
+ }
240
+ /**
241
+ * Phase 1: Resolve conflict markers on disk BEFORE rebasing.
242
+ * Handles keep-mine, keep-generated, and prompt policies.
243
+ * Must run before rebasePatches() so rebased content captures clean files.
244
+ */
245
+ async resolveConflictsOnDisk(results, allPatches, flow, options, warnings) {
246
+ const hasConflicts = results.some((r) => r.status === "conflict");
247
+ if (!hasConflicts)
248
+ return;
249
+ const policy = this.getConflictPolicy();
250
+ if (policy === undefined)
251
+ return; // backwards-compatible: commit with markers
252
+ switch (policy) {
253
+ case "fail":
254
+ // Don't resolve — enforceConflictFailPolicy() handles this after lockfile save
255
+ break;
256
+ case "keep-mine":
257
+ await this.autoResolveConflicts(results, "theirs");
258
+ break;
259
+ case "keep-generated":
260
+ await this.autoResolveConflicts(results, "ours");
261
+ break;
262
+ case "prompt": {
263
+ if (!process.stdin.isTTY)
264
+ break; // No TTY → fall through to default
265
+ const { join } = await import("node:path");
266
+ for (const result of results) {
267
+ if (result.status !== "conflict" || !result.fileResults)
268
+ continue;
269
+ for (const fileResult of result.fileResults) {
270
+ if (fileResult.status !== "conflict")
271
+ continue;
272
+ const answer = await promptForConflictResolution({
273
+ patchId: result.patch.id,
274
+ patchMessage: result.patch.original_message,
275
+ file: fileResult,
276
+ });
277
+ if (answer === "abort") {
278
+ const report = this.buildReport(flow, allPatches, results, options, warnings);
279
+ throw new ReplayConflictError(report);
280
+ }
281
+ if (answer === "ours" || answer === "theirs") {
282
+ const filePath = join(this.outputDir, fileResult.file);
283
+ await resolveConflictMarkers(filePath, answer);
284
+ fileResult.status = "merged";
285
+ fileResult.reason = `resolved (${answer === "ours" ? "keep-generated" : "keep-mine"})`;
286
+ }
287
+ // "manual" → leave conflict markers
288
+ }
289
+ const allResolved = result.fileResults.every((f) => f.status !== "conflict");
290
+ if (allResolved) {
291
+ result.status = "applied";
292
+ }
293
+ }
294
+ break;
295
+ }
296
+ case "create-pr":
297
+ // Future feature. Fall through with a warning.
298
+ if (warnings) {
299
+ warnings.push("on_conflict: create-pr is not yet implemented; conflict markers left in place");
300
+ }
301
+ break;
302
+ }
303
+ }
304
+ /**
305
+ * Phase 2: Throw for "fail" policy AFTER lockfile save.
306
+ * This ensures the lockfile is preserved even when we reject the commit.
307
+ */
308
+ enforceConflictFailPolicy(results, allPatches, flow, options, warnings, rebaseCounts) {
309
+ const hasConflicts = results.some((r) => r.status === "conflict");
310
+ if (!hasConflicts)
311
+ return;
312
+ const policy = this.getConflictPolicy();
313
+ if (policy !== "fail")
314
+ return;
315
+ const report = this.buildReport(flow, allPatches, results, options, warnings, rebaseCounts);
316
+ throw new ReplayConflictError(report);
317
+ }
318
+ /**
319
+ * Rebase cleanly applied patches so they are relative to the current generation.
320
+ * This prevents recurring conflicts on subsequent regenerations.
321
+ * Returns the number of patches rebased.
322
+ */
323
+ async rebasePatches(results, currentGenSha) {
324
+ let absorbed = 0;
325
+ let repointed = 0;
326
+ let contentRebased = 0;
327
+ let keptAsUserOwned = 0;
328
+ // Track content hashes seen during rebase to absorb duplicates.
329
+ // When incremental patches (e.g., commit A adds method, commit B renames it)
330
+ // are both rebased, they capture the same cumulative diff and become redundant.
331
+ const seenContentHashes = new Set();
332
+ const absorbedPatchIds = new Set();
333
+ for (const result of results) {
334
+ // Only rebase cleanly applied patches.
335
+ // Conflicted patches keep their old base_generation so they retry.
336
+ if (result.status !== "applied")
337
+ continue;
338
+ const patch = result.patch;
339
+ // Skip if already based on the current generation
340
+ if (patch.base_generation === currentGenSha)
341
+ continue;
342
+ try {
343
+ // Check if any files in this patch are user-owned and can never
344
+ // be "absorbed" by the generator. Three cases:
345
+ // 1. File doesn't exist in the gen commit tree (truly new file)
346
+ // 2. File is protected by .fernignore (preserved during gen wipe,
347
+ // so it exists in the gen tree, but the generator didn't produce it)
348
+ // 3. File IS .fernignore itself (always preserved during gen wipe,
349
+ // but doesn't list itself in its own patterns)
350
+ // In all cases, git diff returns empty, but removing the patch is wrong.
351
+ const fernignorePatterns = this.readFernignorePatterns();
352
+ const isUserOwned = await Promise.all(patch.files.map(async (file) => {
353
+ // .fernignore itself is always user-owned
354
+ if (file === ".fernignore") {
355
+ return true;
356
+ }
357
+ // Check .fernignore patterns (cheaper than git)
358
+ if (fernignorePatterns.some((p) => file === p || minimatch(file, p))) {
359
+ return true;
360
+ }
361
+ // Check if file exists in the generation commit tree
362
+ const content = await this.git.showFile(currentGenSha, file);
363
+ return content === null;
364
+ }));
365
+ const hasUserOwnedFiles = isUserOwned.some(Boolean);
366
+ if (hasUserOwnedFiles) {
367
+ // Patch contains user-owned files — just update base_generation
368
+ // to prevent re-evaluation. Keep patch_content as-is since
369
+ // these files aren't produced by the generator.
370
+ this.lockManager.updatePatch(patch.id, {
371
+ base_generation: currentGenSha,
372
+ });
373
+ keptAsUserOwned++;
374
+ continue;
375
+ }
376
+ // All files exist in generation — safe to use git diff for
377
+ // absorption check and patch rebasing.
378
+ const diff = await this.git.exec([
379
+ "diff", currentGenSha, "--", ...patch.files,
380
+ ]).catch(() => null);
381
+ if (!diff || !diff.trim()) {
382
+ // Patch is now empty — customization was absorbed by the generator.
383
+ // Only removePatch (not absorbedPatchIds) — new patches that haven't
384
+ // been added yet are correctly ignored by the no-op removePatch.
385
+ this.lockManager.removePatch(patch.id);
386
+ absorbed++;
387
+ continue;
388
+ }
389
+ const newContentHash = this.detector.computeContentHash(diff);
390
+ // If another patch already captured this exact diff, this patch
391
+ // is redundant (e.g., incremental patches that both resolve to
392
+ // the same cumulative state after rebase).
393
+ if (seenContentHashes.has(newContentHash)) {
394
+ this.lockManager.removePatch(patch.id);
395
+ absorbedPatchIds.add(patch.id);
396
+ absorbed++;
397
+ continue;
398
+ }
399
+ seenContentHashes.add(newContentHash);
400
+ this.lockManager.updatePatch(patch.id, {
401
+ base_generation: currentGenSha,
402
+ patch_content: diff,
403
+ content_hash: newContentHash,
404
+ });
405
+ contentRebased++;
406
+ }
407
+ catch {
408
+ // If rebasing fails for any reason, keep the original patch unchanged
409
+ }
410
+ }
411
+ return { absorbed, repointed, contentRebased, keptAsUserOwned, absorbedPatchIds };
412
+ }
413
+ /**
414
+ * Read .fernignore patterns from the output directory.
415
+ * Returns an empty array if .fernignore doesn't exist.
416
+ */
417
+ readFernignorePatterns() {
418
+ const fernignorePath = join(this.outputDir, ".fernignore");
419
+ if (!existsSync(fernignorePath))
420
+ return [];
421
+ return readFileSync(fernignorePath, "utf-8")
422
+ .split("\n")
423
+ .map((line) => line.trim())
424
+ .filter((line) => line && !line.startsWith("#"));
425
+ }
426
+ /**
427
+ * Build the final report from results.
428
+ */
429
+ buildReport(flow, patches, results, options, warnings, rebaseCounts) {
430
+ const conflictResults = results.filter((r) => r.status === "conflict");
431
+ const conflictDetails = conflictResults
432
+ .map((r) => ({
433
+ patchId: r.patch.id,
434
+ patchMessage: r.patch.original_message,
435
+ reason: r.conflictReason,
436
+ files: r.fileResults?.filter((f) => f.status === "conflict") ?? [],
437
+ }))
438
+ .filter((d) => d.files.length > 0);
439
+ return {
440
+ flow,
441
+ patchesDetected: patches.length,
442
+ patchesApplied: results.filter((r) => r.status === "applied").length,
443
+ patchesWithConflicts: conflictResults.length,
444
+ patchesSkipped: results.filter((r) => r.status === "skipped").length,
445
+ patchesAbsorbed: rebaseCounts && rebaseCounts.absorbed > 0 ? rebaseCounts.absorbed : undefined,
446
+ patchesRepointed: rebaseCounts && rebaseCounts.repointed > 0 ? rebaseCounts.repointed : undefined,
447
+ patchesContentRebased: rebaseCounts && rebaseCounts.contentRebased > 0 ? rebaseCounts.contentRebased : undefined,
448
+ patchesKeptAsUserOwned: rebaseCounts && rebaseCounts.keptAsUserOwned > 0 ? rebaseCounts.keptAsUserOwned : undefined,
449
+ conflicts: conflictResults
450
+ .flatMap((r) => r.fileResults?.filter((f) => f.status === "conflict") ?? []),
451
+ conflictDetails: conflictDetails.length > 0 ? conflictDetails : undefined,
452
+ wouldApply: options?.dryRun ? patches : undefined,
453
+ warnings: warnings && warnings.length > 0 ? warnings : undefined,
454
+ };
455
+ }
456
+ }
457
+ //# sourceMappingURL=ReplayService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ReplayService.js","sourceRoot":"","sources":["../src/ReplayService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { MergeResult } from "./types.js";
2
+ /**
3
+ * Performs a 3-way merge using the diff3 algorithm.
4
+ *
5
+ * @param base - The common ancestor (pristine generated state user edited against)
6
+ * @param ours - The new generated version
7
+ * @param theirs - The user's customized version
8
+ * @returns MergeResult with content, conflict flag, and conflict regions
9
+ */
10
+ export declare function threeWayMerge(base: string, ours: string, theirs: string): MergeResult;
11
+ //# sourceMappingURL=ThreeWayMerge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ThreeWayMerge.d.ts","sourceRoot":"","sources":["../src/ThreeWayMerge.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAkB,MAAM,YAAY,CAAC;AAE9D;;;;;;;GAOG;AACH,wBAAgB,aAAa,CACzB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GACf,WAAW,CA2Cb"}
@@ -0,0 +1,48 @@
1
+ import { diff3Merge } from "node-diff3";
2
+ /**
3
+ * Performs a 3-way merge using the diff3 algorithm.
4
+ *
5
+ * @param base - The common ancestor (pristine generated state user edited against)
6
+ * @param ours - The new generated version
7
+ * @param theirs - The user's customized version
8
+ * @returns MergeResult with content, conflict flag, and conflict regions
9
+ */
10
+ export function threeWayMerge(base, ours, theirs) {
11
+ const baseLines = base.split("\n");
12
+ const oursLines = ours.split("\n");
13
+ const theirsLines = theirs.split("\n");
14
+ const regions = diff3Merge(oursLines, baseLines, theirsLines);
15
+ const outputLines = [];
16
+ const conflicts = [];
17
+ let currentLine = 1;
18
+ for (const region of regions) {
19
+ if (region.ok) {
20
+ outputLines.push(...region.ok);
21
+ currentLine += region.ok.length;
22
+ }
23
+ else if (region.conflict) {
24
+ const startLine = currentLine;
25
+ outputLines.push("<<<<<<< OURS (generated)");
26
+ outputLines.push(...region.conflict.a);
27
+ outputLines.push("=======");
28
+ outputLines.push(...region.conflict.b);
29
+ outputLines.push(">>>>>>> THEIRS (your customization)");
30
+ // Total lines in conflict block: 3 markers + a.length + b.length
31
+ // endLine is the line number of the ">>>>>>>" marker
32
+ const conflictLines = region.conflict.a.length + region.conflict.b.length + 3;
33
+ conflicts.push({
34
+ startLine,
35
+ endLine: startLine + conflictLines - 1,
36
+ ours: region.conflict.a,
37
+ theirs: region.conflict.b,
38
+ });
39
+ currentLine += conflictLines;
40
+ }
41
+ }
42
+ return {
43
+ content: outputLines.join("\n"),
44
+ hasConflicts: conflicts.length > 0,
45
+ conflicts,
46
+ };
47
+ }
48
+ //# sourceMappingURL=ThreeWayMerge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ThreeWayMerge.js","sourceRoot":"","sources":["../src/ThreeWayMerge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAGxC;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CACzB,IAAY,EACZ,IAAY,EACZ,MAAc;IAEd,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAEvC,MAAM,OAAO,GAAG,UAAU,CAAC,SAAS,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;IAE9D,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,MAAM,SAAS,GAAqB,EAAE,CAAC;IACvC,IAAI,WAAW,GAAG,CAAC,CAAC;IAEpB,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC3B,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACZ,WAAW,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;YAC/B,WAAW,IAAI,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC;QACpC,CAAC;aAAM,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YACzB,MAAM,SAAS,GAAG,WAAW,CAAC;YAE9B,WAAW,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;YAC7C,WAAW,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YACvC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC5B,WAAW,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YACvC,WAAW,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;YAExD,iEAAiE;YACjE,qDAAqD;YACrD,MAAM,aAAa,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;YAC9E,SAAS,CAAC,IAAI,CAAC;gBACX,SAAS;gBACT,OAAO,EAAE,SAAS,GAAG,aAAa,GAAG,CAAC;gBACtC,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;gBACvB,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;aAC5B,CAAC,CAAC;YAEH,WAAW,IAAI,aAAa,CAAC;QACjC,CAAC;IACL,CAAC;IAED,OAAO;QACH,OAAO,EAAE,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;QAC/B,YAAY,EAAE,SAAS,CAAC,MAAM,GAAG,CAAC;QAClC,SAAS;KACZ,CAAC;AACN,CAAC"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}