@fern-api/fern-api-dev 4.62.3-3-g2870783b556 → 4.62.3-30-g41b622156cc

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 (2) hide show
  1. package/cli.cjs +1007 -94
  2. package/package.json +1 -1
package/cli.cjs CHANGED
@@ -363452,9 +363452,9 @@ var require_diff3 = __commonJS({
363452
363452
  }
363453
363453
  });
363454
363454
 
363455
- // ../../../node_modules/.pnpm/@fern-api+replay@0.8.0/node_modules/@fern-api/replay/dist/index.cjs
363455
+ // ../../../node_modules/.pnpm/@fern-api+replay@0.9.1/node_modules/@fern-api/replay/dist/index.cjs
363456
363456
  var require_dist11 = __commonJS({
363457
- "../../../node_modules/.pnpm/@fern-api+replay@0.8.0/node_modules/@fern-api/replay/dist/index.cjs"(exports2, module4) {
363457
+ "../../../node_modules/.pnpm/@fern-api+replay@0.9.1/node_modules/@fern-api/replay/dist/index.cjs"(exports2, module4) {
363458
363458
  "use strict";
363459
363459
  var __defProp4 = Object.defineProperty;
363460
363460
  var __getOwnPropDesc4 = Object.getOwnPropertyDescriptor;
@@ -363579,6 +363579,14 @@ var require_dist11 = __commonJS({
363579
363579
  return false;
363580
363580
  }
363581
363581
  }
363582
+ async treeExists(treeHash) {
363583
+ try {
363584
+ const type8 = await this.exec(["cat-file", "-t", treeHash]);
363585
+ return type8.trim() === "tree";
363586
+ } catch {
363587
+ return false;
363588
+ }
363589
+ }
363582
363590
  async getCommitBody(commitSha) {
363583
363591
  return this.exec(["log", "-1", "--format=%B", commitSha]);
363584
363592
  }
@@ -363588,6 +363596,253 @@ var require_dist11 = __commonJS({
363588
363596
  };
363589
363597
  }
363590
363598
  });
363599
+ var HybridReconstruction_exports = {};
363600
+ __export4(HybridReconstruction_exports, {
363601
+ assembleHybrid: () => assembleHybrid,
363602
+ locateHunksInOurs: () => locateHunksInOurs,
363603
+ parseHunks: () => parseHunks,
363604
+ reconstructFromGhostPatch: () => reconstructFromGhostPatch
363605
+ });
363606
+ function parseHunks(fileDiff) {
363607
+ const lines = fileDiff.split("\n");
363608
+ const hunks = [];
363609
+ let currentHunk = null;
363610
+ for (const line of lines) {
363611
+ const headerMatch = line.match(
363612
+ /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/
363613
+ );
363614
+ if (headerMatch) {
363615
+ if (currentHunk) {
363616
+ hunks.push(currentHunk);
363617
+ }
363618
+ currentHunk = {
363619
+ oldStart: parseInt(headerMatch[1], 10),
363620
+ oldCount: headerMatch[2] != null ? parseInt(headerMatch[2], 10) : 1,
363621
+ newStart: parseInt(headerMatch[3], 10),
363622
+ newCount: headerMatch[4] != null ? parseInt(headerMatch[4], 10) : 1,
363623
+ lines: []
363624
+ };
363625
+ continue;
363626
+ }
363627
+ if (!currentHunk) continue;
363628
+ if (line.startsWith("diff --git") || line.startsWith("index ") || line.startsWith("---") || line.startsWith("+++") || line.startsWith("old mode") || line.startsWith("new mode") || line.startsWith("similarity index") || line.startsWith("rename from") || line.startsWith("rename to") || line.startsWith("new file mode") || line.startsWith("deleted file mode")) {
363629
+ continue;
363630
+ }
363631
+ if (line === "\") {
363632
+ continue;
363633
+ }
363634
+ if (line.startsWith("-")) {
363635
+ currentHunk.lines.push({ type: "remove", content: line.slice(1) });
363636
+ } else if (line.startsWith("+")) {
363637
+ currentHunk.lines.push({ type: "add", content: line.slice(1) });
363638
+ } else if (line.startsWith(" ") || line === "") {
363639
+ currentHunk.lines.push({
363640
+ type: "context",
363641
+ content: line.startsWith(" ") ? line.slice(1) : line
363642
+ });
363643
+ }
363644
+ }
363645
+ if (currentHunk) {
363646
+ hunks.push(currentHunk);
363647
+ }
363648
+ return hunks;
363649
+ }
363650
+ function extractLeadingContext(hunk) {
363651
+ const result = [];
363652
+ for (const line of hunk.lines) {
363653
+ if (line.type !== "context") break;
363654
+ result.push(line.content);
363655
+ }
363656
+ return result;
363657
+ }
363658
+ function extractTrailingContext(hunk) {
363659
+ const result = [];
363660
+ for (let i11 = hunk.lines.length - 1; i11 >= 0; i11--) {
363661
+ if (hunk.lines[i11].type !== "context") break;
363662
+ result.unshift(hunk.lines[i11].content);
363663
+ }
363664
+ return result;
363665
+ }
363666
+ function countOursLinesBeforeTrailing(hunk) {
363667
+ let count = 0;
363668
+ const trailingStart = findTrailingContextStart(hunk);
363669
+ for (let i11 = 0; i11 < trailingStart; i11++) {
363670
+ if (hunk.lines[i11].type === "context") count++;
363671
+ }
363672
+ return count;
363673
+ }
363674
+ function findTrailingContextStart(hunk) {
363675
+ let i11 = hunk.lines.length - 1;
363676
+ while (i11 >= 0 && hunk.lines[i11].type === "context") {
363677
+ i11--;
363678
+ }
363679
+ return i11 + 1;
363680
+ }
363681
+ function matchesAt(needle, haystack, offset2) {
363682
+ for (let i11 = 0; i11 < needle.length; i11++) {
363683
+ if (haystack[offset2 + i11] !== needle[i11]) return false;
363684
+ }
363685
+ return true;
363686
+ }
363687
+ function findContextInOurs(contextLines, oursLines, minIndex, hint) {
363688
+ const SEARCH_WINDOW = 200;
363689
+ const maxStart = oursLines.length - contextLines.length;
363690
+ const clampedHint = Math.max(minIndex, Math.min(hint, maxStart));
363691
+ if (clampedHint >= minIndex && clampedHint <= maxStart) {
363692
+ if (matchesAt(contextLines, oursLines, clampedHint)) {
363693
+ return clampedHint;
363694
+ }
363695
+ }
363696
+ for (let delta = 1; delta <= SEARCH_WINDOW; delta++) {
363697
+ for (const sign2 of [1, -1]) {
363698
+ const idx = clampedHint + delta * sign2;
363699
+ if (idx < minIndex || idx > maxStart) continue;
363700
+ if (matchesAt(contextLines, oursLines, idx)) {
363701
+ return idx;
363702
+ }
363703
+ }
363704
+ }
363705
+ return -1;
363706
+ }
363707
+ function computeOursSpan(hunk, oursLines, oursOffset) {
363708
+ const leading = extractLeadingContext(hunk);
363709
+ const trailing = extractTrailingContext(hunk);
363710
+ if (trailing.length === 0) {
363711
+ const contextCount2 = hunk.lines.filter(
363712
+ (l14) => l14.type === "context"
363713
+ ).length;
363714
+ return Math.min(contextCount2, oursLines.length - oursOffset);
363715
+ }
363716
+ const searchStart = oursOffset + leading.length;
363717
+ for (let i11 = searchStart; i11 <= oursLines.length - trailing.length; i11++) {
363718
+ if (matchesAt(trailing, oursLines, i11)) {
363719
+ return i11 + trailing.length - oursOffset;
363720
+ }
363721
+ }
363722
+ const contextCount = hunk.lines.filter(
363723
+ (l14) => l14.type === "context"
363724
+ ).length;
363725
+ return Math.min(contextCount, oursLines.length - oursOffset);
363726
+ }
363727
+ function locateHunksInOurs(hunks, oursLines) {
363728
+ const located = [];
363729
+ let minOursIndex = 0;
363730
+ for (const hunk of hunks) {
363731
+ const contextLines = extractLeadingContext(hunk);
363732
+ let oursOffset;
363733
+ if (contextLines.length > 0) {
363734
+ const found = findContextInOurs(
363735
+ contextLines,
363736
+ oursLines,
363737
+ minOursIndex,
363738
+ hunk.newStart - 1
363739
+ );
363740
+ if (found === -1) {
363741
+ const trailingContext = extractTrailingContext(hunk);
363742
+ if (trailingContext.length > 0) {
363743
+ const trailingFound = findContextInOurs(
363744
+ trailingContext,
363745
+ oursLines,
363746
+ minOursIndex,
363747
+ hunk.newStart - 1
363748
+ );
363749
+ if (trailingFound === -1) return null;
363750
+ const nonTrailingCount = countOursLinesBeforeTrailing(hunk);
363751
+ oursOffset = trailingFound - nonTrailingCount;
363752
+ if (oursOffset < minOursIndex) return null;
363753
+ } else {
363754
+ return null;
363755
+ }
363756
+ } else {
363757
+ oursOffset = found;
363758
+ }
363759
+ } else if (hunk.oldStart === 1 && hunk.oldCount === 0) {
363760
+ oursOffset = 0;
363761
+ } else {
363762
+ oursOffset = Math.max(hunk.newStart - 1, minOursIndex);
363763
+ }
363764
+ const oursSpan = computeOursSpan(hunk, oursLines, oursOffset);
363765
+ located.push({ hunk, oursOffset, oursSpan });
363766
+ minOursIndex = oursOffset + oursSpan;
363767
+ }
363768
+ return located;
363769
+ }
363770
+ function assembleHybrid(locatedHunks, oursLines) {
363771
+ const baseLines = [];
363772
+ const theirsLines = [];
363773
+ let oursCursor = 0;
363774
+ for (const { hunk, oursOffset, oursSpan } of locatedHunks) {
363775
+ if (oursOffset > oursCursor) {
363776
+ const gapLines = oursLines.slice(oursCursor, oursOffset);
363777
+ baseLines.push(...gapLines);
363778
+ theirsLines.push(...gapLines);
363779
+ }
363780
+ for (const line of hunk.lines) {
363781
+ switch (line.type) {
363782
+ case "context":
363783
+ baseLines.push(line.content);
363784
+ theirsLines.push(line.content);
363785
+ break;
363786
+ case "remove":
363787
+ baseLines.push(line.content);
363788
+ break;
363789
+ case "add":
363790
+ theirsLines.push(line.content);
363791
+ break;
363792
+ }
363793
+ }
363794
+ oursCursor = oursOffset + oursSpan;
363795
+ }
363796
+ if (oursCursor < oursLines.length) {
363797
+ const gapLines = oursLines.slice(oursCursor);
363798
+ baseLines.push(...gapLines);
363799
+ theirsLines.push(...gapLines);
363800
+ }
363801
+ return {
363802
+ base: baseLines.join("\n"),
363803
+ theirs: theirsLines.join("\n")
363804
+ };
363805
+ }
363806
+ function reconstructFromGhostPatch(fileDiff, ours) {
363807
+ const hunks = parseHunks(fileDiff);
363808
+ if (hunks.length === 0) {
363809
+ return null;
363810
+ }
363811
+ const isPureAddition = hunks.every(
363812
+ (h14) => h14.oldCount === 0 && h14.lines.every((l14) => l14.type !== "remove")
363813
+ );
363814
+ if (isPureAddition) {
363815
+ return null;
363816
+ }
363817
+ const isPureDeletion = hunks.every(
363818
+ (h14) => h14.newCount === 0 && h14.lines.every((l14) => l14.type !== "add")
363819
+ );
363820
+ if (isPureDeletion) {
363821
+ const baseLines = [];
363822
+ for (const hunk of hunks) {
363823
+ for (const line of hunk.lines) {
363824
+ if (line.type === "context" || line.type === "remove") {
363825
+ baseLines.push(line.content);
363826
+ }
363827
+ }
363828
+ }
363829
+ return {
363830
+ base: baseLines.join("\n"),
363831
+ theirs: ""
363832
+ };
363833
+ }
363834
+ const oursLines = ours.split("\n");
363835
+ const located = locateHunksInOurs(hunks, oursLines);
363836
+ if (!located) {
363837
+ return null;
363838
+ }
363839
+ return assembleHybrid(located, oursLines);
363840
+ }
363841
+ var init_HybridReconstruction = __esm3({
363842
+ "src/HybridReconstruction.ts"() {
363843
+ "use strict";
363844
+ }
363845
+ });
363591
363846
  var index_exports = {};
363592
363847
  __export4(index_exports, {
363593
363848
  FERN_BOT_EMAIL: () => FERN_BOT_EMAIL,
@@ -363631,7 +363886,7 @@ var require_dist11 = __commonJS({
363631
363886
  return commit.message.startsWith("[fern-replay]");
363632
363887
  }
363633
363888
  function isRevertCommit(message) {
363634
- return message.startsWith('Revert "');
363889
+ return /^Revert ".+"$/.test(message);
363635
363890
  }
363636
363891
  function parseRevertedSha(fullBody) {
363637
363892
  const match3 = fullBody.match(/This reverts commit ([0-9a-f]{40})\./);
@@ -363730,6 +363985,15 @@ var require_dist11 = __commonJS({
363730
363985
  this.ensureLoaded();
363731
363986
  this.lock.patches = [];
363732
363987
  }
363988
+ addForgottenHash(hash5) {
363989
+ this.ensureLoaded();
363990
+ if (!this.lock.forgotten_hashes) {
363991
+ this.lock.forgotten_hashes = [];
363992
+ }
363993
+ if (!this.lock.forgotten_hashes.includes(hash5)) {
363994
+ this.lock.forgotten_hashes.push(hash5);
363995
+ }
363996
+ }
363733
363997
  getUnresolvedPatches() {
363734
363998
  this.ensureLoaded();
363735
363999
  return this.lock.patches.filter((p10) => p10.status === "unresolved");
@@ -363824,6 +364088,7 @@ var require_dist11 = __commonJS({
363824
364088
  }
363825
364089
  const commits = this.parseGitLog(log4);
363826
364090
  const newPatches = [];
364091
+ const forgottenHashes = new Set(lock.forgotten_hashes ?? []);
363827
364092
  for (const commit of commits) {
363828
364093
  if (isGenerationCommit(commit)) {
363829
364094
  continue;
@@ -363837,7 +364102,7 @@ var require_dist11 = __commonJS({
363837
364102
  }
363838
364103
  const patchContent = await this.git.formatPatch(commit.sha);
363839
364104
  const contentHash = this.computeContentHash(patchContent);
363840
- if (lock.patches.find((p10) => p10.content_hash === contentHash)) {
364105
+ if (lock.patches.find((p10) => p10.content_hash === contentHash) || forgottenHashes.has(contentHash)) {
363841
364106
  continue;
363842
364107
  }
363843
364108
  const filesOutput = await this.git.exec(["diff-tree", "--no-commit-id", "--name-only", "-r", commit.sha]);
@@ -363907,6 +364172,9 @@ var require_dist11 = __commonJS({
363907
364172
  revertIndicesToRemove.add(idx);
363908
364173
  }
363909
364174
  }
364175
+ if (!matchedExisting && !matchedNew) {
364176
+ revertIndicesToRemove.add(i11);
364177
+ }
363910
364178
  }
363911
364179
  const filteredPatches = newPatches.filter((_16, i11) => !revertIndicesToRemove.has(i11));
363912
364180
  return { patches: filteredPatches, revertedPatchIds: [...revertedPatchIdSet] };
@@ -363933,7 +364201,7 @@ var require_dist11 = __commonJS({
363933
364201
  if (!diff2.trim()) return { patches: [], revertedPatchIds: [] };
363934
364202
  const contentHash = this.computeContentHash(diff2);
363935
364203
  const lock = this.lockManager.read();
363936
- if (lock.patches.some((p10) => p10.content_hash === contentHash)) {
364204
+ if (lock.patches.some((p10) => p10.content_hash === contentHash) || (lock.forgotten_hashes ?? []).includes(contentHash)) {
363937
364205
  return { patches: [], revertedPatchIds: [] };
363938
364206
  }
363939
364207
  const headSha = (await this.git.exec(["rev-parse", "HEAD"])).trim();
@@ -363999,6 +364267,32 @@ var require_dist11 = __commonJS({
363999
364267
  var import_node_os15 = require("os");
364000
364268
  var import_node_path210 = require("path");
364001
364269
  var import_minimatch8 = require_commonjs3();
364270
+ function stripConflictMarkers(content5) {
364271
+ const lines = content5.split("\n");
364272
+ const result = [];
364273
+ let inConflict = false;
364274
+ let inOurs = false;
364275
+ for (const line of lines) {
364276
+ if (line.startsWith("<<<<<<< ")) {
364277
+ inConflict = true;
364278
+ inOurs = true;
364279
+ continue;
364280
+ }
364281
+ if (inConflict && line === "=======") {
364282
+ inOurs = false;
364283
+ continue;
364284
+ }
364285
+ if (inConflict && line.startsWith(">>>>>>> ")) {
364286
+ inConflict = false;
364287
+ inOurs = false;
364288
+ continue;
364289
+ }
364290
+ if (!inConflict || inOurs) {
364291
+ result.push(line);
364292
+ }
364293
+ }
364294
+ return result.join("\n");
364295
+ }
364002
364296
  var BINARY_EXTENSIONS2 = /* @__PURE__ */ new Set([
364003
364297
  ".png",
364004
364298
  ".jpg",
@@ -364053,6 +364347,7 @@ var require_dist11 = __commonJS({
364053
364347
  lockManager;
364054
364348
  outputDir;
364055
364349
  renameCache = /* @__PURE__ */ new Map();
364350
+ treeExistsCache = /* @__PURE__ */ new Map();
364056
364351
  fileTheirsAccumulator = /* @__PURE__ */ new Map();
364057
364352
  constructor(git, lockManager, outputDir) {
364058
364353
  this.git = git;
@@ -364070,7 +364365,8 @@ var require_dist11 = __commonJS({
364070
364365
  async applyPatches(patches) {
364071
364366
  this.resetAccumulator();
364072
364367
  const results = [];
364073
- for (const patch5 of patches) {
364368
+ for (let i11 = 0; i11 < patches.length; i11++) {
364369
+ const patch5 = patches[i11];
364074
364370
  if (this.isExcluded(patch5)) {
364075
364371
  results.push({
364076
364372
  patch: patch5,
@@ -364081,6 +364377,33 @@ var require_dist11 = __commonJS({
364081
364377
  }
364082
364378
  const result = await this.applyPatchWithFallback(patch5);
364083
364379
  results.push(result);
364380
+ if (result.status === "conflict" && result.fileResults) {
364381
+ const laterFiles = /* @__PURE__ */ new Set();
364382
+ for (let j16 = i11 + 1; j16 < patches.length; j16++) {
364383
+ for (const f10 of patches[j16].files) {
364384
+ laterFiles.add(f10);
364385
+ }
364386
+ }
364387
+ const resolvedToOriginal = /* @__PURE__ */ new Map();
364388
+ if (result.resolvedFiles) {
364389
+ for (const [orig, resolved] of Object.entries(result.resolvedFiles)) {
364390
+ resolvedToOriginal.set(resolved, orig);
364391
+ }
364392
+ }
364393
+ for (const fileResult of result.fileResults) {
364394
+ if (fileResult.status !== "conflict") continue;
364395
+ const originalPath = resolvedToOriginal.get(fileResult.file) ?? fileResult.file;
364396
+ if (laterFiles.has(fileResult.file) || laterFiles.has(originalPath)) {
364397
+ const filePath = (0, import_node_path210.join)(this.outputDir, fileResult.file);
364398
+ try {
364399
+ const content5 = await (0, import_promises181.readFile)(filePath, "utf-8");
364400
+ const stripped = stripConflictMarkers(content5);
364401
+ await (0, import_promises181.writeFile)(filePath, stripped);
364402
+ } catch {
364403
+ }
364404
+ }
364405
+ }
364406
+ }
364084
364407
  }
364085
364408
  return results;
364086
364409
  }
@@ -364099,7 +364422,7 @@ var require_dist11 = __commonJS({
364099
364422
  const resolvedPath = await this.resolveFilePath(filePath, baseGen.tree_hash, currentTreeHash);
364100
364423
  const base4 = await this.git.showFile(baseGen.tree_hash, filePath);
364101
364424
  const theirs = await this.applyPatchToContent(base4, patch5.patch_content, filePath, tempGit, tempDir2);
364102
- if (theirs && base4) {
364425
+ if (theirs) {
364103
364426
  this.fileTheirsAccumulator.set(resolvedPath, {
364104
364427
  content: theirs,
364105
364428
  baseGeneration: patch5.base_generation
@@ -364221,17 +364544,36 @@ var require_dist11 = __commonJS({
364221
364544
  }
364222
364545
  const oursPath = (0, import_node_path210.join)(this.outputDir, resolvedPath);
364223
364546
  const ours = await (0, import_promises181.readFile)(oursPath, "utf-8").catch(() => null);
364224
- let theirs = await this.applyPatchToContent(
364225
- base4,
364226
- patch5.patch_content,
364227
- filePath,
364228
- tempGit,
364229
- tempDir2,
364230
- renameSourcePath
364231
- );
364547
+ let ghostReconstructed = false;
364548
+ let theirs = null;
364549
+ if (!base4 && ours && !renameSourcePath) {
364550
+ const treeReachable = await this.isTreeReachable(baseGen.tree_hash);
364551
+ if (!treeReachable) {
364552
+ const fileDiff = this.extractFileDiff(patch5.patch_content, filePath);
364553
+ if (fileDiff) {
364554
+ const { reconstructFromGhostPatch: reconstructFromGhostPatch2 } = await Promise.resolve().then(() => (init_HybridReconstruction(), HybridReconstruction_exports));
364555
+ const result = reconstructFromGhostPatch2(fileDiff, ours);
364556
+ if (result) {
364557
+ base4 = result.base;
364558
+ theirs = result.theirs;
364559
+ ghostReconstructed = true;
364560
+ }
364561
+ }
364562
+ }
364563
+ }
364564
+ if (!ghostReconstructed) {
364565
+ theirs = await this.applyPatchToContent(
364566
+ base4,
364567
+ patch5.patch_content,
364568
+ filePath,
364569
+ tempGit,
364570
+ tempDir2,
364571
+ renameSourcePath
364572
+ );
364573
+ }
364232
364574
  let useAccumulatorAsMergeBase = false;
364233
364575
  const accumulatorEntry = this.fileTheirsAccumulator.get(resolvedPath);
364234
- if (!theirs && base4 && accumulatorEntry) {
364576
+ if (!theirs && accumulatorEntry) {
364235
364577
  theirs = await this.applyPatchToContent(
364236
364578
  accumulatorEntry.content,
364237
364579
  patch5.patch_content,
@@ -364261,13 +364603,13 @@ var require_dist11 = __commonJS({
364261
364603
  baseMismatchSkipped = true;
364262
364604
  }
364263
364605
  }
364264
- if (!base4 && !ours && effective_theirs) {
364606
+ if (base4 == null && !ours && effective_theirs) {
364265
364607
  const outDir2 = (0, import_node_path210.dirname)(oursPath);
364266
364608
  await (0, import_promises181.mkdir)(outDir2, { recursive: true });
364267
364609
  await (0, import_promises181.writeFile)(oursPath, effective_theirs);
364268
364610
  return { file: resolvedPath, status: "merged", reason: "new-file" };
364269
364611
  }
364270
- if (!base4 && ours && effective_theirs) {
364612
+ if (base4 == null && ours && effective_theirs) {
364271
364613
  const merged2 = threeWayMerge("", ours, effective_theirs);
364272
364614
  const outDir2 = (0, import_node_path210.dirname)(oursPath);
364273
364615
  await (0, import_promises181.mkdir)(outDir2, { recursive: true });
@@ -364290,7 +364632,7 @@ var require_dist11 = __commonJS({
364290
364632
  reason: "missing-content"
364291
364633
  };
364292
364634
  }
364293
- if (!base4 || !ours) {
364635
+ if (base4 == null && !useAccumulatorAsMergeBase || !ours) {
364294
364636
  return {
364295
364637
  file: resolvedPath,
364296
364638
  status: "skipped",
@@ -364298,11 +364640,18 @@ var require_dist11 = __commonJS({
364298
364640
  };
364299
364641
  }
364300
364642
  const mergeBase = useAccumulatorAsMergeBase && accumulatorEntry ? accumulatorEntry.content : base4;
364643
+ if (mergeBase == null) {
364644
+ return {
364645
+ file: resolvedPath,
364646
+ status: "skipped",
364647
+ reason: "missing-content"
364648
+ };
364649
+ }
364301
364650
  const merged = threeWayMerge(mergeBase, ours, effective_theirs);
364302
364651
  const outDir = (0, import_node_path210.dirname)(oursPath);
364303
364652
  await (0, import_promises181.mkdir)(outDir, { recursive: true });
364304
364653
  await (0, import_promises181.writeFile)(oursPath, merged.content);
364305
- if (effective_theirs && base4) {
364654
+ if (effective_theirs) {
364306
364655
  this.fileTheirsAccumulator.set(resolvedPath, {
364307
364656
  content: effective_theirs,
364308
364657
  baseGeneration: patch5.base_generation
@@ -364326,6 +364675,14 @@ var require_dist11 = __commonJS({
364326
364675
  };
364327
364676
  }
364328
364677
  }
364678
+ async isTreeReachable(treeHash) {
364679
+ let result = this.treeExistsCache.get(treeHash);
364680
+ if (result === void 0) {
364681
+ result = await this.git.treeExists(treeHash);
364682
+ this.treeExistsCache.set(treeHash, result);
364683
+ }
364684
+ return result;
364685
+ }
364329
364686
  isExcluded(patch5) {
364330
364687
  const config5 = this.lockManager.getCustomizationsConfig();
364331
364688
  if (!config5.exclude) return false;
@@ -364541,32 +364898,6 @@ CLI Version: ${options2.cliVersion}`;
364541
364898
  var import_node_path310 = require("path");
364542
364899
  var import_minimatch22 = require_commonjs3();
364543
364900
  init_GitClient();
364544
- function stripConflictMarkers(content5) {
364545
- const lines = content5.split("\n");
364546
- const result = [];
364547
- let inConflict = false;
364548
- let inOurs = false;
364549
- for (const line of lines) {
364550
- if (line.startsWith("<<<<<<< ")) {
364551
- inConflict = true;
364552
- inOurs = true;
364553
- continue;
364554
- }
364555
- if (inConflict && line === "=======") {
364556
- inOurs = false;
364557
- continue;
364558
- }
364559
- if (inConflict && line.startsWith(">>>>>>> ")) {
364560
- inConflict = false;
364561
- inOurs = false;
364562
- continue;
364563
- }
364564
- if (!inConflict || inOurs) {
364565
- result.push(line);
364566
- }
364567
- }
364568
- return result.join("\n");
364569
- }
364570
364901
  var ReplayService = class {
364571
364902
  git;
364572
364903
  detector;
@@ -365418,6 +365749,7 @@ CLI Version: ${options2.cliVersion}`;
365418
365749
  }
365419
365750
  lockManager.save();
365420
365751
  const fernignoreUpdated = ensureFernignoreEntries(outputDir);
365752
+ ensureGitattributesEntries(outputDir);
365421
365753
  if (migrator.fernignoreExists() && fernignorePatterns.length > 0) {
365422
365754
  const action = options2?.fernignoreAction ?? "skip";
365423
365755
  if (action === "migrate") {
@@ -365499,7 +365831,7 @@ CLI Version: ${options2.cliVersion}`;
365499
365831
  return { sha, authorName, authorEmail, message };
365500
365832
  });
365501
365833
  }
365502
- var REPLAY_FERNIGNORE_ENTRIES = [".fern/replay.lock", ".fern/replay.yml"];
365834
+ var REPLAY_FERNIGNORE_ENTRIES = [".fern/replay.lock", ".fern/replay.yml", ".gitattributes"];
365503
365835
  function ensureFernignoreEntries(outputDir) {
365504
365836
  const fernignorePath = (0, import_node_path52.join)(outputDir, ".fernignore");
365505
365837
  let content5 = "";
@@ -365523,35 +365855,173 @@ CLI Version: ${options2.cliVersion}`;
365523
365855
  (0, import_node_fs42.writeFileSync)(fernignorePath, content5, "utf-8");
365524
365856
  return true;
365525
365857
  }
365858
+ var GITATTRIBUTES_ENTRIES = [".fern/replay.lock linguist-generated=true"];
365859
+ function ensureGitattributesEntries(outputDir) {
365860
+ const gitattributesPath = (0, import_node_path52.join)(outputDir, ".gitattributes");
365861
+ let content5 = "";
365862
+ if ((0, import_node_fs42.existsSync)(gitattributesPath)) {
365863
+ content5 = (0, import_node_fs42.readFileSync)(gitattributesPath, "utf-8");
365864
+ }
365865
+ const lines = content5.split("\n");
365866
+ const toAdd = [];
365867
+ for (const entry of GITATTRIBUTES_ENTRIES) {
365868
+ if (!lines.some((line) => line.trim() === entry)) {
365869
+ toAdd.push(entry);
365870
+ }
365871
+ }
365872
+ if (toAdd.length === 0) {
365873
+ return;
365874
+ }
365875
+ if (content5 && !content5.endsWith("\n")) {
365876
+ content5 += "\n";
365877
+ }
365878
+ content5 += toAdd.join("\n") + "\n";
365879
+ (0, import_node_fs42.writeFileSync)(gitattributesPath, content5, "utf-8");
365880
+ }
365526
365881
  function computeContentHash(patchContent) {
365527
365882
  const normalized = patchContent.split("\n").filter((line) => !line.startsWith("From ") && !line.startsWith("index ") && !line.startsWith("Date: ")).join("\n");
365528
365883
  return `sha256:${(0, import_node_crypto32.createHash)("sha256").update(normalized).digest("hex")}`;
365529
365884
  }
365530
365885
  var import_minimatch42 = require_commonjs3();
365531
- function forget(outputDir, filePattern, options2) {
365886
+ function parseDiffStat(patchContent) {
365887
+ let additions = 0;
365888
+ let deletions = 0;
365889
+ let inDiffHunk = false;
365890
+ for (const line of patchContent.split("\n")) {
365891
+ if (line.startsWith("diff --git ")) {
365892
+ inDiffHunk = true;
365893
+ continue;
365894
+ }
365895
+ if (!inDiffHunk) continue;
365896
+ if (line.startsWith("+") && !line.startsWith("+++")) {
365897
+ additions++;
365898
+ } else if (line.startsWith("-") && !line.startsWith("---")) {
365899
+ deletions++;
365900
+ }
365901
+ }
365902
+ return { additions, deletions };
365903
+ }
365904
+ function toMatchedPatch(patch5) {
365905
+ return {
365906
+ id: patch5.id,
365907
+ message: patch5.original_message,
365908
+ files: patch5.files,
365909
+ diffstat: parseDiffStat(patch5.patch_content),
365910
+ ...patch5.status ? { status: patch5.status } : {}
365911
+ };
365912
+ }
365913
+ function matchesPatch(patch5, pattern) {
365914
+ const fileMatch = patch5.files.some(
365915
+ (file4) => file4 === pattern || (0, import_minimatch42.minimatch)(file4, pattern)
365916
+ );
365917
+ if (fileMatch) return true;
365918
+ return patch5.original_message.toLowerCase().includes(pattern.toLowerCase());
365919
+ }
365920
+ function buildWarnings(patches) {
365921
+ const warnings = [];
365922
+ for (const patch5 of patches) {
365923
+ if (patch5.status === "resolving") {
365924
+ warnings.push(
365925
+ `patch ${patch5.id} has conflict markers in these files: ${patch5.files.join(", ")}. Run \`git checkout -- <files>\` to restore the generated versions.`
365926
+ );
365927
+ } else if (patch5.status === "unresolved") {
365928
+ warnings.push(
365929
+ `patch ${patch5.id} had unresolved conflicts (files: ${patch5.files.join(", ")}).`
365930
+ );
365931
+ }
365932
+ }
365933
+ return warnings;
365934
+ }
365935
+ var EMPTY_RESULT = {
365936
+ initialized: false,
365937
+ removed: [],
365938
+ remaining: 0,
365939
+ notFound: false,
365940
+ alreadyForgotten: [],
365941
+ totalPatches: 0,
365942
+ warnings: []
365943
+ };
365944
+ function forget(outputDir, options2) {
365532
365945
  const lockManager = new LockfileManager(outputDir);
365533
365946
  if (!lockManager.exists()) {
365534
- return { removed: [], notFound: true };
365947
+ return { ...EMPTY_RESULT };
365535
365948
  }
365536
365949
  const lock = lockManager.read();
365537
- const matchingPatches = lock.patches.filter(
365538
- (patch5) => patch5.files.some((file4) => file4 === filePattern || (0, import_minimatch42.minimatch)(file4, filePattern))
365539
- );
365540
- if (matchingPatches.length === 0) {
365541
- return { removed: [], notFound: true };
365950
+ const totalPatches = lock.patches.length;
365951
+ if (options2?.all) {
365952
+ const removed = lock.patches.map(toMatchedPatch);
365953
+ const warnings = buildWarnings(lock.patches);
365954
+ if (!options2.dryRun) {
365955
+ for (const patch5 of lock.patches) {
365956
+ lockManager.addForgottenHash(patch5.content_hash);
365957
+ }
365958
+ lockManager.clearPatches();
365959
+ lockManager.save();
365960
+ }
365961
+ return {
365962
+ initialized: true,
365963
+ removed,
365964
+ remaining: 0,
365965
+ notFound: false,
365966
+ alreadyForgotten: [],
365967
+ totalPatches,
365968
+ warnings
365969
+ };
365542
365970
  }
365543
- const removed = matchingPatches.map((p10) => ({
365544
- id: p10.id,
365545
- message: p10.original_message,
365546
- files: p10.files
365547
- }));
365548
- if (!options2?.dryRun) {
365549
- for (const patch5 of matchingPatches) {
365550
- lockManager.removePatch(patch5.id);
365971
+ if (options2?.patchIds && options2.patchIds.length > 0) {
365972
+ const removed = [];
365973
+ const alreadyForgotten = [];
365974
+ const patchesToRemove = [];
365975
+ for (const id2 of options2.patchIds) {
365976
+ const patch5 = lock.patches.find((p10) => p10.id === id2);
365977
+ if (patch5) {
365978
+ removed.push(toMatchedPatch(patch5));
365979
+ patchesToRemove.push(patch5);
365980
+ } else {
365981
+ alreadyForgotten.push(id2);
365982
+ }
365551
365983
  }
365552
- lockManager.save();
365984
+ const warnings = buildWarnings(patchesToRemove);
365985
+ if (!options2.dryRun) {
365986
+ for (const patch5 of patchesToRemove) {
365987
+ lockManager.addForgottenHash(patch5.content_hash);
365988
+ lockManager.removePatch(patch5.id);
365989
+ }
365990
+ lockManager.save();
365991
+ }
365992
+ return {
365993
+ initialized: true,
365994
+ removed,
365995
+ remaining: totalPatches - removed.length,
365996
+ notFound: removed.length === 0 && alreadyForgotten.length > 0,
365997
+ alreadyForgotten,
365998
+ totalPatches,
365999
+ warnings
366000
+ };
366001
+ }
366002
+ if (options2?.pattern) {
366003
+ const matched = lock.patches.filter((p10) => matchesPatch(p10, options2.pattern)).map(toMatchedPatch);
366004
+ return {
366005
+ initialized: true,
366006
+ removed: [],
366007
+ remaining: totalPatches,
366008
+ notFound: matched.length === 0,
366009
+ alreadyForgotten: [],
366010
+ totalPatches,
366011
+ warnings: [],
366012
+ matched
366013
+ };
365553
366014
  }
365554
- return { removed, notFound: false };
366015
+ return {
366016
+ initialized: true,
366017
+ removed: [],
366018
+ remaining: totalPatches,
366019
+ notFound: totalPatches === 0,
366020
+ alreadyForgotten: [],
366021
+ totalPatches,
366022
+ warnings: [],
366023
+ matched: lock.patches.map(toMatchedPatch)
366024
+ };
365555
366025
  }
365556
366026
  var import_node_fs52 = require("fs");
365557
366027
  function reset2(outputDir, options2) {
@@ -365667,24 +366137,49 @@ CLI Version: ${options2.cliVersion}`;
365667
366137
  function status(outputDir) {
365668
366138
  const lockManager = new LockfileManager(outputDir);
365669
366139
  if (!lockManager.exists()) {
365670
- return { initialized: false, patches: [], lastGeneration: void 0 };
366140
+ return {
366141
+ initialized: false,
366142
+ generationCount: 0,
366143
+ lastGeneration: void 0,
366144
+ patches: [],
366145
+ unresolvedCount: 0,
366146
+ excludePatterns: []
366147
+ };
365671
366148
  }
365672
366149
  const lock = lockManager.read();
365673
366150
  const patches = lock.patches.map((patch5) => ({
365674
- sha: patch5.original_commit.slice(0, 7),
365675
- author: patch5.original_author.split("<")[0]?.trim() ?? "unknown",
366151
+ id: patch5.id,
366152
+ type: patch5.patch_content.includes("new file mode") ? "added" : "modified",
365676
366153
  message: patch5.original_message,
365677
- files: patch5.files
366154
+ author: patch5.original_author.split("<")[0]?.trim() || "unknown",
366155
+ sha: patch5.original_commit.slice(0, 7),
366156
+ files: patch5.files,
366157
+ fileCount: patch5.files.length,
366158
+ ...patch5.status ? { status: patch5.status } : {}
365678
366159
  }));
366160
+ const unresolvedCount = lock.patches.filter(
366161
+ (p10) => p10.status === "unresolved" || p10.status === "resolving"
366162
+ ).length;
365679
366163
  let lastGeneration;
365680
366164
  const lastGen = lock.generations.find((g19) => g19.commit_sha === lock.current_generation);
365681
366165
  if (lastGen) {
365682
366166
  lastGeneration = {
365683
- sha: lastGen.commit_sha,
365684
- timestamp: lastGen.timestamp
366167
+ sha: lastGen.commit_sha.slice(0, 7),
366168
+ timestamp: lastGen.timestamp,
366169
+ cliVersion: lastGen.cli_version,
366170
+ generatorVersions: lastGen.generator_versions
365685
366171
  };
365686
366172
  }
365687
- return { initialized: true, patches, lastGeneration };
366173
+ const config5 = lockManager.getCustomizationsConfig();
366174
+ const excludePatterns = config5.exclude ?? [];
366175
+ return {
366176
+ initialized: true,
366177
+ generationCount: lock.generations.length,
366178
+ lastGeneration,
366179
+ patches,
366180
+ unresolvedCount,
366181
+ excludePatterns
366182
+ };
365688
366183
  }
365689
366184
  }
365690
366185
  });
@@ -366044,6 +366539,19 @@ var require_pipeline2 = __commonJS({
366044
366539
  }
366045
366540
  });
366046
366541
 
366542
+ // ../../generator-cli/lib/replay/replay-forget.js
366543
+ var require_replay_forget = __commonJS({
366544
+ "../../generator-cli/lib/replay/replay-forget.js"(exports2) {
366545
+ "use strict";
366546
+ Object.defineProperty(exports2, "__esModule", { value: true });
366547
+ exports2.replayForget = replayForget2;
366548
+ var replay_1 = require_dist11();
366549
+ function replayForget2(params2) {
366550
+ return (0, replay_1.forget)(params2.outputDir, params2.options);
366551
+ }
366552
+ }
366553
+ });
366554
+
366047
366555
  // ../../generator-cli/lib/replay/replay-init.js
366048
366556
  var require_replay_init = __commonJS({
366049
366557
  "../../generator-cli/lib/replay/replay-init.js"(exports2) {
@@ -366208,12 +366716,25 @@ var require_replay_resolve = __commonJS({
366208
366716
  }
366209
366717
  });
366210
366718
 
366719
+ // ../../generator-cli/lib/replay/replay-status.js
366720
+ var require_replay_status = __commonJS({
366721
+ "../../generator-cli/lib/replay/replay-status.js"(exports2) {
366722
+ "use strict";
366723
+ Object.defineProperty(exports2, "__esModule", { value: true });
366724
+ exports2.replayStatus = replayStatus2;
366725
+ var replay_1 = require_dist11();
366726
+ function replayStatus2(params2) {
366727
+ return (0, replay_1.status)(params2.outputDir);
366728
+ }
366729
+ }
366730
+ });
366731
+
366211
366732
  // ../../generator-cli/lib/api.js
366212
366733
  var require_api5 = __commonJS({
366213
366734
  "../../generator-cli/lib/api.js"(exports2) {
366214
366735
  "use strict";
366215
366736
  Object.defineProperty(exports2, "__esModule", { value: true });
366216
- exports2.replayRun = exports2.replayResolve = exports2.replayInit = exports2.formatBootstrapSummary = exports2.PostGenerationPipeline = exports2.logReplaySummary = exports2.formatReplayPrBody = exports2.consolePipelineLogger = exports2.githubRelease = exports2.githubPush = exports2.githubPr = exports2.generateReferenceToStream = exports2.generateReference = exports2.generateReadmeToStream = exports2.generateReadme = void 0;
366737
+ exports2.replayStatus = exports2.replayRun = exports2.replayResolve = exports2.replayInit = exports2.formatBootstrapSummary = exports2.replayForget = exports2.PostGenerationPipeline = exports2.logReplaySummary = exports2.formatReplayPrBody = exports2.consolePipelineLogger = exports2.githubRelease = exports2.githubPush = exports2.githubPr = exports2.generateReferenceToStream = exports2.generateReference = exports2.generateReadmeToStream = exports2.generateReadme = void 0;
366217
366738
  var generate_readme_js_1 = require_generate_readme();
366218
366739
  Object.defineProperty(exports2, "generateReadme", { enumerable: true, get: function() {
366219
366740
  return generate_readme_js_1.generateReadme;
@@ -366253,6 +366774,10 @@ var require_api5 = __commonJS({
366253
366774
  Object.defineProperty(exports2, "PostGenerationPipeline", { enumerable: true, get: function() {
366254
366775
  return index_js_1.PostGenerationPipeline;
366255
366776
  } });
366777
+ var replay_forget_js_1 = require_replay_forget();
366778
+ Object.defineProperty(exports2, "replayForget", { enumerable: true, get: function() {
366779
+ return replay_forget_js_1.replayForget;
366780
+ } });
366256
366781
  var replay_init_js_1 = require_replay_init();
366257
366782
  Object.defineProperty(exports2, "formatBootstrapSummary", { enumerable: true, get: function() {
366258
366783
  return replay_init_js_1.formatBootstrapSummary;
@@ -366268,6 +366793,10 @@ var require_api5 = __commonJS({
366268
366793
  Object.defineProperty(exports2, "replayRun", { enumerable: true, get: function() {
366269
366794
  return replay_run_js_1.replayRun;
366270
366795
  } });
366796
+ var replay_status_js_1 = require_replay_status();
366797
+ Object.defineProperty(exports2, "replayStatus", { enumerable: true, get: function() {
366798
+ return replay_status_js_1.replayStatus;
366799
+ } });
366271
366800
  }
366272
366801
  });
366273
366802
 
@@ -546920,11 +547449,19 @@ var DynamicSnippetsConverter = class {
546920
547449
  }
546921
547450
  const scheme = auth8.schemes[0];
546922
547451
  switch (scheme.type) {
546923
- case "basic":
546924
- return dynamic_exports.Auth.basic({
547452
+ case "basic": {
547453
+ const basicAuth = {
546925
547454
  username: this.inflateName(scheme.username),
546926
547455
  password: this.inflateName(scheme.password)
546927
- });
547456
+ };
547457
+ if (scheme.usernameOmit) {
547458
+ basicAuth.usernameOmit = scheme.usernameOmit;
547459
+ }
547460
+ if (scheme.passwordOmit) {
547461
+ basicAuth.passwordOmit = scheme.passwordOmit;
547462
+ }
547463
+ return dynamic_exports.Auth.basic(basicAuth);
547464
+ }
546928
547465
  case "bearer":
546929
547466
  return dynamic_exports.Auth.bearer({
546930
547467
  token: this.inflateName(scheme.token)
@@ -588535,7 +589072,7 @@ var RequestBodyConverter = class extends converters_exports.AbstractConverters.A
588535
589072
  contentType
588536
589073
  });
588537
589074
  if (convertedSchema == null) {
588538
- return void 0;
589075
+ return this.handleSchemalessJsonContent({ contentType, mediaTypeObject });
588539
589076
  }
588540
589077
  const requestBodyTypeShape = convertedSchema.schema?.typeDeclaration.shape;
588541
589078
  if (requestBodyTypeShape?.type === "object") {
@@ -588591,6 +589128,55 @@ var RequestBodyConverter = class extends converters_exports.AbstractConverters.A
588591
589128
  };
588592
589129
  }
588593
589130
  }
589131
+ /**
589132
+ * Handles JSON request bodies that have no schema but DO have native OpenAPI
589133
+ * examples. Creates an unknown-typed reference request body so that examples
589134
+ * are preserved for docs rendering and code snippet generation.
589135
+ */
589136
+ handleSchemalessJsonContent({ contentType, mediaTypeObject }) {
589137
+ const hasExamples = mediaTypeObject.example != null || mediaTypeObject.examples != null && Object.keys(mediaTypeObject.examples).length > 0;
589138
+ if (!hasExamples) {
589139
+ return void 0;
589140
+ }
589141
+ const v2Examples = {
589142
+ userSpecifiedExamples: {},
589143
+ autogeneratedExamples: {}
589144
+ };
589145
+ const examples = this.context.getNamedExamplesFromMediaTypeObject({
589146
+ mediaTypeObject,
589147
+ breadcrumbs: this.breadcrumbs,
589148
+ defaultExampleName: `${[...this.group, this.method].join("_")}_example`
589149
+ });
589150
+ const usedExampleNames = /* @__PURE__ */ new Set();
589151
+ for (const [key2, example] of examples) {
589152
+ const resolvedExample = this.context.resolveExampleWithValue(example);
589153
+ const resolvedExampleObject = this.context.resolveExampleRecursively({
589154
+ example,
589155
+ breadcrumbs: this.breadcrumbs
589156
+ });
589157
+ let exampleName = key2;
589158
+ if (this.context.isExampleWithSummary(resolvedExampleObject)) {
589159
+ const summary = resolvedExampleObject.summary;
589160
+ if (!usedExampleNames.has(summary)) {
589161
+ exampleName = summary;
589162
+ }
589163
+ }
589164
+ usedExampleNames.add(exampleName);
589165
+ if (resolvedExample != null) {
589166
+ v2Examples.userSpecifiedExamples[exampleName] = resolvedExample;
589167
+ }
589168
+ }
589169
+ return {
589170
+ requestBody: HttpRequestBody.reference({
589171
+ contentType,
589172
+ docs: this.description,
589173
+ requestBodyType: TypeReference2.unknown(),
589174
+ v2Examples
589175
+ }),
589176
+ streamRequestBody: void 0,
589177
+ inlinedTypes: {}
589178
+ };
589179
+ }
588594
589180
  handleMultipartContent({ contentType }) {
588595
589181
  const mediaTypeObject = this.mediaType;
588596
589182
  if (mediaTypeObject == null || mediaTypeObject.schema == null) {
@@ -590440,6 +591026,18 @@ var OperationConverter = class _OperationConverter extends AbstractOperationConv
590440
591026
  httpMethod,
590441
591027
  baseUrl
590442
591028
  });
591029
+ if (Object.keys(fernExamples.examples).length === 0 && Object.keys(fernExamples.streamExamples).length === 0) {
591030
+ const nativeExamples = this.synthesizeEndpointExamplesFromNativeRequestBody({
591031
+ httpPath: path97,
591032
+ httpMethod,
591033
+ baseUrl
591034
+ });
591035
+ if (nativeExamples != null) {
591036
+ for (const [name2, example] of Object.entries(nativeExamples)) {
591037
+ fernExamples.examples[name2] = example;
591038
+ }
591039
+ }
591040
+ }
590443
591041
  const endpointLevelSecuritySchemes = new Set(this.operation.security?.flatMap((securityRequirement) => Object.keys(securityRequirement)) ?? []);
590444
591042
  const securityHeaders = this.authSchemeToHeaders(Array.from(endpointLevelSecuritySchemes));
590445
591043
  if (securityHeaders.length > 0) {
@@ -590876,6 +591474,107 @@ var OperationConverter = class _OperationConverter extends AbstractOperationConv
590876
591474
  streamExamples: {}
590877
591475
  };
590878
591476
  }
591477
+ /**
591478
+ * Synthesizes endpoint-level v2Examples from native OpenAPI request body
591479
+ * examples (mediaType.example / mediaType.examples) when no x-fern-examples
591480
+ * or x-code-samples extensions are present.
591481
+ *
591482
+ * This ensures that specs like Close's, which have native examples on
591483
+ * schemaless request bodies, get rendered in docs and code snippets.
591484
+ *
591485
+ * Also extracts native response examples from the operation's successful (2xx)
591486
+ * responses so that the 200 response panel is preserved in docs.
591487
+ */
591488
+ synthesizeEndpointExamplesFromNativeRequestBody({ httpPath, httpMethod, baseUrl }) {
591489
+ if (this.operation.requestBody == null) {
591490
+ return void 0;
591491
+ }
591492
+ const resolvedRequestBody = this.context.resolveMaybeReference({
591493
+ schemaOrReference: this.operation.requestBody,
591494
+ breadcrumbs: [...this.breadcrumbs, "requestBody"]
591495
+ });
591496
+ if (resolvedRequestBody == null) {
591497
+ return void 0;
591498
+ }
591499
+ const responseExample = this.extractNativeResponseExample();
591500
+ const result = {};
591501
+ for (const [, mediaType] of Object.entries(resolvedRequestBody.content)) {
591502
+ if (mediaType.schema != null) {
591503
+ continue;
591504
+ }
591505
+ const namedExamples = this.context.getNamedExamplesFromMediaTypeObject({
591506
+ mediaTypeObject: mediaType,
591507
+ breadcrumbs: [...this.breadcrumbs, "requestBody"],
591508
+ defaultExampleName: "Example"
591509
+ });
591510
+ for (const [name2, example] of namedExamples) {
591511
+ const resolvedValue = this.context.resolveExampleWithValue(example);
591512
+ if (resolvedValue != null) {
591513
+ result[name2] = {
591514
+ displayName: void 0,
591515
+ request: {
591516
+ docs: void 0,
591517
+ endpoint: {
591518
+ method: httpMethod,
591519
+ path: this.buildExamplePath(httpPath, {})
591520
+ },
591521
+ baseUrl: void 0,
591522
+ environment: baseUrl,
591523
+ auth: void 0,
591524
+ pathParameters: {},
591525
+ queryParameters: {},
591526
+ headers: {},
591527
+ requestBody: resolvedValue
591528
+ },
591529
+ response: responseExample,
591530
+ codeSamples: void 0
591531
+ };
591532
+ }
591533
+ }
591534
+ }
591535
+ return Object.keys(result).length > 0 ? result : void 0;
591536
+ }
591537
+ /**
591538
+ * Extracts the first native example from the operation's successful (2xx) response.
591539
+ * This is used to populate the response body in synthesized endpoint examples
591540
+ * so that the 200 response panel is preserved in docs.
591541
+ */
591542
+ extractNativeResponseExample() {
591543
+ if (this.operation.responses == null) {
591544
+ return void 0;
591545
+ }
591546
+ for (const [statusCode, response] of Object.entries(this.operation.responses)) {
591547
+ const statusCodeNum = parseInt(statusCode);
591548
+ if (isNaN(statusCodeNum) || statusCodeNum < 200 || statusCodeNum >= 300) {
591549
+ continue;
591550
+ }
591551
+ const resolvedResponse = this.context.resolveMaybeReference({
591552
+ schemaOrReference: response,
591553
+ breadcrumbs: [...this.breadcrumbs, "responses", statusCode]
591554
+ });
591555
+ if (resolvedResponse?.content == null) {
591556
+ continue;
591557
+ }
591558
+ for (const [, responseMediaType] of Object.entries(resolvedResponse.content)) {
591559
+ const namedExamples = this.context.getNamedExamplesFromMediaTypeObject({
591560
+ mediaTypeObject: responseMediaType,
591561
+ breadcrumbs: [...this.breadcrumbs, "responses", statusCode],
591562
+ defaultExampleName: "Example"
591563
+ });
591564
+ for (const [, example] of namedExamples) {
591565
+ const resolvedValue = this.context.resolveExampleWithValue(example);
591566
+ if (resolvedValue != null) {
591567
+ return {
591568
+ docs: void 0,
591569
+ statusCode: statusCodeNum,
591570
+ body: api_exports.V2HttpEndpointResponseBody.json(resolvedValue)
591571
+ };
591572
+ }
591573
+ }
591574
+ }
591575
+ }
591576
+ return void 0;
591577
+ }
590879
591578
  convertStreamConditionExamples({ httpPath, httpMethod, baseUrl, fernExamples }) {
590880
591579
  const filteredJsonExamples = fernExamples.filter((example) => !(example.response != null && "stream" in example.response));
590881
591580
  const filteredStreamExamples = fernExamples.filter((example) => example.response != null && "stream" in example.response);
@@ -602754,7 +603453,7 @@ var AccessTokenPosthogManager = class {
602754
603453
  properties: {
602755
603454
  ...event,
602756
603455
  ...event.properties,
602757
- version: "4.62.3-3-g2870783b556",
603456
+ version: "4.62.3-30-g41b622156cc",
602758
603457
  usingAccessToken: true
602759
603458
  }
602760
603459
  });
@@ -602805,7 +603504,7 @@ var UserPosthogManager = class {
602805
603504
  distinctId: this.userId ?? await this.getPersistedDistinctId(),
602806
603505
  event: "CLI",
602807
603506
  properties: {
602808
- version: "4.62.3-3-g2870783b556",
603507
+ version: "4.62.3-30-g41b622156cc",
602809
603508
  ...event,
602810
603509
  ...event.properties,
602811
603510
  usingAccessToken: false,
@@ -622192,7 +622891,7 @@ function getClientOptions(options2, getDefaultIntegrationsImpl) {
622192
622891
  const tracesSampleRate = getTracesSampleRate(options2.tracesSampleRate);
622193
622892
  const mergedOptions = {
622194
622893
  ...options2,
622195
- dsn: options2.dsn ?? "https://84f58b5e457f06999d92f11ce4b79158@o4509504076185600.ingest.us.sentry.io/4511021546602496",
622894
+ dsn: options2.dsn ?? "",
622196
622895
  environment: options2.environment ?? "development",
622197
622896
  sendClientReports: options2.sendClientReports ?? true,
622198
622897
  transport: options2.transport ?? makeNodeTransport,
@@ -626786,7 +627485,7 @@ var TelemetryClient = class {
626786
627485
  usingAccessToken: process.env.FERN_TOKEN != null
626787
627486
  };
626788
627487
  this.posthog = apiKey != null && apiKey.length > 0 && isTelemetryEnabled ? new PostHog(apiKey) : void 0;
626789
- const sentryDsn = "https://84f58b5e457f06999d92f11ce4b79158@o4509504076185600.ingest.us.sentry.io/4511021546602496";
627488
+ const sentryDsn = "";
626790
627489
  if (sentryDsn != null && sentryDsn.length > 0 && isTelemetryEnabled) {
626791
627490
  const sentryEnvironment = "development";
626792
627491
  if (sentryEnvironment == null || sentryEnvironment.length === 0) {
@@ -752793,7 +753492,7 @@ var V66_TO_V65_MIGRATION = {
752793
753492
  [GeneratorName.JAVA_SDK]: GeneratorWasNeverUpdatedToConsumeNewIR,
752794
753493
  [GeneratorName.JAVA_SPRING]: GeneratorWasNeverUpdatedToConsumeNewIR,
752795
753494
  [GeneratorName.OPENAPI_PYTHON_CLIENT]: GeneratorWasNeverUpdatedToConsumeNewIR,
752796
- [GeneratorName.OPENAPI]: GeneratorWasNeverUpdatedToConsumeNewIR,
753495
+ [GeneratorName.OPENAPI]: "0.4.0-rc.0",
752797
753496
  [GeneratorName.PYTHON_FASTAPI]: GeneratorWasNeverUpdatedToConsumeNewIR,
752798
753497
  [GeneratorName.PYTHON_PYDANTIC]: GeneratorWasNeverUpdatedToConsumeNewIR,
752799
753498
  [GeneratorName.PYTHON_SDK]: GeneratorWasNeverUpdatedToConsumeNewIR,
@@ -752808,8 +753507,8 @@ var V66_TO_V65_MIGRATION = {
752808
753507
  [GeneratorName.SWIFT_SDK]: GeneratorWasNeverUpdatedToConsumeNewIR,
752809
753508
  [GeneratorName.PHP_MODEL]: "0.1.0-rc.0",
752810
753509
  [GeneratorName.PHP_SDK]: "2.3.2-rc.0",
752811
- [GeneratorName.RUST_MODEL]: GeneratorWasNeverUpdatedToConsumeNewIR,
752812
- [GeneratorName.RUST_SDK]: GeneratorWasNeverUpdatedToConsumeNewIR
753510
+ [GeneratorName.RUST_MODEL]: "0.5.0-rc.0",
753511
+ [GeneratorName.RUST_SDK]: "0.32.0-rc.0"
752813
753512
  },
752814
753513
  jsonifyEarlierVersion: (ir15) => IrSerialization_exports.V65.IntermediateRepresentation.jsonOrThrow(ir15, {
752815
753514
  unrecognizedObjectKeys: "passthrough",
@@ -756093,7 +756792,7 @@ function addLogoutCommand(cli) {
756093
756792
 
756094
756793
  // ../cli-v2/lib/constants.js
756095
756794
  var FERN_TOKEN_ENV_VAR2 = "FERN_TOKEN";
756096
- var FETCH_API_SPEC_REQUEST_TIMEOUT_MS = 3e3;
756795
+ var FETCH_API_SPEC_REQUEST_TIMEOUT_MS = 3e4;
756097
756796
  var GENERATE_COMMAND_TIMEOUT_MS = 10 * 60 * 1e3;
756098
756797
 
756099
756798
  // ../cli-v2/lib/commands/auth/status/command.js
@@ -840101,7 +840800,7 @@ var import_path54 = __toESM(require("path"), 1);
840101
840800
  var LOCAL_STORAGE_FOLDER4 = ".fern-dev";
840102
840801
  var LOGS_FOLDER_NAME = "logs";
840103
840802
  function getCliSource() {
840104
- const version7 = "4.62.3-3-g2870783b556";
840803
+ const version7 = "4.62.3-30-g41b622156cc";
840105
840804
  return `cli@${version7}`;
840106
840805
  }
840107
840806
  var DebugLogger = class {
@@ -851209,7 +851908,7 @@ var LegacyDocsPublisher = class {
851209
851908
  previewId,
851210
851909
  disableTemplates: void 0,
851211
851910
  skipUpload,
851212
- cliVersion: "4.62.3-3-g2870783b556"
851911
+ cliVersion: "4.62.3-30-g41b622156cc"
851213
851912
  });
851214
851913
  if (taskContext.getResult() === TaskResult.Failure) {
851215
851914
  return { success: false };
@@ -872469,16 +873168,23 @@ var EndpointSnippetGenerator2 = class extends WithGeneration {
872469
873168
  this.context.errors.add({ severity: Severity.Warning, message });
872470
873169
  }
872471
873170
  getConstructorBasicAuthArg({ auth: auth8, values: values2 }) {
872472
- return [
872473
- {
873171
+ const authRecord = auth8;
873172
+ const usernameOmitted = !!authRecord.usernameOmit;
873173
+ const passwordOmitted = !!authRecord.passwordOmit;
873174
+ const args = [];
873175
+ if (!usernameOmitted) {
873176
+ args.push({
872474
873177
  name: this.context.getParameterName(auth8.username),
872475
873178
  assignment: this.csharp.Literal.string(values2.username)
872476
- },
872477
- {
873179
+ });
873180
+ }
873181
+ if (!passwordOmitted) {
873182
+ args.push({
872478
873183
  name: this.context.getParameterName(auth8.password),
872479
873184
  assignment: this.csharp.Literal.string(values2.password)
872480
- }
872481
- ];
873185
+ });
873186
+ }
873187
+ return args;
872482
873188
  }
872483
873189
  getConstructorBearerAuthArgs({ auth: auth8, values: values2 }) {
872484
873190
  return [
@@ -923948,7 +924654,7 @@ var SentryClient = class {
923948
924654
  sentry;
923949
924655
  constructor({ release: release2 }) {
923950
924656
  const isTelemetryEnabled = process.env.FERN_DISABLE_TELEMETRY !== "true";
923951
- const sentryDsn = "https://84f58b5e457f06999d92f11ce4b79158@o4509504076185600.ingest.us.sentry.io/4511021546602496";
924657
+ const sentryDsn = "";
923952
924658
  if (isTelemetryEnabled && sentryDsn != null && sentryDsn.length > 0) {
923953
924659
  const sentryEnvironment = "development";
923954
924660
  if (sentryEnvironment == null || sentryEnvironment.length === 0) {
@@ -924509,7 +925215,7 @@ var CliContext = class {
924509
925215
  if (false) {
924510
925216
  this.logger.error("CLI_VERSION is not defined");
924511
925217
  }
924512
- return "4.62.3-3-g2870783b556";
925218
+ return "4.62.3-30-g41b622156cc";
924513
925219
  }
924514
925220
  getCliName() {
924515
925221
  if (false) {
@@ -944317,6 +945023,8 @@ function addReplayCommand(cli, cliContext) {
944317
945023
  builder: (yargs) => {
944318
945024
  addReplayInitCommand(yargs, cliContext);
944319
945025
  addReplayResolveCommand(yargs, cliContext);
945026
+ addReplayStatusCommand(yargs, cliContext);
945027
+ addReplayForgetCommand(yargs, cliContext);
944320
945028
  return yargs;
944321
945029
  },
944322
945030
  handler: () => {
@@ -944507,6 +945215,211 @@ Resolve the conflicts in your editor, then run \`fern replay resolve\` again to
944507
945215
  }
944508
945216
  );
944509
945217
  }
945218
+ function addReplayStatusCommand(cli, cliContext) {
945219
+ cli.command(
945220
+ "status [directory]",
945221
+ false,
945222
+ // hidden from --help
945223
+ (yargs) => yargs.positional("directory", {
945224
+ type: "string",
945225
+ default: ".",
945226
+ description: "SDK directory containing .fern/replay.lock"
945227
+ }).option("verbose", {
945228
+ type: "boolean",
945229
+ alias: "v",
945230
+ default: false,
945231
+ description: "Show all patches with full details"
945232
+ }),
945233
+ async (argv) => {
945234
+ await cliContext.instrumentPostHogEvent({
945235
+ command: "fern replay status"
945236
+ });
945237
+ const outputDir = resolve5(cwd(), argv.directory ?? ".");
945238
+ try {
945239
+ const result = (0, import_generator_cli2.replayStatus)({ outputDir });
945240
+ if (!result.initialized) {
945241
+ cliContext.logger.info("Replay is not initialized. Run `fern replay init` to get started.");
945242
+ return;
945243
+ }
945244
+ cliContext.logger.info(
945245
+ `Replay: ${result.patches.length} customization(s) tracked, ${result.generationCount} generation(s)`
945246
+ );
945247
+ if (result.lastGeneration) {
945248
+ cliContext.logger.info(
945249
+ `Last generation: ${result.lastGeneration.sha} (${result.lastGeneration.timestamp})`
945250
+ );
945251
+ }
945252
+ if (result.patches.length === 0) {
945253
+ cliContext.logger.info("No customizations tracked.");
945254
+ return;
945255
+ }
945256
+ const patchesToShow = argv.verbose ? result.patches : result.patches.slice(0, 10);
945257
+ for (const patch5 of patchesToShow) {
945258
+ const statusTag = patch5.status ? ` [${patch5.status}]` : "";
945259
+ if (argv.verbose) {
945260
+ cliContext.logger.info(
945261
+ `
945262
+ ${patch5.id} (${patch5.type})${statusTag}
945263
+ ${patch5.message}
945264
+ Author: ${patch5.author} (${patch5.sha})
945265
+ Files (${patch5.fileCount}): ${patch5.files.join(", ")}`
945266
+ );
945267
+ } else {
945268
+ cliContext.logger.info(
945269
+ ` ${patch5.id}: ${patch5.message} (${patch5.fileCount} file(s))${statusTag}`
945270
+ );
945271
+ }
945272
+ }
945273
+ if (!argv.verbose && result.patches.length > 10) {
945274
+ cliContext.logger.info(` ... and ${result.patches.length - 10} more (use --verbose to see all)`);
945275
+ }
945276
+ if (result.unresolvedCount > 0) {
945277
+ cliContext.logger.warn(
945278
+ `
945279
+ ${result.unresolvedCount} patch(es) have unresolved conflicts. Run \`fern replay resolve\` to fix.`
945280
+ );
945281
+ }
945282
+ if (result.excludePatterns.length > 0) {
945283
+ cliContext.logger.info(`
945284
+ Exclude patterns: ${result.excludePatterns.join(", ")}`);
945285
+ }
945286
+ } catch (error50) {
945287
+ cliContext.failAndThrow(`Failed to get Replay status: ${extractErrorMessage(error50)}`);
945288
+ }
945289
+ }
945290
+ );
945291
+ }
945292
+ function addReplayForgetCommand(cli, cliContext) {
945293
+ cli.command(
945294
+ "forget [args..]",
945295
+ false,
945296
+ // hidden from --help
945297
+ (yargs) => yargs.positional("args", {
945298
+ type: "string",
945299
+ array: true,
945300
+ description: "Patch IDs (e.g. patch-abc12345) or a search pattern"
945301
+ }).option("dry-run", {
945302
+ type: "boolean",
945303
+ default: false,
945304
+ description: "Show what would be removed without actually removing"
945305
+ }).option("yes", {
945306
+ type: "boolean",
945307
+ alias: "y",
945308
+ default: false,
945309
+ description: "Skip confirmation prompts"
945310
+ }).option("all", {
945311
+ type: "boolean",
945312
+ default: false,
945313
+ description: "Remove all tracked patches"
945314
+ }),
945315
+ async (argv) => {
945316
+ await cliContext.instrumentPostHogEvent({
945317
+ command: "fern replay forget"
945318
+ });
945319
+ const outputDir = resolve5(cwd(), ".");
945320
+ const args = argv.args ?? [];
945321
+ const dryRun = argv.dryRun;
945322
+ try {
945323
+ if (argv.all) {
945324
+ const result2 = (0, import_generator_cli2.replayForget)({ outputDir, options: { all: true, dryRun } });
945325
+ if (!result2.initialized) {
945326
+ cliContext.logger.info("Replay is not initialized. Nothing to forget.");
945327
+ return;
945328
+ }
945329
+ if (result2.removed.length === 0) {
945330
+ cliContext.logger.info("No patches to remove.");
945331
+ return;
945332
+ }
945333
+ if (dryRun) {
945334
+ cliContext.logger.info(`Would remove ${result2.removed.length} patch(es):`);
945335
+ } else {
945336
+ cliContext.logger.info(`Removed ${result2.removed.length} patch(es):`);
945337
+ }
945338
+ for (const patch5 of result2.removed) {
945339
+ cliContext.logger.info(` ${patch5.id}: ${patch5.message}`);
945340
+ }
945341
+ for (const warning of result2.warnings) {
945342
+ cliContext.logger.warn(warning);
945343
+ }
945344
+ return;
945345
+ }
945346
+ if (args.length > 0 && args.every((a10) => a10.startsWith("patch-"))) {
945347
+ const result2 = (0, import_generator_cli2.replayForget)({ outputDir, options: { patchIds: args, dryRun } });
945348
+ if (!result2.initialized) {
945349
+ cliContext.logger.info("Replay is not initialized. Nothing to forget.");
945350
+ return;
945351
+ }
945352
+ if (result2.removed.length > 0) {
945353
+ const verb = dryRun ? "Would remove" : "Removed";
945354
+ for (const patch5 of result2.removed) {
945355
+ cliContext.logger.info(`${verb}: ${patch5.id} \u2014 ${patch5.message}`);
945356
+ }
945357
+ }
945358
+ for (const id2 of result2.alreadyForgotten) {
945359
+ cliContext.logger.info(`Already forgotten: ${id2}`);
945360
+ }
945361
+ for (const warning of result2.warnings) {
945362
+ cliContext.logger.warn(warning);
945363
+ }
945364
+ return;
945365
+ }
945366
+ const pattern = args.length === 1 ? args[0] : void 0;
945367
+ const result = (0, import_generator_cli2.replayForget)({ outputDir, options: { pattern } });
945368
+ if (!result.initialized) {
945369
+ cliContext.logger.info("Replay is not initialized. Nothing to forget.");
945370
+ return;
945371
+ }
945372
+ const matched = result.matched ?? [];
945373
+ if (matched.length === 0) {
945374
+ if (pattern) {
945375
+ cliContext.logger.info(`No patches matching "${pattern}".`);
945376
+ } else {
945377
+ cliContext.logger.info("No patches tracked.");
945378
+ }
945379
+ return;
945380
+ }
945381
+ cliContext.logger.info(`${matched.length} patch(es) matched:`);
945382
+ for (const patch5 of matched) {
945383
+ const stat6 = `+${patch5.diffstat.additions}/-${patch5.diffstat.deletions}`;
945384
+ cliContext.logger.info(` ${patch5.id}: ${patch5.message} (${stat6})`);
945385
+ }
945386
+ if (dryRun) {
945387
+ cliContext.logger.info("\nDry run \u2014 no patches removed.");
945388
+ return;
945389
+ }
945390
+ if (!argv.yes) {
945391
+ if (!process.stdout.isTTY) {
945392
+ cliContext.failAndThrow(
945393
+ "Confirmation required. Use --yes to skip confirmation in non-interactive mode."
945394
+ );
945395
+ return;
945396
+ }
945397
+ const readline7 = await import("readline");
945398
+ const rl3 = readline7.createInterface({ input: process.stdin, output: process.stderr });
945399
+ const answer = await new Promise((resolvePrompt) => {
945400
+ rl3.question(`
945401
+ Remove ${matched.length} patch(es)? [y/N] `, resolvePrompt);
945402
+ });
945403
+ rl3.close();
945404
+ if (answer.toLowerCase() !== "y") {
945405
+ cliContext.logger.info("Cancelled.");
945406
+ return;
945407
+ }
945408
+ }
945409
+ const patchIds = matched.map((p10) => p10.id);
945410
+ const removeResult = (0, import_generator_cli2.replayForget)({ outputDir, options: { patchIds, dryRun: false } });
945411
+ cliContext.logger.info(
945412
+ `Removed ${removeResult.removed.length} patch(es). ${removeResult.remaining} remaining.`
945413
+ );
945414
+ for (const warning of removeResult.warnings) {
945415
+ cliContext.logger.warn(warning);
945416
+ }
945417
+ } catch (error50) {
945418
+ cliContext.failAndThrow(`Failed to forget patches: ${extractErrorMessage(error50)}`);
945419
+ }
945420
+ }
945421
+ );
945422
+ }
944510
945423
  function parseOwnerRepo(githubRepo) {
944511
945424
  const cleaned = githubRepo.replace(/^https?:\/\//, "").replace(/\.git$/, "").replace(/^github\.com\//, "");
944512
945425
  const parts = cleaned.split("/");