@fern-api/generator-cli 0.6.11 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/dist/api.d.ts +19 -16
  2. package/dist/api.js +178 -178
  3. package/dist/cli.js +908 -638
  4. package/package.json +3 -3
package/dist/api.js CHANGED
@@ -902,7 +902,7 @@ module.exports = __toCommonJS(api_exports2);
902
902
  var import_promises = require("fs/promises");
903
903
  var import_path = __toESM(require("path"), 1);
904
904
 
905
- // ../../node_modules/.pnpm/simple-git@3.30.0/node_modules/simple-git/dist/esm/index.js
905
+ // ../../node_modules/.pnpm/simple-git@3.33.0/node_modules/simple-git/dist/esm/index.js
906
906
  var import_node_buffer = require("buffer");
907
907
  var import_file_exists = __toESM(require_dist(), 1);
908
908
  var import_debug = __toESM(require_src(), 1);
@@ -1153,7 +1153,7 @@ var init_argument_filters = __esm({
1153
1153
  return typeof input === "number";
1154
1154
  };
1155
1155
  filterString = (input) => {
1156
- return typeof input === "string";
1156
+ return typeof input === "string" || isPathSpec(input);
1157
1157
  };
1158
1158
  filterStringOrStringArray = (input) => {
1159
1159
  return filterString(input) || Array.isArray(input) && input.every(filterString);
@@ -3528,15 +3528,15 @@ function parser3(indexX, indexY, handler) {
3528
3528
  return [`${indexX}${indexY}`, handler];
3529
3529
  }
3530
3530
  function conflicts(indexX, ...indexY) {
3531
- return indexY.map((y) => parser3(indexX, y, (result, file) => append(result.conflicted, file)));
3531
+ return indexY.map((y) => parser3(indexX, y, (result, file) => result.conflicted.push(file)));
3532
3532
  }
3533
3533
  function splitLine(result, lineStr) {
3534
3534
  const trimmed2 = lineStr.trim();
3535
3535
  switch (" ") {
3536
3536
  case trimmed2.charAt(2):
3537
- return data(trimmed2.charAt(0), trimmed2.charAt(1), trimmed2.substr(3));
3537
+ return data(trimmed2.charAt(0), trimmed2.charAt(1), trimmed2.slice(3));
3538
3538
  case trimmed2.charAt(1):
3539
- return data(" ", trimmed2.charAt(0), trimmed2.substr(2));
3539
+ return data(" ", trimmed2.charAt(0), trimmed2.slice(2));
3540
3540
  default:
3541
3541
  return;
3542
3542
  }
@@ -3584,58 +3584,54 @@ var init_StatusSummary = __esm({
3584
3584
  parser3(
3585
3585
  " ",
3586
3586
  "A",
3587
- (result, file) => append(result.created, file)
3587
+ (result, file) => result.created.push(file)
3588
3588
  ),
3589
3589
  parser3(
3590
3590
  " ",
3591
3591
  "D",
3592
- (result, file) => append(result.deleted, file)
3592
+ (result, file) => result.deleted.push(file)
3593
3593
  ),
3594
3594
  parser3(
3595
3595
  " ",
3596
3596
  "M",
3597
- (result, file) => append(result.modified, file)
3598
- ),
3599
- parser3(
3600
- "A",
3601
- " ",
3602
- (result, file) => append(result.created, file) && append(result.staged, file)
3603
- ),
3604
- parser3(
3605
- "A",
3606
- "M",
3607
- (result, file) => append(result.created, file) && append(result.staged, file) && append(result.modified, file)
3608
- ),
3609
- parser3(
3610
- "D",
3611
- " ",
3612
- (result, file) => append(result.deleted, file) && append(result.staged, file)
3613
- ),
3614
- parser3(
3615
- "M",
3616
- " ",
3617
- (result, file) => append(result.modified, file) && append(result.staged, file)
3618
- ),
3619
- parser3(
3620
- "M",
3621
- "M",
3622
- (result, file) => append(result.modified, file) && append(result.staged, file)
3597
+ (result, file) => result.modified.push(file)
3623
3598
  ),
3599
+ parser3("A", " ", (result, file) => {
3600
+ result.created.push(file);
3601
+ result.staged.push(file);
3602
+ }),
3603
+ parser3("A", "M", (result, file) => {
3604
+ result.created.push(file);
3605
+ result.staged.push(file);
3606
+ result.modified.push(file);
3607
+ }),
3608
+ parser3("D", " ", (result, file) => {
3609
+ result.deleted.push(file);
3610
+ result.staged.push(file);
3611
+ }),
3612
+ parser3("M", " ", (result, file) => {
3613
+ result.modified.push(file);
3614
+ result.staged.push(file);
3615
+ }),
3616
+ parser3("M", "M", (result, file) => {
3617
+ result.modified.push(file);
3618
+ result.staged.push(file);
3619
+ }),
3624
3620
  parser3("R", " ", (result, file) => {
3625
- append(result.renamed, renamedFile(file));
3621
+ result.renamed.push(renamedFile(file));
3626
3622
  }),
3627
3623
  parser3("R", "M", (result, file) => {
3628
3624
  const renamed = renamedFile(file);
3629
- append(result.renamed, renamed);
3630
- append(result.modified, renamed.to);
3625
+ result.renamed.push(renamed);
3626
+ result.modified.push(renamed.to);
3631
3627
  }),
3632
3628
  parser3("!", "!", (_result, _file) => {
3633
- append(_result.ignored = _result.ignored || [], _file);
3629
+ (_result.ignored = _result.ignored || []).push(_file);
3634
3630
  }),
3635
3631
  parser3(
3636
3632
  "?",
3637
3633
  "?",
3638
- (result, file) => append(result.not_added, file)
3634
+ (result, file) => result.not_added.push(file)
3639
3635
  ),
3640
3636
  ...conflicts(
3641
3637
  "A",
@@ -3793,6 +3789,48 @@ var init_version = __esm({
3793
3789
  ];
3794
3790
  }
3795
3791
  });
3792
+ function createCloneTask(api, task, repoPath, ...args) {
3793
+ if (!filterString(repoPath)) {
3794
+ return configurationErrorTask(`git.${api}() requires a string 'repoPath'`);
3795
+ }
3796
+ return task(repoPath, filterType(args[0], filterString), getTrailingOptions(arguments));
3797
+ }
3798
+ function clone_default() {
3799
+ return {
3800
+ clone(repo, ...rest) {
3801
+ return this._runTask(
3802
+ createCloneTask("clone", cloneTask, filterType(repo, filterString), ...rest),
3803
+ trailingFunctionArgument(arguments)
3804
+ );
3805
+ },
3806
+ mirror(repo, ...rest) {
3807
+ return this._runTask(
3808
+ createCloneTask("mirror", cloneMirrorTask, filterType(repo, filterString), ...rest),
3809
+ trailingFunctionArgument(arguments)
3810
+ );
3811
+ }
3812
+ };
3813
+ }
3814
+ var cloneTask;
3815
+ var cloneMirrorTask;
3816
+ var init_clone = __esm({
3817
+ "src/lib/tasks/clone.ts"() {
3818
+ "use strict";
3819
+ init_task();
3820
+ init_utils();
3821
+ init_pathspec();
3822
+ cloneTask = (repo, directory, customArgs) => {
3823
+ const commands = ["clone", ...customArgs];
3824
+ filterString(repo) && commands.push(pathspec(repo));
3825
+ filterString(directory) && commands.push(pathspec(directory));
3826
+ return straightThroughStringTask(commands);
3827
+ };
3828
+ cloneMirrorTask = (repo, directory, customArgs) => {
3829
+ append(customArgs, "--mirror");
3830
+ return cloneTask(repo, directory, customArgs);
3831
+ };
3832
+ }
3833
+ });
3796
3834
  var simple_git_api_exports = {};
3797
3835
  __export2(simple_git_api_exports, {
3798
3836
  SimpleGitApi: () => SimpleGitApi
@@ -3819,6 +3857,7 @@ var init_simple_git_api = __esm({
3819
3857
  init_task();
3820
3858
  init_version();
3821
3859
  init_utils();
3860
+ init_clone();
3822
3861
  SimpleGitApi = class {
3823
3862
  constructor(_executor) {
3824
3863
  this._executor = _executor;
@@ -3921,6 +3960,7 @@ var init_simple_git_api = __esm({
3921
3960
  Object.assign(
3922
3961
  SimpleGitApi.prototype,
3923
3962
  checkout_default(),
3963
+ clone_default(),
3924
3964
  commit_default(),
3925
3965
  config_default(),
3926
3966
  count_objects_default(),
@@ -4244,35 +4284,6 @@ var init_check_ignore = __esm({
4244
4284
  init_CheckIgnore();
4245
4285
  }
4246
4286
  });
4247
- var clone_exports = {};
4248
- __export2(clone_exports, {
4249
- cloneMirrorTask: () => cloneMirrorTask,
4250
- cloneTask: () => cloneTask
4251
- });
4252
- function disallowedCommand(command) {
4253
- return /^--upload-pack(=|$)/.test(command);
4254
- }
4255
- function cloneTask(repo, directory, customArgs) {
4256
- const commands = ["clone", ...customArgs];
4257
- filterString(repo) && commands.push(repo);
4258
- filterString(directory) && commands.push(directory);
4259
- const banned = commands.find(disallowedCommand);
4260
- if (banned) {
4261
- return configurationErrorTask(`git.fetch: potential exploit argument blocked.`);
4262
- }
4263
- return straightThroughStringTask(commands);
4264
- }
4265
- function cloneMirrorTask(repo, directory, customArgs) {
4266
- append(customArgs, "--mirror");
4267
- return cloneTask(repo, directory, customArgs);
4268
- }
4269
- var init_clone = __esm({
4270
- "src/lib/tasks/clone.ts"() {
4271
- "use strict";
4272
- init_task();
4273
- init_utils();
4274
- }
4275
- });
4276
4287
  function parseFetchResult(stdOut, stdErr) {
4277
4288
  const result = {
4278
4289
  raw: stdOut,
@@ -4328,7 +4339,7 @@ var fetch_exports = {};
4328
4339
  __export2(fetch_exports, {
4329
4340
  fetchTask: () => fetchTask
4330
4341
  });
4331
- function disallowedCommand2(command) {
4342
+ function disallowedCommand(command) {
4332
4343
  return /^--upload-pack(=|$)/.test(command);
4333
4344
  }
4334
4345
  function fetchTask(remote, branch, customArgs) {
@@ -4336,7 +4347,7 @@ function fetchTask(remote, branch, customArgs) {
4336
4347
  if (remote && branch) {
4337
4348
  commands.push(remote, branch);
4338
4349
  }
4339
- const banned = commands.find(disallowedCommand2);
4350
+ const banned = commands.find(disallowedCommand);
4340
4351
  if (banned) {
4341
4352
  return configurationErrorTask(`git.fetch: potential exploit argument blocked.`);
4342
4353
  }
@@ -4652,7 +4663,7 @@ var require_git = __commonJS2({
4652
4663
  var { GitExecutor: GitExecutor2 } = (init_git_executor(), __toCommonJS2(git_executor_exports));
4653
4664
  var { SimpleGitApi: SimpleGitApi2 } = (init_simple_git_api(), __toCommonJS2(simple_git_api_exports));
4654
4665
  var { Scheduler: Scheduler2 } = (init_scheduler(), __toCommonJS2(scheduler_exports));
4655
- var { configurationErrorTask: configurationErrorTask2 } = (init_task(), __toCommonJS2(task_exports));
4666
+ var { adhocExecTask: adhocExecTask2, configurationErrorTask: configurationErrorTask2 } = (init_task(), __toCommonJS2(task_exports));
4656
4667
  var {
4657
4668
  asArray: asArray2,
4658
4669
  filterArray: filterArray2,
@@ -4673,7 +4684,6 @@ var require_git = __commonJS2({
4673
4684
  } = (init_branch(), __toCommonJS2(branch_exports));
4674
4685
  var { checkIgnoreTask: checkIgnoreTask2 } = (init_check_ignore(), __toCommonJS2(check_ignore_exports));
4675
4686
  var { checkIsRepoTask: checkIsRepoTask2 } = (init_check_is_repo(), __toCommonJS2(check_is_repo_exports));
4676
- var { cloneTask: cloneTask2, cloneMirrorTask: cloneMirrorTask2 } = (init_clone(), __toCommonJS2(clone_exports));
4677
4687
  var { cleanWithOptionsTask: cleanWithOptionsTask2, isCleanOptionsArray: isCleanOptionsArray2 } = (init_clean(), __toCommonJS2(clean_exports));
4678
4688
  var { diffSummaryTask: diffSummaryTask2 } = (init_diff(), __toCommonJS2(diff_exports));
4679
4689
  var { fetchTask: fetchTask2 } = (init_fetch(), __toCommonJS2(fetch_exports));
@@ -4728,24 +4738,6 @@ var require_git = __commonJS2({
4728
4738
  trailingFunctionArgument2(arguments)
4729
4739
  );
4730
4740
  };
4731
- function createCloneTask(api, task, repoPath, localPath) {
4732
- if (typeof repoPath !== "string") {
4733
- return configurationErrorTask2(`git.${api}() requires a string 'repoPath'`);
4734
- }
4735
- return task(repoPath, filterType2(localPath, filterString2), getTrailingOptions2(arguments));
4736
- }
4737
- Git2.prototype.clone = function() {
4738
- return this._runTask(
4739
- createCloneTask("clone", cloneTask2, ...arguments),
4740
- trailingFunctionArgument2(arguments)
4741
- );
4742
- };
4743
- Git2.prototype.mirror = function() {
4744
- return this._runTask(
4745
- createCloneTask("mirror", cloneMirrorTask2, ...arguments),
4746
- trailingFunctionArgument2(arguments)
4747
- );
4748
- };
4749
4741
  Git2.prototype.mv = function(from, to) {
4750
4742
  return this._runTask(moveTask2(from, to), trailingFunctionArgument2(arguments));
4751
4743
  };
@@ -4778,10 +4770,13 @@ var require_git = __commonJS2({
4778
4770
  );
4779
4771
  };
4780
4772
  Git2.prototype.silent = function(silence) {
4781
- console.warn(
4782
- "simple-git deprecation notice: git.silent: logging should be configured using the `debug` library / `DEBUG` environment variable, this will be an error in version 3"
4773
+ return this._runTask(
4774
+ adhocExecTask2(
4775
+ () => console.warn(
4776
+ "simple-git deprecation notice: git.silent: logging should be configured using the `debug` library / `DEBUG` environment variable, this method will be removed."
4777
+ )
4778
+ )
4783
4779
  );
4784
- return this;
4785
4780
  };
4786
4781
  Git2.prototype.tags = function(options, then) {
4787
4782
  return this._runTask(
@@ -5007,7 +5002,13 @@ var require_git = __commonJS2({
5007
5002
  return this._runTask(task);
5008
5003
  };
5009
5004
  Git2.prototype.clearQueue = function() {
5010
- return this;
5005
+ return this._runTask(
5006
+ adhocExecTask2(
5007
+ () => console.warn(
5008
+ "simple-git deprecation notice: clearQueue() is deprecated and will be removed, switch to using the abortPlugin instead."
5009
+ )
5010
+ )
5011
+ );
5011
5012
  };
5012
5013
  Git2.prototype.checkIgnore = function(pathnames, then) {
5013
5014
  return this._runTask(
@@ -5077,19 +5078,36 @@ function abortPlugin(signal) {
5077
5078
  function isConfigSwitch(arg) {
5078
5079
  return typeof arg === "string" && arg.trim().toLowerCase() === "-c";
5079
5080
  }
5080
- function preventProtocolOverride(arg, next) {
5081
- if (!isConfigSwitch(arg)) {
5082
- return;
5083
- }
5084
- if (!/^\s*protocol(.[a-z]+)?.allow/.test(next)) {
5085
- return;
5081
+ function isCloneUploadPackSwitch(char, arg) {
5082
+ if (typeof arg !== "string" || !arg.includes(char)) {
5083
+ return false;
5086
5084
  }
5087
- throw new GitPluginError(
5088
- void 0,
5089
- "unsafe",
5090
- "Configuring protocol.allow is not permitted without enabling allowUnsafeExtProtocol"
5091
- );
5085
+ const cleaned = arg.trim().replace(/\0/g, "");
5086
+ return /^(--no)?-{1,2}[\dlsqvnobucj]+(\s|$)/.test(cleaned);
5087
+ }
5088
+ function preventConfigBuilder(config, setting, message = String(config)) {
5089
+ const regex = typeof config === "string" ? new RegExp(`\\s*${config}`, "i") : config;
5090
+ return function preventCommand(options, arg, next) {
5091
+ if (options[setting] !== true && isConfigSwitch(arg) && regex.test(next)) {
5092
+ throw new GitPluginError(
5093
+ void 0,
5094
+ "unsafe",
5095
+ `Configuring ${message} is not permitted without enabling ${setting}`
5096
+ );
5097
+ }
5098
+ };
5092
5099
  }
5100
+ var preventUnsafeConfig = [
5101
+ preventConfigBuilder(
5102
+ /^\s*protocol(.[a-z]+)?.allow/i,
5103
+ "allowUnsafeProtocolOverride",
5104
+ "protocol.allow"
5105
+ ),
5106
+ preventConfigBuilder("core.sshCommand", "allowUnsafeSshCommand"),
5107
+ preventConfigBuilder("core.gitProxy", "allowUnsafeGitProxy"),
5108
+ preventConfigBuilder("core.hooksPath", "allowUnsafeHooksPath"),
5109
+ preventConfigBuilder("diff.external", "allowUnsafeDiffExternal")
5110
+ ];
5093
5111
  function preventUploadPack(arg, method) {
5094
5112
  if (/^\s*--(upload|receive)-pack/.test(arg)) {
5095
5113
  throw new GitPluginError(
@@ -5098,7 +5116,7 @@ function preventUploadPack(arg, method) {
5098
5116
  `Use of --upload-pack or --receive-pack is not permitted without enabling allowUnsafePack`
5099
5117
  );
5100
5118
  }
5101
- if (method === "clone" && /^\s*-u\b/.test(arg)) {
5119
+ if (method === "clone" && isCloneUploadPackSwitch("u", arg)) {
5102
5120
  throw new GitPluginError(
5103
5121
  void 0,
5104
5122
  "unsafe",
@@ -5114,16 +5132,16 @@ function preventUploadPack(arg, method) {
5114
5132
  }
5115
5133
  }
5116
5134
  function blockUnsafeOperationsPlugin({
5117
- allowUnsafeProtocolOverride = false,
5118
- allowUnsafePack = false
5135
+ allowUnsafePack = false,
5136
+ ...options
5119
5137
  } = {}) {
5120
5138
  return {
5121
5139
  type: "spawn.args",
5122
5140
  action(args, context) {
5123
5141
  args.forEach((current, index) => {
5124
5142
  const next = index < args.length ? args[index + 1] : "";
5125
- allowUnsafeProtocolOverride || preventProtocolOverride(current, next);
5126
5143
  allowUnsafePack || preventUploadPack(current, context.method);
5144
+ preventUnsafeConfig.forEach((helper) => helper(options, current, next));
5127
5145
  });
5128
5146
  return args;
5129
5147
  }
@@ -5207,7 +5225,7 @@ init_utils();
5207
5225
  var WRONG_NUMBER_ERR = `Invalid value supplied for custom binary, requires a single string or an array containing either one or two strings`;
5208
5226
  var WRONG_CHARS_ERR = `Invalid value supplied for custom binary, restricted characters must be removed or supply the unsafe.allowUnsafeCustomBinary option`;
5209
5227
  function isBadArgument(arg) {
5210
- return !arg || !/^([a-z]:)?([a-z0-9/.\\_-]+)$/i.test(arg);
5228
+ return !arg || !/^([a-z]:)?([a-z0-9/.\\_~-]+)$/i.test(arg);
5211
5229
  }
5212
5230
  function toBinaryConfig(input, allowUnsafe) {
5213
5231
  if (input.length < 1 || input.length > 2) {
@@ -5435,12 +5453,12 @@ function gitInstanceFactory(baseDir, options) {
5435
5453
  plugins.add(commandConfigPrefixingPlugin(config.config));
5436
5454
  }
5437
5455
  plugins.add(blockUnsafeOperationsPlugin(config.unsafe));
5438
- plugins.add(suffixPathsPlugin());
5439
5456
  plugins.add(completionDetectionPlugin(config.completion));
5440
5457
  config.abort && plugins.add(abortPlugin(config.abort));
5441
5458
  config.progress && plugins.add(progressMonitorPlugin(config.progress));
5442
5459
  config.timeout && plugins.add(timeoutPlugin(config.timeout));
5443
5460
  config.spawnOptions && plugins.add(spawnOptionsPlugin(config.spawnOptions));
5461
+ plugins.add(suffixPathsPlugin());
5444
5462
  plugins.add(errorDetectionPlugin(errorDetectionHandler(true)));
5445
5463
  config.errors && plugins.add(errorDetectionPlugin(config.errors));
5446
5464
  customBinaryPlugin(plugins, config.binary, config.unsafe?.allowUnsafeCustomBinary);
@@ -5748,6 +5766,21 @@ async function doesPathExist(filepath) {
5748
5766
  }
5749
5767
  }
5750
5768
 
5769
+ // ../commons/core-utils/lib/extractErrorMessage.js
5770
+ function extractErrorMessage(e) {
5771
+ if (typeof e === "string") {
5772
+ return e.length > 0 ? e : "Unknown error";
5773
+ }
5774
+ if (e instanceof Error) {
5775
+ return e.message.length > 0 ? e.message : "Unknown error";
5776
+ }
5777
+ if (typeof e === "object" && e !== null && "message" in e && typeof e["message"] === "string") {
5778
+ return e["message"].length > 0 ? e["message"] : "Unknown error";
5779
+ }
5780
+ const stringified = String(e);
5781
+ return stringified.length > 0 ? stringified : "Unknown error";
5782
+ }
5783
+
5751
5784
  // ../commons/github/lib/cloneRepository.js
5752
5785
  var import_child_process2 = require("child_process");
5753
5786
  var import_tmp_promise = __toESM(require("tmp-promise"), 1);
@@ -5769,7 +5802,7 @@ function parseRepository(githubRepository) {
5769
5802
  } else if (parts.length === 3 && parts[0] != null && parts[1] != null && parts[2] != null) {
5770
5803
  [remote, owner, repo] = parts;
5771
5804
  } else {
5772
- throw new Error(`Failed to parse GitHub repostiory ${githubRepository}`);
5805
+ throw new Error(`Failed to parse GitHub repository ${githubRepository}`);
5773
5806
  }
5774
5807
  return newRepositoryReference({ remote, owner, repo });
5775
5808
  }
@@ -5850,7 +5883,7 @@ async function cloneRepository({ githubRepository, installationToken, targetDire
5850
5883
  await git.clone(cloneUrl, ".");
5851
5884
  } catch (error) {
5852
5885
  const elapsed = Date.now() - startTime;
5853
- const errorMessage = error instanceof Error ? error.message : String(error);
5886
+ const errorMessage = extractErrorMessage(error);
5854
5887
  if (errorMessage.includes("ENOENT") || errorMessage.includes("spawn git")) {
5855
5888
  const diagnostics = getGitDiagnostics();
5856
5889
  throw new Error(`Failed to clone repository: git command not found. Self-hosted GitHub mode requires git to be installed on the host machine where the Fern CLI runs. URL: ${sanitizedUrl}. Elapsed: ${elapsed}ms. Debug info: ${diagnostics}. Original error: ${errorMessage}`);
@@ -8922,7 +8955,7 @@ var ReadmeGenerator = class {
8922
8955
  await writer.writeLine();
8923
8956
  await writer.writeLine("```groovy");
8924
8957
  await writer.writeLine("dependencies {");
8925
- await writer.writeLine(` implementation '${maven.group}:${maven.artifact}'`);
8958
+ await writer.writeLine(` implementation '${maven.group}:${maven.artifact}:${maven.version}'`);
8926
8959
  await writer.writeLine("}");
8927
8960
  await writer.writeLine("```");
8928
8961
  await writer.writeLine();
@@ -9735,7 +9768,7 @@ async function findExistingUpdatablePR(octokit, owner, repo, baseBranch, logger)
9735
9768
  }
9736
9769
  return void 0;
9737
9770
  } catch (error) {
9738
- logger.debug(`Error finding existing PRs: ${error instanceof Error ? error.message : String(error)}`);
9771
+ logger.debug(`Error finding existing PRs: ${extractErrorMessage(error)}`);
9739
9772
  return void 0;
9740
9773
  }
9741
9774
  }
@@ -9762,16 +9795,22 @@ async function checkPRHasOnlyGenerationCommits(octokit, owner, repo, pullNumber,
9762
9795
  }
9763
9796
  return true;
9764
9797
  } catch (error) {
9765
- logger.debug(`Error checking PR commits: ${error instanceof Error ? error.message : String(error)}`);
9798
+ logger.debug(`Error checking PR commits: ${extractErrorMessage(error)}`);
9766
9799
  return false;
9767
9800
  }
9768
9801
  }
9769
9802
 
9770
9803
  // src/pipeline/github/parseCommitMessage.ts
9771
- function parseCommitMessageForPR(commitMessage) {
9804
+ function parseCommitMessageForPR(commitMessage, changelogEntry, prDescription, versionBumpReason) {
9772
9805
  const lines = commitMessage.split("\n");
9773
9806
  const prTitle = lines[0]?.trim() || "SDK Generation";
9774
- const prBody = lines.slice(1).join("\n").trim() || "Automated SDK generation by Fern";
9807
+ const bodyFromCommit = lines.slice(1).join("\n").trim() || "Automated SDK generation by Fern";
9808
+ let prBody = prDescription?.trim() || changelogEntry?.trim() || bodyFromCommit;
9809
+ if (versionBumpReason?.trim()) {
9810
+ prBody = `**Version Bump:** ${versionBumpReason.trim()}
9811
+
9812
+ ${prBody}`;
9813
+ }
9775
9814
  return { prTitle, prBody };
9776
9815
  }
9777
9816
 
@@ -10031,14 +10070,17 @@ var GithubStep = class extends BaseStep {
10031
10070
  this.logger.debug(`Pushed ${tagName} tag for generation tracking`);
10032
10071
  result.generationBaseTagSha = generationBaseSha;
10033
10072
  } catch (error) {
10034
- this.logger.debug(
10035
- `Could not push generation tag: ${error instanceof Error ? error.message : String(error)}`
10036
- );
10073
+ this.logger.debug(`Could not push generation tag: ${extractErrorMessage(error)}`);
10037
10074
  }
10038
10075
  }
10039
10076
  }
10040
10077
  const finalCommitMessage = this.config.commitMessage ?? "SDK Generation";
10041
- const { prTitle, prBody } = parseCommitMessageForPR(finalCommitMessage);
10078
+ const { prTitle, prBody } = parseCommitMessageForPR(
10079
+ finalCommitMessage,
10080
+ this.config.changelogEntry,
10081
+ this.config.prDescription,
10082
+ this.config.versionBumpReason
10083
+ );
10042
10084
  const replaySection = formatReplayPrBody(replayResult, { branchName: prBranch, repoUri: this.config.uri });
10043
10085
  const enrichedBody = replaySection != null ? prBody + "\n\n---\n\n" + replaySection : prBody;
10044
10086
  if (isUpdatingExistingPR && existingPR != null) {
@@ -10055,9 +10097,7 @@ var GithubStep = class extends BaseStep {
10055
10097
  });
10056
10098
  this.logger.debug(`Updated PR #${existingPR.number} title and body`);
10057
10099
  } catch (error) {
10058
- this.logger.debug(
10059
- `Failed to update PR title/body: ${error instanceof Error ? error.message : String(error)}`
10060
- );
10100
+ this.logger.debug(`Failed to update PR title/body: ${extractErrorMessage(error)}`);
10061
10101
  }
10062
10102
  } else {
10063
10103
  const head = `${owner}:${prBranch}`;
@@ -10074,7 +10114,7 @@ var GithubStep = class extends BaseStep {
10074
10114
  result.prUrl = pullRequest.html_url;
10075
10115
  result.prNumber = pullRequest.number;
10076
10116
  } catch (error) {
10077
- const message = error instanceof Error ? error.message : String(error);
10117
+ const message = extractErrorMessage(error);
10078
10118
  if (message.includes("A pull request already exists for")) {
10079
10119
  this.logger.warn(`A pull request already exists for ${head}`);
10080
10120
  } else {
@@ -10149,7 +10189,7 @@ var import_path5 = require("path");
10149
10189
  var import_fs2 = require("fs");
10150
10190
  var import_promises3 = require("fs/promises");
10151
10191
  var import_path4 = require("path");
10152
- var REPLAY_FERNIGNORE_ENTRIES = [".fern/replay.lock", ".fern/replay.yml"];
10192
+ var REPLAY_FERNIGNORE_ENTRIES = [".fern/replay.lock"];
10153
10193
  async function ensureReplayFernignoreEntries(outputDir) {
10154
10194
  const fernignorePath = (0, import_path4.join)(outputDir, ".fernignore");
10155
10195
  let content = "";
@@ -10440,7 +10480,7 @@ var PostGenerationPipeline = class {
10440
10480
  } catch (error) {
10441
10481
  result.success = false;
10442
10482
  result.errors = result.errors ?? [];
10443
- const errorMessage = error instanceof Error ? error.message : String(error);
10483
+ const errorMessage = extractErrorMessage(error);
10444
10484
  result.errors.push(`${step.name} step error: ${errorMessage}`);
10445
10485
  }
10446
10486
  }
@@ -10450,7 +10490,6 @@ var PostGenerationPipeline = class {
10450
10490
 
10451
10491
  // src/replay/replay-init.ts
10452
10492
  var import_replay2 = require("@fern-api/replay");
10453
- var import_rest3 = require("@octokit/rest");
10454
10493
  var import_fs4 = require("fs");
10455
10494
  var import_path6 = require("path");
10456
10495
  var import_tmp_promise2 = __toESM(require("tmp-promise"));
@@ -10458,12 +10497,11 @@ async function replayInit(params) {
10458
10497
  const { githubRepo, token, dryRun } = params;
10459
10498
  const tmpDir = await import_tmp_promise2.default.dir({ unsafeCleanup: true });
10460
10499
  const repoPath = tmpDir.path;
10461
- const repository = await cloneRepository({
10500
+ await cloneRepository({
10462
10501
  githubRepository: githubRepo,
10463
10502
  installationToken: token,
10464
10503
  targetDirectory: repoPath
10465
10504
  });
10466
- const defaultBranch = await repository.getDefaultBranch();
10467
10505
  const bootstrapResult = await (0, import_replay2.bootstrap)(repoPath, {
10468
10506
  dryRun,
10469
10507
  fernignoreAction: "skip",
@@ -10472,52 +10510,22 @@ async function replayInit(params) {
10472
10510
  importHistory: params.importHistory
10473
10511
  });
10474
10512
  if (!bootstrapResult.generationCommit) {
10475
- return { bootstrap: bootstrapResult };
10513
+ return { bootstrap: bootstrapResult, fernignoreEntries: [] };
10476
10514
  }
10477
10515
  if (dryRun) {
10478
- return { bootstrap: bootstrapResult };
10516
+ return { bootstrap: bootstrapResult, fernignoreEntries: [] };
10479
10517
  }
10480
10518
  ensureReplayFernignoreEntriesSync(repoPath);
10481
- const commitMessage = `[fern-replay] Initialize Replay
10482
-
10483
- Tracked ${bootstrapResult.patchesCreated} customization patch(es).
10484
- Base generation: ${bootstrapResult.generationCommit.sha.slice(0, 7)}`;
10485
- const filesToAdd = [".fern/replay.lock", ".fern/replay.yml", ".fernignore"].filter(
10486
- (f) => (0, import_fs4.existsSync)((0, import_path6.join)(repoPath, f))
10487
- );
10488
- const branchName = `fern-replay/init-${Date.now()}`;
10489
- await repository.checkoutOrCreateLocal(branchName);
10490
- const git = new import_replay2.GitClient(repoPath);
10491
- await git.exec(["add", ...filesToAdd]);
10492
- await git.exec([
10493
- "-c",
10494
- `user.name=${import_replay2.FERN_BOT_NAME}`,
10495
- "-c",
10496
- `user.email=${import_replay2.FERN_BOT_EMAIL}`,
10497
- "-c",
10498
- "commit.gpgsign=false",
10499
- "commit",
10500
- "--no-verify",
10501
- "-m",
10502
- commitMessage
10503
- ]);
10504
- await repository.pushUpstream(branchName);
10505
- const parsed = parseRepository(githubRepo);
10506
- const octokit = new import_rest3.Octokit({ auth: token });
10507
- const prTitle = params.prTitle ?? "[fern-replay] Initialize Replay for SDK customizations";
10508
- const prBody = params.prBody ?? buildPrBody(bootstrapResult);
10509
- const { data: pr } = await octokit.pulls.create({
10510
- owner: parsed.owner,
10511
- repo: parsed.repo,
10512
- head: branchName,
10513
- base: defaultBranch,
10514
- title: prTitle,
10515
- body: prBody
10516
- });
10519
+ const lockfilePath = (0, import_path6.join)(repoPath, ".fern", "replay.lock");
10520
+ const lockfileContent = (0, import_fs4.existsSync)(lockfilePath) ? (0, import_fs4.readFileSync)(lockfilePath, "utf-8") : void 0;
10521
+ const replayYmlPath = (0, import_path6.join)(repoPath, ".fern", "replay.yml");
10522
+ const replayYmlContent = (0, import_fs4.existsSync)(replayYmlPath) ? (0, import_fs4.readFileSync)(replayYmlPath, "utf-8") : void 0;
10517
10523
  return {
10518
10524
  bootstrap: bootstrapResult,
10519
- prUrl: pr.html_url,
10520
- branch: branchName
10525
+ lockfileContent,
10526
+ replayYmlContent,
10527
+ fernignoreEntries: REPLAY_FERNIGNORE_ENTRIES,
10528
+ prBody: buildPrBody(bootstrapResult)
10521
10529
  };
10522
10530
  }
10523
10531
  function formatBootstrapSummary(result) {
@@ -10576,14 +10584,6 @@ function formatBootstrapSummary(result) {
10576
10584
  entries2.push({ level: "warn", message: ` ${w}` });
10577
10585
  }
10578
10586
  }
10579
- if (result.prUrl) {
10580
- entries2.push({ level: "info", message: `
10581
- PR created: ${result.prUrl}` });
10582
- entries2.push({ level: "info", message: "Merge the PR to enable Replay for this repository." });
10583
- } else if (result.branch) {
10584
- entries2.push({ level: "info", message: `
10585
- Pushed to branch: ${result.branch}` });
10586
- }
10587
10587
  return entries2;
10588
10588
  }
10589
10589
  function buildPrBody(result) {