@fern-api/generator-cli 0.10.1 → 0.10.3

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/dist/cli.js +429 -315
  2. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -21964,257 +21964,7 @@ var require_dist3 = __commonJS({
21964
21964
  }
21965
21965
  });
21966
21966
 
21967
- // ../../node_modules/.pnpm/node-diff3@3.2.0/node_modules/node-diff3/dist/diff3.mjs
21968
- function LCS(buffer1, buffer2) {
21969
- let equivalenceClasses = {};
21970
- for (let j2 = 0; j2 < buffer2.length; j2++) {
21971
- const item = buffer2[j2];
21972
- if (equivalenceClasses[item]) {
21973
- equivalenceClasses[item].push(j2);
21974
- } else {
21975
- equivalenceClasses[item] = [j2];
21976
- }
21977
- }
21978
- const NULLRESULT = { buffer1index: -1, buffer2index: -1, chain: null };
21979
- let candidates = [NULLRESULT];
21980
- for (let i2 = 0; i2 < buffer1.length; i2++) {
21981
- const item = buffer1[i2];
21982
- const buffer2indices = equivalenceClasses[item] || [];
21983
- let r2 = 0;
21984
- let c3 = candidates[0];
21985
- for (let jx = 0; jx < buffer2indices.length; jx++) {
21986
- const j2 = buffer2indices[jx];
21987
- let s;
21988
- for (s = r2; s < candidates.length; s++) {
21989
- if (candidates[s].buffer2index < j2 && (s === candidates.length - 1 || candidates[s + 1].buffer2index > j2)) {
21990
- break;
21991
- }
21992
- }
21993
- if (s < candidates.length) {
21994
- const newCandidate = { buffer1index: i2, buffer2index: j2, chain: candidates[s] };
21995
- if (r2 === candidates.length) {
21996
- candidates.push(c3);
21997
- } else {
21998
- candidates[r2] = c3;
21999
- }
22000
- r2 = s + 1;
22001
- c3 = newCandidate;
22002
- if (r2 === candidates.length) {
22003
- break;
22004
- }
22005
- }
22006
- }
22007
- candidates[r2] = c3;
22008
- }
22009
- return candidates[candidates.length - 1];
22010
- }
22011
- function diffIndices(buffer1, buffer2) {
22012
- const lcs = LCS(buffer1, buffer2);
22013
- let result = [];
22014
- let tail1 = buffer1.length;
22015
- let tail2 = buffer2.length;
22016
- for (let candidate = lcs; candidate !== null; candidate = candidate.chain) {
22017
- const mismatchLength1 = tail1 - candidate.buffer1index - 1;
22018
- const mismatchLength2 = tail2 - candidate.buffer2index - 1;
22019
- tail1 = candidate.buffer1index;
22020
- tail2 = candidate.buffer2index;
22021
- if (mismatchLength1 || mismatchLength2) {
22022
- result.push({
22023
- buffer1: [tail1 + 1, mismatchLength1],
22024
- buffer1Content: buffer1.slice(tail1 + 1, tail1 + 1 + mismatchLength1),
22025
- buffer2: [tail2 + 1, mismatchLength2],
22026
- buffer2Content: buffer2.slice(tail2 + 1, tail2 + 1 + mismatchLength2)
22027
- });
22028
- }
22029
- }
22030
- result.reverse();
22031
- return result;
22032
- }
22033
- function diffPatch(buffer1, buffer2) {
22034
- const lcs = LCS(buffer1, buffer2);
22035
- let result = [];
22036
- let tail1 = buffer1.length;
22037
- let tail2 = buffer2.length;
22038
- function chunkDescription(buffer, offset, length) {
22039
- let chunk = [];
22040
- for (let i2 = 0; i2 < length; i2++) {
22041
- chunk.push(buffer[offset + i2]);
22042
- }
22043
- return {
22044
- offset,
22045
- length,
22046
- chunk
22047
- };
22048
- }
22049
- for (let candidate = lcs; candidate !== null; candidate = candidate.chain) {
22050
- const mismatchLength1 = tail1 - candidate.buffer1index - 1;
22051
- const mismatchLength2 = tail2 - candidate.buffer2index - 1;
22052
- tail1 = candidate.buffer1index;
22053
- tail2 = candidate.buffer2index;
22054
- if (mismatchLength1 || mismatchLength2) {
22055
- result.push({
22056
- buffer1: chunkDescription(buffer1, candidate.buffer1index + 1, mismatchLength1),
22057
- buffer2: chunkDescription(buffer2, candidate.buffer2index + 1, mismatchLength2)
22058
- });
22059
- }
22060
- }
22061
- result.reverse();
22062
- return result;
22063
- }
22064
- function diff3MergeRegions(a, o2, b3) {
22065
- let hunks = [];
22066
- function addHunk(h2, ab) {
22067
- hunks.push({
22068
- ab,
22069
- oStart: h2.buffer1[0],
22070
- oLength: h2.buffer1[1],
22071
- abStart: h2.buffer2[0],
22072
- abLength: h2.buffer2[1]
22073
- });
22074
- }
22075
- diffIndices(o2, a).forEach((item) => addHunk(item, "a"));
22076
- diffIndices(o2, b3).forEach((item) => addHunk(item, "b"));
22077
- hunks.sort((x2, y2) => x2.oStart - y2.oStart);
22078
- let results = [];
22079
- let currOffset = 0;
22080
- function advanceTo(endOffset) {
22081
- if (endOffset > currOffset) {
22082
- results.push({
22083
- stable: true,
22084
- buffer: "o",
22085
- bufferStart: currOffset,
22086
- bufferLength: endOffset - currOffset,
22087
- bufferContent: o2.slice(currOffset, endOffset)
22088
- });
22089
- currOffset = endOffset;
22090
- }
22091
- }
22092
- while (hunks.length) {
22093
- let hunk = hunks.shift();
22094
- let regionStart = hunk.oStart;
22095
- let regionEnd = hunk.oStart + hunk.oLength;
22096
- let regionHunks = [hunk];
22097
- advanceTo(regionStart);
22098
- while (hunks.length) {
22099
- const nextHunk = hunks[0];
22100
- const nextHunkStart = nextHunk.oStart;
22101
- if (nextHunkStart > regionEnd)
22102
- break;
22103
- regionEnd = Math.max(regionEnd, nextHunkStart + nextHunk.oLength);
22104
- regionHunks.push(hunks.shift());
22105
- }
22106
- if (regionHunks.length === 1) {
22107
- if (hunk.abLength > 0) {
22108
- const buffer = hunk.ab === "a" ? a : b3;
22109
- results.push({
22110
- stable: true,
22111
- buffer: hunk.ab,
22112
- bufferStart: hunk.abStart,
22113
- bufferLength: hunk.abLength,
22114
- bufferContent: buffer.slice(hunk.abStart, hunk.abStart + hunk.abLength)
22115
- });
22116
- }
22117
- } else {
22118
- let bounds = {
22119
- a: [a.length, -1, o2.length, -1],
22120
- b: [b3.length, -1, o2.length, -1]
22121
- };
22122
- while (regionHunks.length) {
22123
- hunk = regionHunks.shift();
22124
- const oStart = hunk.oStart;
22125
- const oEnd = oStart + hunk.oLength;
22126
- const abStart = hunk.abStart;
22127
- const abEnd = abStart + hunk.abLength;
22128
- let b22 = bounds[hunk.ab];
22129
- b22[0] = Math.min(abStart, b22[0]);
22130
- b22[1] = Math.max(abEnd, b22[1]);
22131
- b22[2] = Math.min(oStart, b22[2]);
22132
- b22[3] = Math.max(oEnd, b22[3]);
22133
- }
22134
- const aStart = bounds.a[0] + (regionStart - bounds.a[2]);
22135
- const aEnd = bounds.a[1] + (regionEnd - bounds.a[3]);
22136
- const bStart = bounds.b[0] + (regionStart - bounds.b[2]);
22137
- const bEnd = bounds.b[1] + (regionEnd - bounds.b[3]);
22138
- let result = {
22139
- stable: false,
22140
- aStart,
22141
- aLength: aEnd - aStart,
22142
- aContent: a.slice(aStart, aEnd),
22143
- oStart: regionStart,
22144
- oLength: regionEnd - regionStart,
22145
- oContent: o2.slice(regionStart, regionEnd),
22146
- bStart,
22147
- bLength: bEnd - bStart,
22148
- bContent: b3.slice(bStart, bEnd)
22149
- };
22150
- results.push(result);
22151
- }
22152
- currOffset = regionEnd;
22153
- }
22154
- advanceTo(o2.length);
22155
- return results;
22156
- }
22157
- function diff3Merge(a, o2, b3, options) {
22158
- let defaults3 = {
22159
- excludeFalseConflicts: true,
22160
- stringSeparator: /\s+/
22161
- };
22162
- options = Object.assign(defaults3, options);
22163
- if (typeof a === "string")
22164
- a = a.split(options.stringSeparator);
22165
- if (typeof o2 === "string")
22166
- o2 = o2.split(options.stringSeparator);
22167
- if (typeof b3 === "string")
22168
- b3 = b3.split(options.stringSeparator);
22169
- let results = [];
22170
- const regions = diff3MergeRegions(a, o2, b3);
22171
- let okBuffer = [];
22172
- function flushOk() {
22173
- if (okBuffer.length) {
22174
- results.push({ ok: okBuffer });
22175
- }
22176
- okBuffer = [];
22177
- }
22178
- function isFalseConflict(a2, b22) {
22179
- if (a2.length !== b22.length)
22180
- return false;
22181
- for (let i2 = 0; i2 < a2.length; i2++) {
22182
- if (a2[i2] !== b22[i2])
22183
- return false;
22184
- }
22185
- return true;
22186
- }
22187
- regions.forEach((region) => {
22188
- if (region.stable) {
22189
- okBuffer.push(...region.bufferContent);
22190
- } else {
22191
- if (options.excludeFalseConflicts && isFalseConflict(region.aContent, region.bContent)) {
22192
- okBuffer.push(...region.aContent);
22193
- } else {
22194
- flushOk();
22195
- results.push({
22196
- conflict: {
22197
- a: region.aContent,
22198
- aIndex: region.aStart,
22199
- o: region.oContent,
22200
- oIndex: region.oStart,
22201
- b: region.bContent,
22202
- bIndex: region.bStart
22203
- }
22204
- });
22205
- }
22206
- }
22207
- });
22208
- flushOk();
22209
- return results;
22210
- }
22211
- var init_diff3 = __esm({
22212
- "../../node_modules/.pnpm/node-diff3@3.2.0/node_modules/node-diff3/dist/diff3.mjs"() {
22213
- "use strict";
22214
- }
22215
- });
22216
-
22217
- // ../../node_modules/.pnpm/@fern-api+replay@0.19.2/node_modules/@fern-api/replay/dist/index.js
21967
+ // ../../node_modules/.pnpm/@fern-api+replay@0.19.3/node_modules/@fern-api/replay/dist/index.js
22218
21968
  var dist_exports = {};
