@fern-api/fern-api-dev 5.23.3-664-g6ef41bc5988 → 5.23.3-665-g0932ac24e1f

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 +120 -39
  2. package/package.json +1 -1
package/cli.cjs CHANGED
@@ -428332,9 +428332,9 @@ var require_diff3 = __commonJS({
428332
428332
  }
428333
428333
  });
428334
428334
 
428335
- // ../../../node_modules/.pnpm/@fern-api+replay@0.16.2/node_modules/@fern-api/replay/dist/index.cjs
428335
+ // ../../../node_modules/.pnpm/@fern-api+replay@0.18.0/node_modules/@fern-api/replay/dist/index.cjs
428336
428336
  var require_dist24 = __commonJS({
428337
- "../../../node_modules/.pnpm/@fern-api+replay@0.16.2/node_modules/@fern-api/replay/dist/index.cjs"(exports2, module4) {
428337
+ "../../../node_modules/.pnpm/@fern-api+replay@0.18.0/node_modules/@fern-api/replay/dist/index.cjs"(exports2, module4) {
428338
428338
  "use strict";
428339
428339
  var __defProp4 = Object.defineProperty;
428340
428340
  var __getOwnPropDesc3 = Object.getOwnPropertyDescriptor;
@@ -428388,6 +428388,11 @@ var require_dist24 = __commonJS({
428388
428388
  proc2.stderr.on("data", (data2) => {
428389
428389
  stderr += data2.toString();
428390
428390
  });
428391
+ proc2.on("error", (err) => {
428392
+ reject(new Error(`git ${args.join(" ")} failed to spawn: ${err.message}`));
428393
+ });
428394
+ proc2.stdin.on("error", () => {
428395
+ });
428391
428396
  proc2.on("close", (code5) => {
428392
428397
  if (code5 === 0) {
428393
428398
  resolve22(stdout);
@@ -429171,7 +429176,8 @@ var require_dist24 = __commonJS({
429171
429176
  var INFRASTRUCTURE_FILES = /* @__PURE__ */ new Set([".fernignore"]);
429172
429177
  function matchesFernignorePattern(filePath, patterns) {
429173
429178
  if (patterns.length === 0) return false;
429174
- return patterns.some((p14) => {
429179
+ return patterns.some((rawPattern) => {
429180
+ const p14 = rawPattern.endsWith("/") ? rawPattern.slice(0, -1) : rawPattern;
429175
429181
  if (filePath === p14) return true;
429176
429182
  if ((0, import_minimatch22.minimatch)(filePath, p14)) return true;
429177
429183
  if (!p14.includes("*") && !p14.includes("?") && filePath.startsWith(p14 + "/")) return true;
@@ -429271,6 +429277,22 @@ var require_dist24 = __commonJS({
429271
429277
  return commit.sha;
429272
429278
  }
429273
429279
  }
429280
+ let fullLog;
429281
+ try {
429282
+ fullLog = await this.git.exec([
429283
+ "log",
429284
+ "--no-merges",
429285
+ "--format=%H%x00%an%x00%ae%x00%s",
429286
+ "HEAD"
429287
+ ]);
429288
+ } catch {
429289
+ return null;
429290
+ }
429291
+ for (const commit of this.parseGitLog(fullLog)) {
429292
+ if (isGenerationBoundary(commit)) {
429293
+ return commit.sha;
429294
+ }
429295
+ }
429274
429296
  return null;
429275
429297
  }
429276
429298
  async detectNewPatches() {
@@ -429282,6 +429304,11 @@ var require_dist24 = __commonJS({
429282
429304
  }
429283
429305
  const lastGen = this.getLastGeneration(lock);
429284
429306
  if (!lastGen) {
429307
+ if (lock.current_generation) {
429308
+ this.warnings.push(
429309
+ `No generation boundary found in git history and the lockfile's recorded generation (${lock.current_generation.slice(0, 7)}) matches no entry in its generation records. Customer customizations may differ from the last known generation and could be lost on the next regeneration. Run \`fern-replay bootstrap --force\` to re-initialize tracking.`
429310
+ );
429311
+ }
429285
429312
  return { patches: [], revertedPatchIds: [] };
429286
429313
  }
429287
429314
  const exists2 = await this.git.commitExists(lastGen.commit_sha);
@@ -429329,20 +429356,15 @@ var require_dist24 = __commonJS({
429329
429356
  continue;
429330
429357
  }
429331
429358
  const parents = await this.git.getCommitParents(commit.sha);
429332
- let patchContent;
429359
+ let filesOutput;
429333
429360
  try {
429334
- patchContent = await this.git.formatPatch(commit.sha);
429361
+ filesOutput = await this.git.exec(["diff-tree", "--no-commit-id", "--name-only", "-r", commit.sha]);
429335
429362
  } catch {
429336
429363
  this.warnings.push(
429337
429364
  `Could not generate patch for commit ${commit.sha.slice(0, 7)} \u2014 it may be unreachable in a shallow clone. Skipping.`
429338
429365
  );
429339
429366
  continue;
429340
429367
  }
429341
- let contentHash = this.computeContentHash(patchContent);
429342
- if (lock.patches.find((p14) => p14.content_hash === contentHash) || forgottenHashes.has(contentHash)) {
429343
- continue;
429344
- }
429345
- const filesOutput = await this.git.exec(["diff-tree", "--no-commit-id", "--name-only", "-r", commit.sha]);
429346
429368
  const { files, sensitiveFiles, fernignoredFiles } = filterInfrastructureAndSensitiveFiles(
429347
429369
  filesOutput,
429348
429370
  this.fernignorePatterns
@@ -429357,19 +429379,31 @@ var require_dist24 = __commonJS({
429357
429379
  `.fernignore-protected file(s) excluded from patch for commit ${commit.sha.slice(0, 7)}: ${fernignoredFiles.join(", ")}. These files are managed by .fernignore, not Replay.`
429358
429380
  );
429359
429381
  }
429360
- if ((sensitiveFiles.length > 0 || fernignoredFiles.length > 0) && files.length > 0) {
429361
- const parentSha = parents[0];
429362
- if (parentSha) {
429363
- try {
429364
- patchContent = await this.git.exec(["diff", parentSha, commit.sha, "--", ...files]);
429365
- } catch {
429366
- continue;
429367
- }
429368
- if (!patchContent.trim()) continue;
429369
- contentHash = this.computeContentHash(patchContent);
429382
+ if (files.length === 0) {
429383
+ continue;
429384
+ }
429385
+ const wasFiltered = sensitiveFiles.length > 0 || fernignoredFiles.length > 0;
429386
+ const parentSha = parents[0];
429387
+ let patchContent;
429388
+ if (wasFiltered && parentSha) {
429389
+ try {
429390
+ patchContent = await this.git.exec(["diff", parentSha, commit.sha, "--", ...files]);
429391
+ } catch {
429392
+ continue;
429393
+ }
429394
+ if (!patchContent.trim()) continue;
429395
+ } else {
429396
+ try {
429397
+ patchContent = await this.git.formatPatch(commit.sha);
429398
+ } catch {
429399
+ this.warnings.push(
429400
+ `Could not generate patch for commit ${commit.sha.slice(0, 7)} \u2014 it may be unreachable in a shallow clone. Skipping.`
429401
+ );
429402
+ continue;
429370
429403
  }
429371
429404
  }
429372
- if (files.length === 0) {
429405
+ const contentHash = this.computeContentHash(patchContent);
429406
+ if (lock.patches.find((p14) => p14.content_hash === contentHash) || forgottenHashes.has(contentHash)) {
429373
429407
  continue;
429374
429408
  }
429375
429409
  const theirsSnapshot = await capturePatchSnapshot(this.git, files, commit.sha);
@@ -430028,16 +430062,20 @@ var require_dist24 = __commonJS({
430028
430062
  const oursPath = (0, import_node_path310.join)(outputDir, resolvedPath);
430029
430063
  const ours = await (0, import_promises208.readFile)(oursPath, "utf-8").catch(() => null);
430030
430064
  let ghostTheirs = null;
430031
- if (!base4 && ours && !renameSourcePath) {
430065
+ let baseTreeUnreachable = false;
430066
+ if (!base4 && !renameSourcePath) {
430032
430067
  const treeReachable = await isTreeReachable(baseGen.tree_hash);
430033
430068
  if (!treeReachable) {
430034
- const fileDiff = extractFileDiff2(patch5.patch_content, filePath);
430035
- if (fileDiff) {
430036
- const { reconstructFromGhostPatch: reconstructFromGhostPatch2 } = await Promise.resolve().then(() => (init_HybridReconstruction(), HybridReconstruction_exports));
430037
- const result = reconstructFromGhostPatch2(fileDiff, ours);
430038
- if (result) {
430039
- base4 = result.base;
430040
- ghostTheirs = result.theirs;
430069
+ baseTreeUnreachable = true;
430070
+ if (ours) {
430071
+ const fileDiff = extractFileDiff2(patch5.patch_content, filePath);
430072
+ if (fileDiff) {
430073
+ const { reconstructFromGhostPatch: reconstructFromGhostPatch2 } = await Promise.resolve().then(() => (init_HybridReconstruction(), HybridReconstruction_exports));
430074
+ const result = reconstructFromGhostPatch2(fileDiff, ours);
430075
+ if (result) {
430076
+ base4 = result.base;
430077
+ ghostTheirs = result.theirs;
430078
+ }
430041
430079
  }
430042
430080
  }
430043
430081
  }
@@ -430049,7 +430087,11 @@ var require_dist24 = __commonJS({
430049
430087
  ours,
430050
430088
  oursPath,
430051
430089
  renameSourcePath,
430052
- ghostTheirs
430090
+ ghostTheirs,
430091
+ // Only meaningful when ghost reconstruction did NOT recover a base; if it
430092
+ // did, `base` is non-null and the merge proceeds normally. We still set
430093
+ // the flag truthfully (the tree IS unreachable) so Phase 3 can decide.
430094
+ baseTreeUnreachable
430053
430095
  };
430054
430096
  }
430055
430097
  var CONFLICT_OPENER = "<<<<<<< Generated";
@@ -430228,7 +430270,11 @@ var require_dist24 = __commonJS({
430228
430270
  return { kind: "new-file-only-user", theirs: effective_theirs };
430229
430271
  }
430230
430272
  if (base4 == null && ours != null && effective_theirs != null && !useAccumulatorAsMergeBase) {
430231
- return { kind: "new-file-both", theirs: effective_theirs };
430273
+ return {
430274
+ kind: "new-file-both",
430275
+ theirs: effective_theirs,
430276
+ ...inputs.baseTreeUnreachable ? { baseTreeUnreachable: true } : {}
430277
+ };
430232
430278
  }
430233
430279
  if (effective_theirs == null) {
430234
430280
  return { kind: "skipped", reason: "missing-content" };
@@ -430274,17 +430320,19 @@ var require_dist24 = __commonJS({
430274
430320
  const merged2 = threeWayMerge("", ours, plan.theirs);
430275
430321
  await (0, import_promises210.mkdir)((0, import_node_path44.dirname)(oursPath), { recursive: true });
430276
430322
  await (0, import_promises210.writeFile)(oursPath, merged2.content);
430323
+ const unreachableFlag = plan.baseTreeUnreachable ? { baseTreeUnreachable: true } : {};
430277
430324
  if (merged2.hasConflicts) {
430278
430325
  return {
430279
430326
  file: resolvedPath,
430280
430327
  status: "conflict",
430281
430328
  conflicts: merged2.conflicts,
430282
430329
  conflictReason: "new-file-both",
430283
- conflictMetadata: metadata
430330
+ conflictMetadata: metadata,
430331
+ ...unreachableFlag
430284
430332
  };
430285
430333
  }
430286
430334
  accumulator.recordMerge(resolvedPath, merged2.content, patch5.base_generation);
430287
- return { file: resolvedPath, status: "merged" };
430335
+ return { file: resolvedPath, status: "merged", ...unreachableFlag };
430288
430336
  }
430289
430337
  const merged = threeWayMerge(plan.mergeBase, ours, plan.theirs);
430290
430338
  await (0, import_promises210.mkdir)((0, import_node_path44.dirname)(oursPath), { recursive: true });
@@ -431484,6 +431532,7 @@ Patches absorbed by generator (${buckets.absorbed.length}):`;
431484
431532
  results = await this.service.applicator.applyPatches(newPatches);
431485
431533
  this.service._lastApplyResults = results;
431486
431534
  this.service.recordDroppedContextLineWarnings(results);
431535
+ this.service.recordUnreachableBaseWarnings(results);
431487
431536
  this.service.revertConflictingFiles(results);
431488
431537
  for (const result of results) {
431489
431538
  if (result.status === "conflict") {
@@ -431637,6 +431686,7 @@ Patches absorbed by generator (${buckets.absorbed.length}):`;
431637
431686
  const results = await this.service.applicator.applyPatches(allPatches);
431638
431687
  this.service._lastApplyResults = results;
431639
431688
  this.service.recordDroppedContextLineWarnings(results);
431689
+ this.service.recordUnreachableBaseWarnings(results);
431640
431690
  this.service.revertConflictingFiles(results);
431641
431691
  for (const result of results) {
431642
431692
  if (result.status === "conflict") {
@@ -432554,6 +432604,37 @@ If you want to keep these lines, restore them in a follow-up commit and re-run r
432554
432604
  }
432555
432605
  }
432556
432606
  }
432607
+ /**
432608
+ * After applyPatches(), surface a warning for each (patch × file) where a
432609
+ * customization's BASE could not be read because the patch's
432610
+ * base-generation tree is unreachable in this clone (shallow-clone window
432611
+ * too small / pruned history). In that state the merge pipeline falls
432612
+ * through to `new-file-both` and the customer's edit can be dropped with NO
432613
+ * conflict and NO error — the INC-866 silent-loss class. This converts that
432614
+ * silence into an explicit, actionable warning naming the file and the
432615
+ * likely cause (insufficient clone window).
432616
+ *
432617
+ * Mirrors `recordDroppedContextLineWarnings`'s "surface, never silently
432618
+ * drop" contract. De-duplicated per file path so a single insufficient
432619
+ * window doesn't spam one warning per touched file repeatedly.
432620
+ */
432621
+ /** @internal Used by Flow implementations in `src/flows/`. */
432622
+ recordUnreachableBaseWarnings(results) {
432623
+ const warned2 = /* @__PURE__ */ new Set();
432624
+ for (const result of results) {
432625
+ if (!result.fileResults) continue;
432626
+ for (const fr9 of result.fileResults) {
432627
+ if (!fr9.baseTreeUnreachable) continue;
432628
+ if (warned2.has(fr9.file)) continue;
432629
+ warned2.add(fr9.file);
432630
+ const base4 = fr9.conflictMetadata?.baseGeneration;
432631
+ const baseRef = base4 ? ` (base generation ${base4.slice(0, 7)})` : "";
432632
+ this.warnings.push(
432633
+ `${fr9.file}: could not read the prior generation's version of this file${baseRef} because that generation's tree is outside the clone window (insufficient shallow-clone depth or pruned history). The customization was treated as a new file, which can drop your edits silently. Re-run with the prior generation in the clone window \u2014 e.g. \`git fetch --shallow-since=<date just before the prior [fern-generated] commit>\` or \`git fetch --unshallow\` \u2014 then re-run replay.`
432634
+ );
432635
+ }
432636
+ }
432637
+ }
432557
432638
  /**
432558
432639
  * After applyPatches(), strip conflict markers from conflicting files
432559
432640
  * so only clean content is committed. Keeps the Generated (OURS) side.
@@ -669478,7 +669559,7 @@ var AccessTokenPosthogManager = class {
669478
669559
  properties: {
669479
669560
  ...event,
669480
669561
  ...event.properties,
669481
- version: "5.23.3-664-g6ef41bc5988",
669562
+ version: "5.23.3-665-g0932ac24e1f",
669482
669563
  usingAccessToken: true,
669483
669564
  ...getRunIdProperties()
669484
669565
  }
@@ -669542,7 +669623,7 @@ var UserPosthogManager = class {
669542
669623
  distinctId: this.userId ?? await this.getPersistedDistinctId(),
669543
669624
  event: "CLI",
669544
669625
  properties: {
669545
- version: "5.23.3-664-g6ef41bc5988",
669626
+ version: "5.23.3-665-g0932ac24e1f",
669546
669627
  ...event,
669547
669628
  ...event.properties,
669548
669629
  usingAccessToken: false,
@@ -861280,7 +861361,7 @@ var LOCAL_STORAGE_FOLDER4 = ".fern-dev";
861280
861361
  var LOGS_FOLDER_NAME = "logs";
861281
861362
  var MAX_LOGS_DIR_SIZE_BYTES = 100 * 1024 * 1024;
861282
861363
  function getCliSource() {
861283
- const version7 = "5.23.3-664-g6ef41bc5988";
861364
+ const version7 = "5.23.3-665-g0932ac24e1f";
861284
861365
  return `cli@${version7}`;
861285
861366
  }
861286
861367
  var DebugLogger = class {
@@ -892372,7 +892453,7 @@ var LegacyDocsPublisher = class {
892372
892453
  previewId,
892373
892454
  disableTemplates: void 0,
892374
892455
  skipUpload,
892375
- cliVersion: "5.23.3-664-g6ef41bc5988",
892456
+ cliVersion: "5.23.3-665-g0932ac24e1f",
892376
892457
  loginCommand: "fern auth login"
892377
892458
  });
892378
892459
  if (taskContext.getResult() === TaskResult.Failure) {
@@ -957562,7 +957643,7 @@ function getAutomationContextFromEnv() {
957562
957643
  config_branch: process.env.FERN_CONFIG_BRANCH,
957563
957644
  config_pr_number: process.env.FERN_CONFIG_PR_NUMBER,
957564
957645
  trigger: process.env.GITHUB_EVENT_NAME,
957565
- cli_version: "5.23.3-664-g6ef41bc5988"
957646
+ cli_version: "5.23.3-665-g0932ac24e1f"
957566
957647
  };
957567
957648
  }
957568
957649
  function isAutomationMode() {
@@ -958388,7 +958469,7 @@ var CliContext = class _CliContext {
958388
958469
  if (false) {
958389
958470
  this.logger.error("CLI_VERSION is not defined");
958390
958471
  }
958391
- return "5.23.3-664-g6ef41bc5988";
958472
+ return "5.23.3-665-g0932ac24e1f";
958392
958473
  }
958393
958474
  getCliName() {
958394
958475
  if (false) {
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "5.23.3-664-g6ef41bc5988",
2
+ "version": "5.23.3-665-g0932ac24e1f",
3
3
  "repository": {
4
4
  "type": "git",
5
5
  "url": "git+https://github.com/fern-api/fern.git",