22219
21969
  __export(dist_exports, {
22220
21970
  CREDENTIAL_PATTERNS: () => CREDENTIAL_PATTERNS,
@@ -22633,6 +22383,244 @@ function filterInfrastructureAndSensitiveFiles(rawFilesOutput, fernignorePattern
22633
22383
  const files = nonSensitive.filter((f) => !matchesFernignorePattern(f, fernignorePatterns));
22634
22384
  return { files, sensitiveFiles, fernignoredFiles, infrastructureFiles };
22635
22385
  }
22386
+ function LCS(buffer1, buffer2) {
22387
+ const equivalenceClasses = /* @__PURE__ */ new Map();
22388
+ for (let j2 = 0; j2 < buffer2.length; j2++) {
22389
+ const item = buffer2[j2];
22390
+ const indices = equivalenceClasses.get(item);
22391
+ if (indices != null) {
22392
+ indices.push(j2);
22393
+ } else {
22394
+ equivalenceClasses.set(item, [j2]);
22395
+ }
22396
+ }
22397
+ const nullResult = { buffer1index: -1, buffer2index: -1, chain: null };
22398
+ const candidates = [nullResult];
22399
+ for (let i2 = 0; i2 < buffer1.length; i2++) {
22400
+ const item = buffer1[i2];
22401
+ const buffer2indices = equivalenceClasses.get(item) ?? [];
22402
+ let r2 = 0;
22403
+ let c3 = candidates[0];
22404
+ for (let jx = 0; jx < buffer2indices.length; jx++) {
22405
+ const j2 = buffer2indices[jx];
22406
+ let s = candidates.length;
22407
+ let lo = r2;
22408
+ let hi = candidates.length - 1;
22409
+ let found = -1;
22410
+ while (lo <= hi) {
22411
+ const mid = lo + hi >> 1;
22412
+ if (candidates[mid].buffer2index < j2) {
22413
+ found = mid;
22414
+ lo = mid + 1;
22415
+ } else {
22416
+ hi = mid - 1;
22417
+ }
22418
+ }
22419
+ if (found !== -1 && (found === candidates.length - 1 || candidates[found + 1].buffer2index > j2)) {
22420
+ s = found;
22421
+ }
22422
+ if (s < candidates.length) {
22423
+ const newCandidate = { buffer1index: i2, buffer2index: j2, chain: candidates[s] };
22424
+ if (r2 === candidates.length) {
22425
+ candidates.push(c3);
22426
+ } else {
22427
+ candidates[r2] = c3;
22428
+ }
22429
+ r2 = s + 1;
22430
+ c3 = newCandidate;
22431
+ if (r2 === candidates.length) {
22432
+ break;
22433
+ }
22434
+ }
22435
+ }
22436
+ candidates[r2] = c3;
22437
+ }
22438
+ return candidates[candidates.length - 1];
22439
+ }
22440
+ function diffIndices(buffer1, buffer2) {
22441
+ const lcs = LCS(buffer1, buffer2);
22442
+ const result = [];
22443
+ let tail1 = buffer1.length;
22444
+ let tail2 = buffer2.length;
22445
+ let candidate = lcs;
22446
+ while (candidate !== null) {
22447
+ const mismatchLength1 = tail1 - candidate.buffer1index - 1;
22448
+ const mismatchLength2 = tail2 - candidate.buffer2index - 1;
22449
+ tail1 = candidate.buffer1index;
22450
+ tail2 = candidate.buffer2index;
22451
+ if (mismatchLength1 || mismatchLength2) {
22452
+ result.push({
22453
+ buffer1: [tail1 + 1, mismatchLength1],
22454
+ buffer1Content: buffer1.slice(tail1 + 1, tail1 + 1 + mismatchLength1),
22455
+ buffer2: [tail2 + 1, mismatchLength2],
22456
+ buffer2Content: buffer2.slice(tail2 + 1, tail2 + 1 + mismatchLength2)
22457
+ });
22458
+ }
22459
+ candidate = candidate.chain;
22460
+ }
22461
+ result.reverse();
22462
+ return result;
22463
+ }
22464
+ function diffPatch(buffer1, buffer2) {
22465
+ const lcs = LCS(buffer1, buffer2);
22466
+ const result = [];
22467
+ let tail1 = buffer1.length;
22468
+ let tail2 = buffer2.length;
22469
+ function chunkDescription(buffer, offset, length) {
22470
+ const chunk = [];
22471
+ for (let i2 = 0; i2 < length; i2++) {
22472
+ chunk.push(buffer[offset + i2]);
22473
+ }
22474
+ return {
22475
+ offset,
22476
+ length,
22477
+ chunk
22478
+ };
22479
+ }
22480
+ let candidate = lcs;
22481
+ while (candidate !== null) {
22482
+ const mismatchLength1 = tail1 - candidate.buffer1index - 1;
22483
+ const mismatchLength2 = tail2 - candidate.buffer2index - 1;
22484
+ tail1 = candidate.buffer1index;
22485
+ tail2 = candidate.buffer2index;
22486
+ if (mismatchLength1 || mismatchLength2) {
22487
+ result.push({
22488
+ buffer1: chunkDescription(buffer1, candidate.buffer1index + 1, mismatchLength1),
22489
+ buffer2: chunkDescription(buffer2, candidate.buffer2index + 1, mismatchLength2)
22490
+ });
22491
+ }
22492
+ candidate = candidate.chain;
22493
+ }
22494
+ result.reverse();
22495
+ return result;
22496
+ }
22497
+ function diff3MergeRegions(a, o2, b3) {
22498
+ const hunks = [];
22499
+ function addHunk(h2, ab) {
22500
+ hunks.push({
22501
+ ab,
22502
+ oStart: h2.buffer1[0],
22503
+ oLength: h2.buffer1[1],
22504
+ abStart: h2.buffer2[0],
22505
+ abLength: h2.buffer2[1]
22506
+ });
22507
+ }
22508
+ diffIndices(o2, a).forEach((item) => addHunk(item, "a"));
22509
+ diffIndices(o2, b3).forEach((item) => addHunk(item, "b"));
22510
+ hunks.sort((x2, y2) => x2.oStart - y2.oStart);
22511
+ const results = [];
22512
+ let currOffset = 0;
22513
+ function advanceTo(endOffset) {
22514
+ if (endOffset > currOffset) {
22515
+ results.push({
22516
+ stable: true,
22517
+ bufferContent: o2.slice(currOffset, endOffset)
22518
+ });
22519
+ currOffset = endOffset;
22520
+ }
22521
+ }
22522
+ while (hunks.length) {
22523
+ const firstHunk = hunks.shift();
22524
+ if (firstHunk === void 0) break;
22525
+ let hunk = firstHunk;
22526
+ const regionStart = hunk.oStart;
22527
+ let regionEnd = hunk.oStart + hunk.oLength;
22528
+ const regionHunks = [hunk];
22529
+ advanceTo(regionStart);
22530
+ while (hunks.length) {
22531
+ const nextHunk = hunks[0];
22532
+ const nextHunkStart = nextHunk.oStart;
22533
+ if (nextHunkStart > regionEnd) break;
22534
+ regionEnd = Math.max(regionEnd, nextHunkStart + nextHunk.oLength);
22535
+ const next = hunks.shift();
22536
+ if (next === void 0) break;
22537
+ regionHunks.push(next);
22538
+ }
22539
+ if (regionHunks.length === 1) {
22540
+ if (hunk.abLength > 0) {
22541
+ const buffer = hunk.ab === "a" ? a : b3;
22542
+ results.push({
22543
+ stable: true,
22544
+ bufferContent: buffer.slice(hunk.abStart, hunk.abStart + hunk.abLength)
22545
+ });
22546
+ }
22547
+ } else {
22548
+ const bounds = {
22549
+ a: [a.length, -1, o2.length, -1],
22550
+ b: [b3.length, -1, o2.length, -1]
22551
+ };
22552
+ while (regionHunks.length) {
22553
+ const next = regionHunks.shift();
22554
+ if (next === void 0) break;
22555
+ hunk = next;
22556
+ const oStart = hunk.oStart;
22557
+ const oEnd = oStart + hunk.oLength;
22558
+ const abStart = hunk.abStart;
22559
+ const abEnd = abStart + hunk.abLength;
22560
+ const bound = bounds[hunk.ab];
22561
+ bound[0] = Math.min(abStart, bound[0]);
22562
+ bound[1] = Math.max(abEnd, bound[1]);
22563
+ bound[2] = Math.min(oStart, bound[2]);
22564
+ bound[3] = Math.max(oEnd, bound[3]);
22565
+ }
22566
+ const aStart = bounds.a[0] + (regionStart - bounds.a[2]);
22567
+ const aEnd = bounds.a[1] + (regionEnd - bounds.a[3]);
22568
+ const bStart = bounds.b[0] + (regionStart - bounds.b[2]);
22569
+ const bEnd = bounds.b[1] + (regionEnd - bounds.b[3]);
22570
+ results.push({
22571
+ stable: false,
22572
+ aStart,
22573
+ aContent: a.slice(aStart, aEnd),
22574
+ oStart: regionStart,
22575
+ oContent: o2.slice(regionStart, regionEnd),
22576
+ bStart,
22577
+ bContent: b3.slice(bStart, bEnd)
22578
+ });
22579
+ }
22580
+ currOffset = regionEnd;
22581
+ }
22582
+ advanceTo(o2.length);
22583
+ return results;
22584
+ }
22585
+ function diff3Merge(a, o2, b3) {
22586
+ const regions = diff3MergeRegions(a, o2, b3);
22587
+ const results = [];
22588
+ let okBuffer = [];
22589
+ function flushOk() {
22590
+ if (okBuffer.length) {
22591
+ results.push({ ok: okBuffer });
22592
+ }
22593
+ okBuffer = [];
22594
+ }
22595
+ function isFalseConflict(left2, right2) {
22596
+ if (left2.length !== right2.length) return false;
22597
+ for (let i2 = 0; i2 < left2.length; i2++) {
22598
+ if (left2[i2] !== right2[i2]) return false;
22599
+ }
22600
+ return true;
22601
+ }
22602
+ regions.forEach((region) => {
22603
+ if (region.stable) {
22604
+ okBuffer.push(...region.bufferContent);
22605
+ } else if (isFalseConflict(region.aContent, region.bContent)) {
22606
+ okBuffer.push(...region.aContent);
22607
+ } else {
22608
+ flushOk();
22609
+ results.push({
22610
+ conflict: {
22611
+ a: region.aContent,
22612
+ aIndex: region.aStart,
22613
+ o: region.oContent,
22614
+ oIndex: region.oStart,
22615
+ b: region.bContent,
22616
+ bIndex: region.bStart
22617
+ }
22618
+ });
22619
+ }
22620
+ });
22621
+ flushOk();
22622
+ return results;
22623
+ }
22636
22624
  function threeWayMerge(base, ours, theirs) {
22637
22625
  const baseLines = base.split("\n");
22638
22626
  const oursLines = ours.split("\n");
@@ -24295,7 +24283,7 @@ function status(outputDir) {
24295
24283
  }
24296
24284
  var import_promises4, import_os, import_path7, import_fs6, import_path8, import_yaml, import_crypto, import_path9, import_promises5, import_os2, import_path10, import_promises6, import_path11, import_promises7, import_path12, import_fs7, import_promises8, import_path13, import_fs8, import_path14, import_promises9, import_os3, import_path15, import_child_process3, import_crypto2, import_fs9, import_path16, import_yaml2, import_crypto3, import_fs10, import_path17, import_fs11, import_promises10, import_path18, __defProp3, __getOwnPropNames3, __esm3, __export3, GitClient_exports, GitClient, init_GitClient, HybridReconstruction_exports, init_HybridReconstruction, PatchApplyTheirs_exports, init_PatchApplyTheirs, CREDENTIAL_PATTERNS, SENSITIVE_FILE_PATTERNS, FERN_BOT_NAME, FERN_BOT_EMAIL, FERN_BOT_LOGIN, FERN_SUPPORT_NAMES, LOCKFILE_HEADER, LockfileNotFoundError, LockfileManager, BINARY_EXTENSIONS, INFRASTRUCTURE_FILES, ReplayDetector, MergeAccumulator, CONFLICT_OPENER, CONFLICT_SEPARATOR, CONFLICT_CLOSER, AUTOVERSION_PLACEHOLDERS, VERSION_TOKEN, VERSION_MASK, ReplayApplicator, ReplayCommitter, FileOwnership, FirstGenerationFlow, SkipApplicationFlow, NoPatchesFlow, NormalRegenerationFlow, ReplayService, FernignoreMigrator, REPLAY_FERNIGNORE_ENTRIES, GITATTRIBUTES_ENTRIES, EMPTY_RESULT;
24297
24285
  var init_dist3 = __esm({
24298
- "../../node_modules/.pnpm/@fern-api+replay@0.19.2/node_modules/@fern-api/replay/dist/index.js"() {
24286
+ "../../node_modules/.pnpm/@fern-api+replay@0.19.3/node_modules/@fern-api/replay/dist/index.js"() {
24299
24287
  "use strict";
24300
24288
  init_esm4();
24301
24289
  import_promises4 = require("fs/promises");
@@ -24308,7 +24296,6 @@ var init_dist3 = __esm({
24308
24296
  import_crypto = require("crypto");
24309
24297
  init_esm3();
24310
24298
  import_path9 = require("path");
24311
- init_diff3();
24312
24299
  import_promises5 = require("fs/promises");
24313
24300
  import_os2 = require("os");
24314
24301
  import_path10 = require("path");
@@ -42030,36 +42017,24 @@ var AutoVersionStep = class extends BaseStep {
42030
42017
  });
42031
42018
  }
42032
42019
  if (cleanedBytes > MAX_RAW_DIFF_BYTES) {
42033
- this.logger.warn(
42034
- `AutoVersionStep: diff too large for FAI (${formatSizeKB(cleanedBytes)}KB, limit ${formatSizeKB(MAX_RAW_DIFF_BYTES)}KB). Falling back to PATCH.`
42035
- );
42020
+ const warning = `diff too large for FAI (${formatSizeKB(cleanedBytes)}KB, limit ${formatSizeKB(MAX_RAW_DIFF_BYTES)}KB)`;
42021
+ this.logger.warn(`AutoVersionStep: ${warning}. Falling back to PATCH.`);
42036
42022
  return await this.finalizeWithBump({
42037
42023
  service,
42038
42024
  language,
42039
42025
  mappedMagicVersion,
42040
42026
  previousVersion,
42041
- analysis: { versionBump: "PATCH", message: this.brandMessage("SDK regeneration") }
42027
+ analysis: this.fallbackPatchAnalysis(),
42028
+ analysisWarning: warning
42042
42029
  });
42043
42030
  }
42044
- let analysis;
42045
- try {
42046
- if (this.config.ai == null && this.config.fernToken != null) {
42047
- analysis = await this.analyzeViaFaiService(cleanedDiff, language, previousVersion);
42048
- } else {
42049
- const chunks = service.chunkDiff(cleanedDiff, MAX_AI_DIFF_BYTES);
42050
- const cappedChunks = chunks.slice(0, MAX_CHUNKS);
42051
- const skippedChunks = chunks.length - cappedChunks.length;
42052
- if (chunks.length > 1) {
42053
- this.logger.info(
42054
- `AutoVersionStep: split diff into ${chunks.length} chunks` + (skippedChunks > 0 ? ` (capped at ${MAX_CHUNKS}, skipping ${skippedChunks})` : "")
42055
- );
42056
- }
42057
- analysis = cappedChunks.length <= 1 ? await this.analyzeSingle(cleanedDiff, language, previousVersion) : await this.analyzeChunks(cappedChunks, language, previousVersion);
42058
- }
42059
- } catch (error) {
42060
- this.logger.warn(`AutoVersionStep: FAI analysis failed (${String(error)}); falling back to PATCH bump.`);
42061
- analysis = { versionBump: "PATCH", message: this.brandMessage("SDK regeneration") };
42062
- }
42031
+ const { analysis, analysisWarning } = await this.analyze({
42032
+ service,
42033
+ cleanedDiff,
42034
+ language,
42035
+ previousVersion,
42036
+ label: "AutoVersionStep"
42037
+ });
42063
42038
  if (analysis == null) {
42064
42039
  this.logger.info(`AutoVersionStep: FAI returned NO_CHANGE; rewriting placeholder to ${previousVersion}.`);
42065
42040
  return await this.finalizeNoChange({
@@ -42067,7 +42042,8 @@ var AutoVersionStep = class extends BaseStep {
42067
42042
  language,
42068
42043
  mappedMagicVersion,
42069
42044
  previousVersion,
42070
- reason: "FAI returned NO_CHANGE"
42045
+ reason: "FAI returned NO_CHANGE",
42046
+ analysisWarning
42071
42047
  });
42072
42048
  }
42073
42049
  return await this.finalizeWithBump({
@@ -42075,7 +42051,8 @@ var AutoVersionStep = class extends BaseStep {
42075
42051
  language,
42076
42052
  mappedMagicVersion,
42077
42053
  previousVersion,
42078
- analysis
42054
+ analysis,
42055
+ analysisWarning
42079
42056
  });
42080
42057
  }
42081
42058
  /**
@@ -42126,38 +42103,24 @@ var AutoVersionStep = class extends BaseStep {
42126
42103
  });
42127
42104
  }
42128
42105
  if (cleanedBytes > MAX_RAW_DIFF_BYTES) {
42129
- this.logger.warn(
42130
- `AutoVersionStep (non-replay): diff too large (${formatSizeKB(cleanedBytes)}KB). Falling back to PATCH.`
42131
- );
42106
+ const warning = `diff too large for FAI (${formatSizeKB(cleanedBytes)}KB, limit ${formatSizeKB(MAX_RAW_DIFF_BYTES)}KB)`;
42107
+ this.logger.warn(`AutoVersionStep (non-replay): ${warning}. Falling back to PATCH.`);
42132
42108
  return await this.finalizeWithBumpNonReplay({
42133
42109
  service,
42134
42110
  language,
42135
42111
  mappedMagicVersion,
42136
42112
  previousVersion,
42137
- analysis: { versionBump: "PATCH", message: this.brandMessage("SDK regeneration") }
42113
+ analysis: this.fallbackPatchAnalysis(),
42114
+ analysisWarning: warning
42138
42115
  });
42139
42116
  }
42140
- let analysis;
42141
- try {
42142
- if (this.config.ai == null && this.config.fernToken != null) {
42143
- analysis = await this.analyzeViaFaiService(cleanedDiff, language, previousVersion);
42144
- } else {
42145
- const chunks = service.chunkDiff(cleanedDiff, MAX_AI_DIFF_BYTES);
42146
- const cappedChunks = chunks.slice(0, MAX_CHUNKS);
42147
- const skippedChunks = chunks.length - cappedChunks.length;
42148
- if (chunks.length > 1) {
42149
- this.logger.info(
42150
- `AutoVersionStep (non-replay): split diff into ${chunks.length} chunks` + (skippedChunks > 0 ? ` (capped at ${MAX_CHUNKS}, skipping ${skippedChunks})` : "")
42151
- );
42152
- }
42153
- analysis = cappedChunks.length <= 1 ? await this.analyzeSingle(cleanedDiff, language, previousVersion) : await this.analyzeChunks(cappedChunks, language, previousVersion);
42154
- }
42155
- } catch (error) {
42156
- this.logger.warn(
42157
- `AutoVersionStep (non-replay): FAI analysis failed (${String(error)}); falling back to PATCH bump.`
42158
- );
42159
- analysis = { versionBump: "PATCH", message: this.brandMessage("SDK regeneration") };
42160
- }
42117
+ const { analysis, analysisWarning } = await this.analyze({
42118
+ service,
42119
+ cleanedDiff,
42120
+ language,
42121
+ previousVersion,
42122
+ label: "AutoVersionStep (non-replay)"
42123
+ });
42161
42124
  if (analysis == null) {
42162
42125
  this.logger.info(
42163
42126
  `AutoVersionStep (non-replay): FAI returned NO_CHANGE; rewriting placeholder to ${previousVersion}.`
@@ -42167,7 +42130,8 @@ var AutoVersionStep = class extends BaseStep {
42167
42130
  language,
42168
42131
  mappedMagicVersion,
42169
42132
  previousVersion,
42170
- reason: "FAI returned NO_CHANGE"
42133
+ reason: "FAI returned NO_CHANGE",
42134
+ analysisWarning
42171
42135
  });
42172
42136
  }
42173
42137
  return await this.finalizeWithBumpNonReplay({
@@ -42175,9 +42139,72 @@ var AutoVersionStep = class extends BaseStep {
42175
42139
  language,
42176
42140
  mappedMagicVersion,
42177
42141
  previousVersion,
42178
- analysis
42142
+ analysis,
42143
+ analysisWarning
42179
42144
  });
42180
42145
  }
42146
+ fallbackPatchAnalysis() {
42147
+ return { versionBump: "PATCH", message: this.brandMessage("SDK regeneration") };
42148
+ }
42149
+ /**
42150
+ * Runs FAI analysis over the cleaned diff. Never throws: when analysis cannot be
42151
+ * obtained at all, returns a PATCH fallback together with an `analysisWarning`
42152
+ * describing why, so callers can surface it in the step result / PR body instead
42153
+ * of shipping a silent PATCH for what may be a breaking change.
42154
+ */
42155
+ async analyze(params) {
42156
+ const { service, cleanedDiff, language, previousVersion, label } = params;
42157
+ const chunks = service.chunkDiff(cleanedDiff, MAX_AI_DIFF_BYTES);
42158
+ const cappedChunks = chunks.slice(0, MAX_CHUNKS);
42159
+ const skippedChunks = chunks.length - cappedChunks.length;
42160
+ const logSplit = () => {
42161
+ if (chunks.length > 1) {
42162
+ this.logger.info(
42163
+ `${label}: split diff into ${chunks.length} chunks` + (skippedChunks > 0 ? ` (capped at ${MAX_CHUNKS}, skipping ${skippedChunks})` : "")
42164
+ );
42165
+ }
42166
+ };
42167
+ try {
42168
+ if (this.config.ai == null && this.config.fernToken != null) {
42169
+ try {
42170
+ return { analysis: await this.analyzeViaFaiService(cleanedDiff, language, previousVersion) };
42171
+ } catch (error) {
42172
+ if (cappedChunks.length <= 1) {
42173
+ throw error;
42174
+ }
42175
+ this.logger.warn(
42176
+ `${label}: FAI analysis of the full diff failed (${String(error)}); retrying in ${cappedChunks.length} chunks.`
42177
+ );
42178
+ logSplit();
42179
+ const chunked = await this.analyzeChunksViaFaiService(
42180
+ cappedChunks,
42181
+ language,
42182
+ previousVersion,
42183
+ label
42184
+ );
42185
+ const warnings = [chunked.analysisWarning];
42186
+ if (skippedChunks > 0) {
42187
+ warnings.push(
42188
+ `${skippedChunks} of ${chunks.length} diff chunks were not analyzed (capped at ${MAX_CHUNKS})`
42189
+ );
42190
+ }
42191
+ const analysisWarning = warnings.filter(hasText).join("; ");
42192
+ return {
42193
+ analysis: chunked.analysis,
42194
+ analysisWarning: analysisWarning.length > 0 ? analysisWarning : void 0
42195
+ };
42196
+ }
42197
+ }
42198
+ logSplit();
42199
+ return {
42200
+ analysis: cappedChunks.length <= 1 ? await this.analyzeSingle(cleanedDiff, language, previousVersion) : await this.analyzeChunks(cappedChunks, language, previousVersion)
42201
+ };
42202
+ } catch (error) {
42203
+ const warning = `FAI analysis failed (${String(error)})`;
42204
+ this.logger.warn(`${label}: ${warning}; falling back to PATCH bump.`);
42205
+ return { analysis: this.fallbackPatchAnalysis(), analysisWarning: warning };
42206
+ }
42207
+ }
42181
42208
  /**
42182
42209
  * Terminal path for runs that determine no semver bump is needed. The
42183
42210
  * current working tree still contains `0.0.0-fern-placeholder` from this
@@ -42188,7 +42215,7 @@ var AutoVersionStep = class extends BaseStep {
42188
42215
  * `[fern-autoversion]` so the replay + github steps see a stable base.
42189
42216
  */
42190
42217
  async finalizeNoChange(params) {
42191
- const { service, language, mappedMagicVersion, previousVersion, reason } = params;
42218
+ const { service, language, mappedMagicVersion, previousVersion, reason, analysisWarning } = params;
42192
42219
  if (!isValidSemver(previousVersion)) {
42193
42220
  const errorMessage = `AutoVersionStep: resolved previousVersion ${JSON.stringify(previousVersion)} is not a valid semver string. Refusing to rewrite placeholder to avoid shell injection.`;
42194
42221
  this.logger.error(errorMessage);
@@ -42207,11 +42234,12 @@ var AutoVersionStep = class extends BaseStep {
42207
42234
  previousVersion,
42208
42235
  versionBump: "NO_CHANGE",
42209
42236
  commitMessage,
42210
- commitSha
42237
+ commitSha,
42238
+ analysisWarning
42211
42239
  };
42212
42240
  }
42213
42241
  async finalizeWithBump(params) {
42214
- const { service, language, mappedMagicVersion, previousVersion } = params;
42242
+ const { service, language, mappedMagicVersion, previousVersion, analysisWarning } = params;
42215
42243
  const analysis = this.withChangelogFallback(params.analysis);
42216
42244
  const newVersion = incrementVersion(previousVersion, analysis.versionBump);
42217
42245
  this.logger.info(`AutoVersionStep: ${analysis.versionBump} bump: ${previousVersion} \u2192 ${newVersion}`);
@@ -42233,6 +42261,7 @@ var AutoVersionStep = class extends BaseStep {
42233
42261
  versionBump: analysis.versionBump,
42234
42262
  prDescription: analysis.prDescription,
42235
42263
  versionBumpReason: analysis.versionBumpReason,
42264
+ analysisWarning,
42236
42265
  commitSha
42237
42266
  };
42238
42267
  }
@@ -42241,7 +42270,7 @@ var AutoVersionStep = class extends BaseStep {
42241
42270
  * `previousVersion` but does NOT commit — GithubStep handles the commit.
42242
42271
  */
42243
42272
  async finalizeNoChangeNonReplay(params) {
42244
- const { service, language, mappedMagicVersion, previousVersion, reason } = params;
42273
+ const { service, language, mappedMagicVersion, previousVersion, reason, analysisWarning } = params;
42245
42274
  if (!isValidSemver(previousVersion)) {
42246
42275
  const errorMessage = `AutoVersionStep: resolved previousVersion ${JSON.stringify(previousVersion)} is not a valid semver string. Refusing to rewrite placeholder to avoid shell injection.`;
42247
42276
  this.logger.error(errorMessage);
@@ -42258,7 +42287,8 @@ var AutoVersionStep = class extends BaseStep {
42258
42287
  version: previousVersion,
42259
42288
  previousVersion,
42260
42289
  versionBump: "NO_CHANGE",
42261
- commitMessage
42290
+ commitMessage,
42291
+ analysisWarning
42262
42292
  };
42263
42293
  }
42264
42294
  /**
@@ -42266,7 +42296,7 @@ var AutoVersionStep = class extends BaseStep {
42266
42296
  * the bumped version but does NOT commit — GithubStep handles the commit.
42267
42297
  */
42268
42298
  async finalizeWithBumpNonReplay(params) {
42269
- const { service, language, mappedMagicVersion, previousVersion } = params;
42299
+ const { service, language, mappedMagicVersion, previousVersion, analysisWarning } = params;
42270
42300
  const analysis = this.withChangelogFallback(params.analysis);
42271
42301
  const newVersion = incrementVersion(previousVersion, analysis.versionBump);
42272
42302
  this.logger.info(
@@ -42288,7 +42318,8 @@ var AutoVersionStep = class extends BaseStep {
42288
42318
  previousVersion,
42289
42319
  versionBump: analysis.versionBump,
42290
42320
  prDescription: analysis.prDescription,
42291
- versionBumpReason: analysis.versionBumpReason
42321
+ versionBumpReason: analysis.versionBumpReason,
42322
+ analysisWarning
42292
42323
  };
42293
42324
  }
42294
42325
  /**
@@ -42689,6 +42720,68 @@ ${body}` : `${COMMIT_MARKER} ${subject}`;
42689
42720
  };
42690
42721
  }
42691
42722
  }
42723
+ /**
42724
+ * Chunked retry for the hosted FAI path. Each chunk is analyzed independently;
42725
+ * chunks whose request fails are skipped as long as at least one chunk succeeds,
42726
+ * and the partial coverage is reported via `analysisWarning` so the PR is flagged
42727
+ * and never automerged. Results are aggregated with the same max-bump rule as the
42728
+ * BAML path; entries are joined rather than consolidated (no hosted rollup endpoint).
42729
+ */
42730
+ async analyzeChunksViaFaiService(chunks, language, previousVersion, label) {
42731
+ const chunkAnalyses = [];
42732
+ let attemptedChunks = 0;
42733
+ let failedChunks = 0;
42734
+ let lastError;
42735
+ for (let i2 = 0; i2 < chunks.length; i2++) {
42736
+ const chunk = chunks[i2];
42737
+ if (!chunk) {
42738
+ continue;
42739
+ }
42740
+ attemptedChunks++;
42741
+ let analysis;
42742
+ try {
42743
+ analysis = await this.analyzeViaFaiService(chunk, language, previousVersion);
42744
+ } catch (error) {
42745
+ failedChunks++;
42746
+ lastError = error;
42747
+ this.logger.warn(
42748
+ `${label}: FAI analysis of chunk ${i2 + 1}/${chunks.length} failed (${String(error)}).`
42749
+ );
42750
+ continue;
42751
+ }
42752
+ if (analysis == null) {
42753
+ continue;
42754
+ }
42755
+ chunkAnalyses.push(analysis);
42756
+ }
42757
+ if (failedChunks > 0 && failedChunks === attemptedChunks) {
42758
+ throw new Error(`all ${attemptedChunks} FAI chunk requests failed; last error: ${String(lastError)}`);
42759
+ }
42760
+ const analysisWarning = failedChunks > 0 ? `${failedChunks} of ${attemptedChunks} FAI chunk requests failed; last error: ${String(lastError)}` : void 0;
42761
+ if (chunkAnalyses.length === 0) {
42762
+ return { analysis: null, analysisWarning };
42763
+ }
42764
+ const { bestBump, bestMessage, bestVersionBumpReason, changelogEntries, usedBumpReasonAsEntry } = aggregateChunkAnalyses(chunkAnalyses);
42765
+ if (usedBumpReasonAsEntry) {
42766
+ this.logger.warn(
42767
+ `${label}: no chunk produced a changelog entry for the ${bestBump} bump; using its version bump reason instead.`
42768
+ );
42769
+ }
42770
+ if (analysisWarning != null) {
42771
+ this.logger.warn(`${label}: ${analysisWarning}; the ${bestBump} bump is based on the remaining chunks.`);
42772
+ }
42773
+ const prDescriptions = chunkAnalyses.filter((analysis) => analysis.versionBump === bestBump && hasText(analysis.prDescription)).map((analysis) => analysis.prDescription?.trim() ?? "");
42774
+ return {
42775
+ analysis: {
42776
+ versionBump: bestBump,
42777
+ message: bestMessage,
42778
+ changelogEntry: changelogEntries.length > 0 ? changelogEntries.join("\n\n") : void 0,
42779
+ prDescription: prDescriptions.length > 0 ? prDescriptions.join("\n\n") : void 0,
42780
+ versionBumpReason: bestVersionBumpReason
42781
+ },
42782
+ analysisWarning
42783
+ };
42784
+ }
42692
42785
  /**
42693
42786
  * Calls the hosted FAI service (`/sdks/analyze-commit-diff`) with the fern token.
42694
42787
  * Used when no BAML `ai` config is supplied (remote generation via fiddle). FAI
@@ -42713,7 +42806,10 @@ ${body}` : `${COMMIT_MARKER} ${subject}`;
42713
42806
  });
42714
42807
  if (!response.ok) {
42715
42808
  const body = await response.text().catch(() => "");
42716
- throw new Error(`FAI analyze-commit-diff failed with status ${response.status}: ${body.slice(0, 500)}`);
42809
+ if (body.length > 0) {
42810
+ this.logger.debug(`AutoVersionStep: FAI analyze-commit-diff response body: ${body.slice(0, 500)}`);
42811
+ }
42812
+ throw new Error(`FAI analyze-commit-diff failed with status ${response.status}`);
42717
42813
  }
42718
42814
  const parsed = await response.json();
42719
42815
  if (!isFaiAnalyzeResponse(parsed)) {
@@ -43513,6 +43609,7 @@ var GithubStep = class extends BaseStep {
43513
43609
  );
43514
43610
  const replaySection = formatReplayPrBody(replayResult, { branchName: prBranch, repoUri: this.config.uri });
43515
43611
  let enrichedBody = replaySection != null ? prBody + "\n\n---\n\n" + replaySection : prBody;
43612
+ enrichedBody = appendAutoVersionWarning(enrichedBody, resolved.analysisWarning);
43516
43613
  enrichedBody = enrichPrBodyForAutomation(enrichedBody, this.config, resolved);
43517
43614
  if (isUpdatingExistingPR && existingPR != null) {
43518
43615
  this.logger.info(`Updated existing pull request: ${existingPR.htmlUrl}`);
@@ -43771,9 +43868,25 @@ function resolvePrFields(config, autoVersion) {
43771
43868
  newVersion: config.newVersion ?? autoVersion?.version,
43772
43869
  versionBump: config.versionBump ?? autoVersion?.versionBump,
43773
43870
  hasBreakingChanges: config.hasBreakingChanges ?? autoVersionBreaking,
43774
- breakingChangesSummary: config.breakingChangesSummary ?? autoVersion?.prDescription
43871
+ breakingChangesSummary: config.breakingChangesSummary ?? autoVersion?.prDescription,
43872
+ analysisWarning: autoVersion?.analysisWarning
43775
43873
  };
43776
43874
  }
43875
+ function appendAutoVersionWarning(body, analysisWarning) {
43876
+ if (analysisWarning == null || analysisWarning.trim().length === 0) {
43877
+ return body;
43878
+ }
43879
+ const reason = analysisWarning.replace(/[`\s]+/g, " ").trim().slice(0, 300);
43880
+ return body + `
43881
+
43882
+ ---
43883
+
43884
+ ## \u26A0\uFE0F Version bump not verified
43885
+
43886
+ Automatic version analysis was unavailable or incomplete for this generation, so the version bump and changelog may understate the changes (a **PATCH** bump with no changelog is applied when no analysis is available). If this change is breaking or adds features, adjust the version and changelog before merging.
43887
+
43888
+ Reason: \`${reason}\``;
43889
+ }
43777
43890
  function enrichPrBodyForAutomation(body, config, breaking = {}) {
43778
43891
  if (!config.automationMode) {
43779
43892
  return body;
@@ -43795,7 +43908,8 @@ _Fern Run ID: \`${config.runId}\`_`;
43795
43908
  }
43796
43909
  function shouldEnableAutomerge(config, breaking = {}) {
43797
43910
  const hasBreakingChanges = breaking.hasBreakingChanges ?? config.hasBreakingChanges;
43798
- return config.automationMode === true && config.autoMerge === true && hasBreakingChanges !== true;
43911
+ const analysisUnavailable = breaking.analysisWarning != null && breaking.analysisWarning.length > 0;
43912
+ return config.automationMode === true && config.autoMerge === true && hasBreakingChanges !== true && !analysisUnavailable;
43799
43913
  }
43800
43914
  function shouldCheckNoDiff(config) {
43801
43915
  return config.skipIfNoDiff === true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fern-api/generator-cli",
3
- "version": "0.10.1",
3
+ "version": "0.10.3",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/fern-api/fern.git",
@@ -23,7 +23,7 @@
23
23
  ],
24
24
  "dependencies": {
25
25
  "@boundaryml/baml": "^0.219.0",
26
- "@fern-api/replay": "0.19.2",
26
+ "@fern-api/replay": "0.19.3",
27
27
  "@octokit/rest": "^22.0.1",
28
28
  "es-toolkit": "^1.45.1",
29
29
  "semver": "^7.6.3",