@pilatos/bitbucket-cli 1.16.0 → 1.16.1

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.
package/dist/index.js CHANGED
@@ -17633,7 +17633,16 @@ class ConfigService {
17633
17633
  await this.verifyPermissions(this.configDir, CONFIG_DIR_MODE, "directory");
17634
17634
  await this.verifyPermissions(this.configFile, CONFIG_FILE_MODE, "file");
17635
17635
  const data = await fs.readFile(this.configFile, "utf-8");
17636
- this.configCache = JSON.parse(data);
17636
+ try {
17637
+ this.configCache = JSON.parse(data);
17638
+ } catch (parseError) {
17639
+ throw new BBError({
17640
+ code: 4001 /* CONFIG_READ_FAILED */,
17641
+ message: `Config file is not valid JSON: ${this.configFile}. Fix the file by hand or remove it and run \`bb auth login\` again.`,
17642
+ cause: parseError instanceof Error ? parseError : undefined,
17643
+ context: { configFile: this.configFile }
17644
+ });
17645
+ }
17637
17646
  return this.configCache;
17638
17647
  } catch (error) {
17639
17648
  if (error.code === "ENOENT") {
@@ -17771,10 +17780,14 @@ class ConfigService {
17771
17780
  }
17772
17781
  }
17773
17782
  // src/services/git.service.ts
17783
+ var DEFAULT_GIT_TIMEOUT_MS = 60000;
17784
+
17774
17785
  class GitService {
17775
17786
  cwd;
17776
- constructor(cwd) {
17787
+ timeoutMs;
17788
+ constructor(cwd, options = {}) {
17777
17789
  this.cwd = cwd ?? process.cwd();
17790
+ this.timeoutMs = options.timeoutMs ?? DEFAULT_GIT_TIMEOUT_MS;
17778
17791
  }
17779
17792
  async exec(args, cwd) {
17780
17793
  const proc = Bun.spawn(["git", ...args], {
@@ -17782,14 +17795,28 @@ class GitService {
17782
17795
  stdout: "pipe",
17783
17796
  stderr: "pipe"
17784
17797
  });
17785
- const stdout = await new Response(proc.stdout).text();
17786
- const stderr = await new Response(proc.stderr).text();
17787
- const exitCode = await proc.exited;
17788
- return {
17789
- stdout: stdout.trim(),
17790
- stderr: stderr.trim(),
17791
- exitCode
17792
- };
17798
+ let timedOut = false;
17799
+ const timer = setTimeout(() => {
17800
+ timedOut = true;
17801
+ try {
17802
+ proc.kill();
17803
+ } catch {}
17804
+ }, this.timeoutMs);
17805
+ try {
17806
+ const stdout = await new Response(proc.stdout).text();
17807
+ const stderr = await new Response(proc.stderr).text();
17808
+ const exitCode = await proc.exited;
17809
+ if (timedOut) {
17810
+ throw new GitError(`git ${args.join(" ")} timed out after ${this.timeoutMs}ms`, `git ${args.join(" ")}`, exitCode);
17811
+ }
17812
+ return {
17813
+ stdout: stdout.trim(),
17814
+ stderr: stderr.trim(),
17815
+ exitCode
17816
+ };
17817
+ } finally {
17818
+ clearTimeout(timer);
17819
+ }
17793
17820
  }
17794
17821
  async execOrError(args, cwd) {
17795
17822
  const result = await this.exec(args, cwd);
@@ -17840,7 +17867,7 @@ class GitService {
17840
17867
  return result.stdout;
17841
17868
  }
17842
17869
  withCwd(cwd) {
17843
- return new GitService(cwd);
17870
+ return new GitService(cwd, { timeoutMs: this.timeoutMs });
17844
17871
  }
17845
17872
  }
17846
17873
  // src/services/context.service.ts
@@ -17940,6 +17967,12 @@ class ContextService {
17940
17967
  }
17941
17968
  return result.context;
17942
17969
  }
17970
+ async requireRepoContextFor(options, context) {
17971
+ return this.requireRepoContext({
17972
+ ...context.globalOptions,
17973
+ ...options
17974
+ });
17975
+ }
17943
17976
  buildRepoNotFoundMessage(reason, remoteUrl) {
17944
17977
  const fallback = "Use --workspace and --repo options, or run this command from within a Bitbucket repository.";
17945
17978
  switch (reason) {
@@ -18571,6 +18604,15 @@ class OutputService {
18571
18604
  text(message) {
18572
18605
  console.log(stripControl(message));
18573
18606
  }
18607
+ truncate(text, maxLength, suffix = "...") {
18608
+ if (maxLength <= 0 || text.length <= maxLength) {
18609
+ return text;
18610
+ }
18611
+ if (suffix.length >= maxLength) {
18612
+ return text.slice(0, maxLength);
18613
+ }
18614
+ return text.slice(0, maxLength - suffix.length) + suffix;
18615
+ }
18574
18616
  formatDate(date) {
18575
18617
  const d = typeof date === "string" ? new Date(date) : date;
18576
18618
  return d.toLocaleDateString("en-US", {
@@ -18640,7 +18682,17 @@ function projectByFieldsRespectingWrapper(data, fields) {
18640
18682
  return projectFields(data, fields);
18641
18683
  }
18642
18684
  async function runJq(data, expression) {
18643
- const jq = await Promise.resolve().then(() => __toESM(require_dist(), 1));
18685
+ let jq;
18686
+ try {
18687
+ jq = await Promise.resolve().then(() => __toESM(require_dist(), 1));
18688
+ } catch (error) {
18689
+ throw new BBError({
18690
+ code: 8001 /* JQ_FAILED */,
18691
+ message: "Failed to load the embedded jq runtime (jq-wasm). Reinstall the CLI or report this issue.",
18692
+ cause: error instanceof Error ? error : undefined,
18693
+ context: { expression }
18694
+ });
18695
+ }
18644
18696
  let result;
18645
18697
  try {
18646
18698
  result = await jq.raw(data, expression);
@@ -18812,7 +18864,11 @@ class VersionService {
18812
18864
  latestVersion,
18813
18865
  updateAvailable
18814
18866
  };
18815
- } catch {
18867
+ } catch (error) {
18868
+ if (process.env.DEBUG === "true") {
18869
+ const message = error instanceof Error ? error.message : String(error);
18870
+ console.error(`[version-check] skipped: ${message}`);
18871
+ }
18816
18872
  return null;
18817
18873
  }
18818
18874
  }
@@ -22946,7 +23002,12 @@ class OAuthService {
22946
23002
  try {
22947
23003
  const open2 = (await Promise.resolve().then(() => (init_open(), exports_open))).default;
22948
23004
  await open2(authUrl);
22949
- } catch {}
23005
+ } catch (err) {
23006
+ if (process.env.DEBUG === "true") {
23007
+ const message = err instanceof Error ? err.message : String(err);
23008
+ console.error(`[oauth] could not open browser: ${message}`);
23009
+ }
23010
+ }
22950
23011
  console.error(`If the browser doesn't open, visit:
22951
23012
  ${authUrl}
22952
23013
  `);
@@ -27267,6 +27328,18 @@ class BaseCommand {
27267
27328
  }
27268
27329
  return parsed;
27269
27330
  }
27331
+ parsePositiveInt(value, name) {
27332
+ const trimmed = value.trim();
27333
+ const parsed = Number.parseInt(trimmed, 10);
27334
+ if (!Number.isFinite(parsed) || parsed < 1 || String(parsed) !== trimmed) {
27335
+ throw new BBError({
27336
+ code: 5002 /* VALIDATION_INVALID */,
27337
+ message: this.appendHelpHint(`--${name} must be a positive integer.`),
27338
+ context: { [name]: value }
27339
+ });
27340
+ }
27341
+ return parsed;
27342
+ }
27270
27343
  parseEnumOption(value, name, allowed) {
27271
27344
  if (!allowed.includes(value)) {
27272
27345
  throw new BBError({
@@ -28094,10 +28167,7 @@ class ListDefaultReviewersCommand extends BaseCommand {
28094
28167
  this.contextService = contextService;
28095
28168
  }
28096
28169
  async execute(options, context) {
28097
- const repoContext = await this.contextService.requireRepoContext({
28098
- ...context.globalOptions,
28099
- ...options
28100
- });
28170
+ const repoContext = await this.contextService.requireRepoContextFor(options, context);
28101
28171
  const mode = options.repoOnly ? "direct" : "effective";
28102
28172
  const reviewers = await this.defaultReviewerService.list(repoContext, mode);
28103
28173
  if (context.globalOptions.json) {
@@ -28140,10 +28210,7 @@ class AddDefaultReviewerCommand extends BaseCommand {
28140
28210
  this.contextService = contextService;
28141
28211
  }
28142
28212
  async execute(options, context) {
28143
- const repoContext = await this.contextService.requireRepoContext({
28144
- ...context.globalOptions,
28145
- ...options
28146
- });
28213
+ const repoContext = await this.contextService.requireRepoContextFor(options, context);
28147
28214
  const userResponse = await this.usersApi.usersSelectedUserGet({
28148
28215
  selectedUser: options.username
28149
28216
  });
@@ -28177,10 +28244,7 @@ class RemoveDefaultReviewerCommand extends BaseCommand {
28177
28244
  this.contextService = contextService;
28178
28245
  }
28179
28246
  async execute(options, context) {
28180
- const repoContext = await this.contextService.requireRepoContext({
28181
- ...context.globalOptions,
28182
- ...options
28183
- });
28247
+ const repoContext = await this.contextService.requireRepoContextFor(options, context);
28184
28248
  if (!options.yes) {
28185
28249
  throw new BBError({
28186
28250
  code: 5001 /* VALIDATION_REQUIRED */,
@@ -28232,10 +28296,7 @@ class CreatePRCommand extends BaseCommand {
28232
28296
  message: this.appendHelpHint("Pull request title is required. Use --title option.")
28233
28297
  });
28234
28298
  }
28235
- const repoContext = await this.contextService.requireRepoContext({
28236
- ...context.globalOptions,
28237
- ...options
28238
- });
28299
+ const repoContext = await this.contextService.requireRepoContextFor(options, context);
28239
28300
  let sourceBranch = options.source;
28240
28301
  if (!sourceBranch) {
28241
28302
  sourceBranch = await this.gitService.getCurrentBranch();
@@ -28360,10 +28421,7 @@ class ListPRsCommand extends BaseCommand {
28360
28421
  this.contextService = contextService;
28361
28422
  }
28362
28423
  async execute(options, context) {
28363
- const repoContext = await this.contextService.requireRepoContext({
28364
- ...context.globalOptions,
28365
- ...options
28366
- });
28424
+ const repoContext = await this.contextService.requireRepoContextFor(options, context);
28367
28425
  const state = options.state ? this.parseEnumOption(options.state, "state", PR_STATES) : "OPEN";
28368
28426
  const limit = parseLimit(options.limit);
28369
28427
  const reviewerQuery = options.mine ? await this.buildMineFilter() : undefined;
@@ -28407,19 +28465,13 @@ class ListPRsCommand extends BaseCommand {
28407
28465
  const destination = pr.destination;
28408
28466
  return [
28409
28467
  `#${pr.id}`,
28410
- this.truncate(title ?? "", 50),
28468
+ this.output.truncate(title ?? "", 50),
28411
28469
  pr.author?.display_name ?? "Unknown",
28412
28470
  `${source?.branch?.name ?? "unknown"} \u2192 ${destination?.branch?.name ?? "unknown"}`
28413
28471
  ];
28414
28472
  });
28415
28473
  this.output.table(["ID", "TITLE", "AUTHOR", "BRANCHES"], rows);
28416
28474
  }
28417
- truncate(text, maxLength) {
28418
- if (text.length <= maxLength) {
28419
- return text;
28420
- }
28421
- return text.substring(0, maxLength - 3) + "...";
28422
- }
28423
28475
  async buildMineFilter() {
28424
28476
  const response = await this.usersApi.userGet();
28425
28477
  const userUuid = response.data.uuid;
@@ -28443,11 +28495,8 @@ class ViewPRCommand extends BaseCommand {
28443
28495
  this.contextService = contextService;
28444
28496
  }
28445
28497
  async execute(options, context) {
28446
- const repoContext = await this.contextService.requireRepoContext({
28447
- ...context.globalOptions,
28448
- ...options
28449
- });
28450
- const prId = this.parseIntOption(options.id, "id");
28498
+ const repoContext = await this.contextService.requireRepoContextFor(options, context);
28499
+ const prId = this.parsePositiveInt(options.id, "id");
28451
28500
  const response = await this.pullrequestsApi.repositoriesWorkspaceRepoSlugPullrequestsPullRequestIdGet({
28452
28501
  workspace: repoContext.workspace,
28453
28502
  repoSlug: repoContext.repoSlug,
@@ -28572,13 +28621,10 @@ class EditPRCommand extends BaseCommand {
28572
28621
  this.gitService = gitService;
28573
28622
  }
28574
28623
  async execute(options, context) {
28575
- const repoContext = await this.contextService.requireRepoContext({
28576
- ...context.globalOptions,
28577
- ...options
28578
- });
28624
+ const repoContext = await this.contextService.requireRepoContextFor(options, context);
28579
28625
  let prId;
28580
28626
  if (options.id) {
28581
- prId = Number.parseInt(options.id, 10);
28627
+ prId = this.parsePositiveInt(options.id, "id");
28582
28628
  } else {
28583
28629
  const currentBranch = await this.gitService.getCurrentBranch();
28584
28630
  const matches = await collectPages({
@@ -28653,7 +28699,7 @@ class EditPRCommand extends BaseCommand {
28653
28699
  this.output.success(`Updated pull request #${pr.id}`);
28654
28700
  this.output.text(` ${this.output.dim("Title:")} ${pr.title}`);
28655
28701
  if (pr.description) {
28656
- const truncatedDesc = pr.description.length > 100 ? pr.description.substring(0, 100) + "..." : pr.description;
28702
+ const truncatedDesc = this.output.truncate(pr.description, 100);
28657
28703
  this.output.text(` ${this.output.dim("Description:")} ${truncatedDesc}`);
28658
28704
  }
28659
28705
  this.output.text(` ${this.output.dim("URL:")} ${links?.html?.href}`);
@@ -28674,11 +28720,8 @@ class MergePRCommand extends BaseCommand {
28674
28720
  this.contextService = contextService;
28675
28721
  }
28676
28722
  async execute(options, context) {
28677
- const repoContext = await this.contextService.requireRepoContext({
28678
- ...context.globalOptions,
28679
- ...options
28680
- });
28681
- const prId = this.parseIntOption(options.id, "id");
28723
+ const repoContext = await this.contextService.requireRepoContextFor(options, context);
28724
+ const prId = this.parsePositiveInt(options.id, "id");
28682
28725
  const request = {
28683
28726
  type: "pullrequest_merge_parameters"
28684
28727
  };
@@ -28722,11 +28765,8 @@ class ApprovePRCommand extends BaseCommand {
28722
28765
  this.contextService = contextService;
28723
28766
  }
28724
28767
  async execute(options, context) {
28725
- const repoContext = await this.contextService.requireRepoContext({
28726
- ...context.globalOptions,
28727
- ...options
28728
- });
28729
- const prId = Number.parseInt(options.id, 10);
28768
+ const repoContext = await this.contextService.requireRepoContextFor(options, context);
28769
+ const prId = this.parsePositiveInt(options.id, "id");
28730
28770
  await this.pullrequestsApi.repositoriesWorkspaceRepoSlugPullrequestsPullRequestIdApprovePost({
28731
28771
  workspace: repoContext.workspace,
28732
28772
  repoSlug: repoContext.repoSlug,
@@ -28755,11 +28795,8 @@ class DeclinePRCommand extends BaseCommand {
28755
28795
  this.contextService = contextService;
28756
28796
  }
28757
28797
  async execute(options, context) {
28758
- const repoContext = await this.contextService.requireRepoContext({
28759
- ...context.globalOptions,
28760
- ...options
28761
- });
28762
- const prId = Number.parseInt(options.id, 10);
28798
+ const repoContext = await this.contextService.requireRepoContextFor(options, context);
28799
+ const prId = this.parsePositiveInt(options.id, "id");
28763
28800
  const response = await this.pullrequestsApi.repositoriesWorkspaceRepoSlugPullrequestsPullRequestIdDeclinePost({
28764
28801
  workspace: repoContext.workspace,
28765
28802
  repoSlug: repoContext.repoSlug,
@@ -28790,11 +28827,8 @@ class ReadyPRCommand extends BaseCommand {
28790
28827
  this.contextService = contextService;
28791
28828
  }
28792
28829
  async execute(options, context) {
28793
- const repoContext = await this.contextService.requireRepoContext({
28794
- ...context.globalOptions,
28795
- ...options
28796
- });
28797
- const prId = Number.parseInt(options.id, 10);
28830
+ const repoContext = await this.contextService.requireRepoContextFor(options, context);
28831
+ const prId = this.parsePositiveInt(options.id, "id");
28798
28832
  const response = await this.pullrequestsApi.repositoriesWorkspaceRepoSlugPullrequestsPullRequestIdPut({
28799
28833
  workspace: repoContext.workspace,
28800
28834
  repoSlug: repoContext.repoSlug,
@@ -28832,11 +28866,8 @@ class CheckoutPRCommand extends BaseCommand {
28832
28866
  this.gitService = gitService;
28833
28867
  }
28834
28868
  async execute(options, context) {
28835
- const repoContext = await this.contextService.requireRepoContext({
28836
- ...context.globalOptions,
28837
- ...options
28838
- });
28839
- const prId = Number.parseInt(options.id, 10);
28869
+ const repoContext = await this.contextService.requireRepoContextFor(options, context);
28870
+ const prId = this.parsePositiveInt(options.id, "id");
28840
28871
  const prResponse = await this.pullrequestsApi.repositoriesWorkspaceRepoSlugPullrequestsPullRequestIdGet({
28841
28872
  workspace: repoContext.workspace,
28842
28873
  repoSlug: repoContext.repoSlug,
@@ -28899,20 +28930,10 @@ class DiffPRCommand extends BaseCommand {
28899
28930
  this.gitService = gitService;
28900
28931
  }
28901
28932
  async execute(options, context) {
28902
- const repoContext = await this.contextService.requireRepoContext({
28903
- ...context.globalOptions,
28904
- ...options
28905
- });
28933
+ const repoContext = await this.contextService.requireRepoContextFor(options, context);
28906
28934
  let prId;
28907
28935
  if (options.id) {
28908
- prId = Number.parseInt(options.id, 10);
28909
- if (Number.isNaN(prId)) {
28910
- throw new BBError({
28911
- code: 5002 /* VALIDATION_INVALID */,
28912
- message: "Invalid PR ID",
28913
- context: { id: options.id }
28914
- });
28915
- }
28936
+ prId = this.parsePositiveInt(options.id, "id");
28916
28937
  } else {
28917
28938
  const currentBranch = await this.gitService.getCurrentBranch();
28918
28939
  const matches = await collectPages({
@@ -29129,11 +29150,8 @@ class ActivityPRCommand extends BaseCommand {
29129
29150
  this.contextService = contextService;
29130
29151
  }
29131
29152
  async execute(options, context) {
29132
- const repoContext = await this.contextService.requireRepoContext({
29133
- ...context.globalOptions,
29134
- ...options
29135
- });
29136
- const prId = this.parseIntOption(options.id, "id");
29153
+ const repoContext = await this.contextService.requireRepoContextFor(options, context);
29154
+ const prId = this.parsePositiveInt(options.id, "id");
29137
29155
  const filterTypes = this.parseTypeFilter(options.type);
29138
29156
  const limit = parseLimit(options.limit);
29139
29157
  const activities = await collectPages({
@@ -29242,14 +29260,14 @@ class ActivityPRCommand extends BaseCommand {
29242
29260
  case "comment": {
29243
29261
  const content = getRawContent(activity.comment?.content) ?? "";
29244
29262
  const id = activity.comment?.id ? `#${activity.comment.id}` : "";
29245
- const snippet = this.truncate(content, 80);
29263
+ const snippet = this.output.truncate(content, 80);
29246
29264
  return [id, snippet].filter(Boolean).join(" ");
29247
29265
  }
29248
29266
  case "approval":
29249
29267
  return "approved";
29250
29268
  case "changes_requested": {
29251
29269
  const reason = activity.changes_requested?.reason;
29252
- return reason ? this.truncate(reason, 80) : "changes requested";
29270
+ return reason ? this.output.truncate(reason, 80) : "changes requested";
29253
29271
  }
29254
29272
  case "merge":
29255
29273
  return this.formatCommitDetail(activity.merge?.commit?.hash, "merged");
@@ -29262,7 +29280,7 @@ class ActivityPRCommand extends BaseCommand {
29262
29280
  return `state: ${activity.update.state}`;
29263
29281
  }
29264
29282
  if (activity.update?.title) {
29265
- return `title: ${this.truncate(activity.update.title, 60)}`;
29283
+ return `title: ${this.output.truncate(activity.update.title, 60)}`;
29266
29284
  }
29267
29285
  if (activity.update?.description) {
29268
29286
  return "description updated";
@@ -29280,12 +29298,6 @@ class ActivityPRCommand extends BaseCommand {
29280
29298
  const shortHash = hash.slice(0, 7);
29281
29299
  return label ? `${label} ${shortHash}` : shortHash;
29282
29300
  }
29283
- truncate(text, maxLength) {
29284
- if (text.length <= maxLength) {
29285
- return text;
29286
- }
29287
- return text.substring(0, maxLength - 3) + "...";
29288
- }
29289
29301
  }
29290
29302
 
29291
29303
  // src/commands/pr/comment.command.ts
@@ -29319,33 +29331,14 @@ class CommentPRCommand extends BaseCommand {
29319
29331
  }
29320
29332
  });
29321
29333
  }
29322
- if (options.lineTo) {
29323
- const parsed = Number.parseInt(options.lineTo, 10);
29324
- if (Number.isNaN(parsed) || parsed < 1) {
29325
- throw new BBError({
29326
- code: 5002 /* VALIDATION_INVALID */,
29327
- message: "--line-to must be a positive integer"
29328
- });
29329
- }
29330
- }
29331
- if (options.lineFrom) {
29332
- const parsed = Number.parseInt(options.lineFrom, 10);
29333
- if (Number.isNaN(parsed) || parsed < 1) {
29334
- throw new BBError({
29335
- code: 5002 /* VALIDATION_INVALID */,
29336
- message: "--line-from must be a positive integer"
29337
- });
29338
- }
29339
- }
29340
- const repoContext = await this.contextService.requireRepoContext({
29341
- ...context.globalOptions,
29342
- ...options
29343
- });
29344
- const prId = Number.parseInt(options.id, 10);
29334
+ const lineTo = options.lineTo ? this.parsePositiveInt(options.lineTo, "line-to") : undefined;
29335
+ const lineFrom = options.lineFrom ? this.parsePositiveInt(options.lineFrom, "line-from") : undefined;
29336
+ const repoContext = await this.contextService.requireRepoContextFor(options, context);
29337
+ const prId = this.parsePositiveInt(options.id, "id");
29345
29338
  const inline = options.file ? {
29346
29339
  path: options.file,
29347
- ...options.lineTo ? { to: Number.parseInt(options.lineTo, 10) } : {},
29348
- ...options.lineFrom ? { from: Number.parseInt(options.lineFrom, 10) } : {}
29340
+ ...lineTo !== undefined ? { to: lineTo } : {},
29341
+ ...lineFrom !== undefined ? { from: lineFrom } : {}
29349
29342
  } : undefined;
29350
29343
  const body = {
29351
29344
  content: {
@@ -29395,11 +29388,8 @@ class ListCommentsPRCommand extends BaseCommand {
29395
29388
  this.contextService = contextService;
29396
29389
  }
29397
29390
  async execute(options, context) {
29398
- const repoContext = await this.contextService.requireRepoContext({
29399
- ...context.globalOptions,
29400
- ...options
29401
- });
29402
- const prId = this.parseIntOption(options.id, "id");
29391
+ const repoContext = await this.contextService.requireRepoContextFor(options, context);
29392
+ const prId = this.parsePositiveInt(options.id, "id");
29403
29393
  const limit = parseLimit(options.limit);
29404
29394
  const values = await collectPages({
29405
29395
  limit,
@@ -29416,6 +29406,8 @@ class ListCommentsPRCommand extends BaseCommand {
29416
29406
  });
29417
29407
  if (context.globalOptions.json) {
29418
29408
  await this.output.json({
29409
+ workspace: repoContext.workspace,
29410
+ repoSlug: repoContext.repoSlug,
29419
29411
  pullRequestId: prId,
29420
29412
  count: values.length,
29421
29413
  comments: values
@@ -29431,7 +29423,7 @@ class ListCommentsPRCommand extends BaseCommand {
29431
29423
  return [
29432
29424
  comment.id?.toString() ?? "",
29433
29425
  getUserDisplayName(comment.user) ?? "Unknown",
29434
- comment.deleted ? "[deleted]" : options.truncate === false ? content : content.slice(0, 60) + (content.length > 60 ? "..." : ""),
29426
+ comment.deleted ? "[deleted]" : options.truncate === false ? content : this.output.truncate(content, 60),
29435
29427
  this.output.formatDate(comment.created_on ?? "")
29436
29428
  ];
29437
29429
  });
@@ -29451,12 +29443,9 @@ class EditCommentPRCommand extends BaseCommand {
29451
29443
  this.contextService = contextService;
29452
29444
  }
29453
29445
  async execute(options, context) {
29454
- const repoContext = await this.contextService.requireRepoContext({
29455
- ...context.globalOptions,
29456
- ...options
29457
- });
29458
- const prId = this.parseIntOption(options.prId, "pr-id");
29459
- const commentId = this.parseIntOption(options.commentId, "comment-id");
29446
+ const repoContext = await this.contextService.requireRepoContextFor(options, context);
29447
+ const prId = this.parsePositiveInt(options.prId, "pr-id");
29448
+ const commentId = this.parsePositiveInt(options.commentId, "comment-id");
29460
29449
  const response = await this.pullrequestsApi.repositoriesWorkspaceRepoSlugPullrequestsPullRequestIdCommentsCommentIdPut({
29461
29450
  workspace: repoContext.workspace,
29462
29451
  repoSlug: repoContext.repoSlug,
@@ -29494,12 +29483,9 @@ class DeleteCommentPRCommand extends BaseCommand {
29494
29483
  this.contextService = contextService;
29495
29484
  }
29496
29485
  async execute(options, context) {
29497
- const repoContext = await this.contextService.requireRepoContext({
29498
- ...context.globalOptions,
29499
- ...options
29500
- });
29501
- const prId = this.parseIntOption(options.prId, "pr-id");
29502
- const commentId = this.parseIntOption(options.commentId, "comment-id");
29486
+ const repoContext = await this.contextService.requireRepoContextFor(options, context);
29487
+ const prId = this.parsePositiveInt(options.prId, "pr-id");
29488
+ const commentId = this.parsePositiveInt(options.commentId, "comment-id");
29503
29489
  if (!options.yes) {
29504
29490
  throw new BBError({
29505
29491
  code: 5001 /* VALIDATION_REQUIRED */,
@@ -29539,11 +29525,8 @@ class AddReviewerPRCommand extends BaseCommand {
29539
29525
  this.contextService = contextService;
29540
29526
  }
29541
29527
  async execute(options, context) {
29542
- const repoContext = await this.contextService.requireRepoContext({
29543
- ...context.globalOptions,
29544
- ...options
29545
- });
29546
- const prId = this.parseIntOption(options.id, "id");
29528
+ const repoContext = await this.contextService.requireRepoContextFor(options, context);
29529
+ const prId = this.parsePositiveInt(options.id, "id");
29547
29530
  const userResponse = await this.usersApi.usersSelectedUserGet({
29548
29531
  selectedUser: options.username
29549
29532
  });
@@ -29584,11 +29567,8 @@ class RemoveReviewerPRCommand extends BaseCommand {
29584
29567
  this.contextService = contextService;
29585
29568
  }
29586
29569
  async execute(options, context) {
29587
- const repoContext = await this.contextService.requireRepoContext({
29588
- ...context.globalOptions,
29589
- ...options
29590
- });
29591
- const prId = this.parseIntOption(options.id, "id");
29570
+ const repoContext = await this.contextService.requireRepoContextFor(options, context);
29571
+ const prId = this.parsePositiveInt(options.id, "id");
29592
29572
  const userResponse = await this.usersApi.usersSelectedUserGet({
29593
29573
  selectedUser: options.username
29594
29574
  });
@@ -29622,11 +29602,8 @@ class ListReviewersPRCommand extends BaseCommand {
29622
29602
  this.contextService = contextService;
29623
29603
  }
29624
29604
  async execute(options, context) {
29625
- const repoContext = await this.contextService.requireRepoContext({
29626
- ...context.globalOptions,
29627
- ...options
29628
- });
29629
- const prId = this.parseIntOption(options.id, "id");
29605
+ const repoContext = await this.contextService.requireRepoContextFor(options, context);
29606
+ const prId = this.parsePositiveInt(options.id, "id");
29630
29607
  const response = await this.pullrequestsApi.repositoriesWorkspaceRepoSlugPullrequestsPullRequestIdGet({
29631
29608
  workspace: repoContext.workspace,
29632
29609
  repoSlug: repoContext.repoSlug,
@@ -29636,6 +29613,8 @@ class ListReviewersPRCommand extends BaseCommand {
29636
29613
  const reviewers = Array.from(pr.reviewers ?? []);
29637
29614
  if (context.globalOptions.json) {
29638
29615
  await this.output.json({
29616
+ workspace: repoContext.workspace,
29617
+ repoSlug: repoContext.repoSlug,
29639
29618
  pullRequestId: prId,
29640
29619
  count: reviewers.length,
29641
29620
  reviewers
@@ -29662,11 +29641,8 @@ class ChecksPRCommand extends BaseCommand {
29662
29641
  this.contextService = contextService;
29663
29642
  }
29664
29643
  async execute(options, context) {
29665
- const repoContext = await this.contextService.requireRepoContext({
29666
- ...context.globalOptions,
29667
- ...options
29668
- });
29669
- const prId = this.parseIntOption(options.id, "id");
29644
+ const repoContext = await this.contextService.requireRepoContextFor(options, context);
29645
+ const prId = this.parsePositiveInt(options.id, "id");
29670
29646
  const response = await this.commitStatusesApi.repositoriesWorkspaceRepoSlugPullrequestsPullRequestIdStatusesGet({
29671
29647
  workspace: repoContext.workspace,
29672
29648
  repoSlug: repoContext.repoSlug,
@@ -29720,7 +29696,7 @@ class ChecksPRCommand extends BaseCommand {
29720
29696
  return [
29721
29697
  `${stateIcon} ${stateLabel}`,
29722
29698
  this.output.bold(name),
29723
- this.truncate(description, 40),
29699
+ this.output.truncate(description, 40),
29724
29700
  status.updated_on ? this.output.formatDate(status.updated_on) : "-"
29725
29701
  ];
29726
29702
  });
@@ -29770,12 +29746,6 @@ class ChecksPRCommand extends BaseCommand {
29770
29746
  return acc;
29771
29747
  }, { successful: 0, failed: 0, pending: 0 });
29772
29748
  }
29773
- truncate(text, maxLength) {
29774
- if (text.length <= maxLength) {
29775
- return text;
29776
- }
29777
- return text.substring(0, maxLength - 3) + "...";
29778
- }
29779
29749
  }
29780
29750
 
29781
29751
  // src/commands/snippet/list.command.ts
@@ -30188,7 +30158,7 @@ class ListSnippetCommentsCommand extends BaseCommand {
30188
30158
  String(comment.id ?? ""),
30189
30159
  getUserDisplayName(comment.user) ?? "Unknown",
30190
30160
  this.output.formatDate(comment.created_on ?? ""),
30191
- content.slice(0, 60) + (content.length > 60 ? "..." : "")
30161
+ this.output.truncate(content, 60)
30192
30162
  ];
30193
30163
  });
30194
30164
  this.output.table(["ID", "AUTHOR", "DATE", "CONTENT"], rows);
@@ -30247,7 +30217,7 @@ class EditSnippetCommentCommand extends BaseCommand {
30247
30217
  }
30248
30218
  async execute(options, context) {
30249
30219
  const workspace = await this.contextService.requireWorkspace(options.workspace ?? context.globalOptions.workspace);
30250
- const commentId = this.parseIntOption(options.commentId, "comment-id");
30220
+ const commentId = this.parsePositiveInt(options.commentId, "comment-id");
30251
30221
  const body = {
30252
30222
  type: "snippet_comment",
30253
30223
  content: {
@@ -30285,7 +30255,7 @@ class DeleteSnippetCommentCommand extends BaseCommand {
30285
30255
  }
30286
30256
  async execute(options, context) {
30287
30257
  const workspace = await this.contextService.requireWorkspace(options.workspace ?? context.globalOptions.workspace);
30288
- const commentId = this.parseIntOption(options.commentId, "comment-id");
30258
+ const commentId = this.parsePositiveInt(options.commentId, "comment-id");
30289
30259
  if (!options.yes) {
30290
30260
  throw new BBError({
30291
30261
  code: 5001 /* VALIDATION_REQUIRED */,
@@ -30535,10 +30505,7 @@ class BrowseCommand extends BaseCommand {
30535
30505
  this.urlBuilder = urlBuilder;
30536
30506
  }
30537
30507
  async execute(options, context) {
30538
- const repoContext = await this.contextService.requireRepoContext({
30539
- ...context.globalOptions,
30540
- ...options
30541
- });
30508
+ const repoContext = await this.contextService.requireRepoContextFor(options, context);
30542
30509
  this.validateFlagCombination(options);
30543
30510
  const url2 = await this.resolveUrl(options, repoContext);
30544
30511
  const useJson = Boolean(context.globalOptions.json);
@@ -30602,7 +30569,7 @@ class BrowseCommand extends BaseCommand {
30602
30569
  const target = options.target?.trim();
30603
30570
  if (target && target.length > 0) {
30604
30571
  if (PR_NUMBER_PATTERN.test(target)) {
30605
- return this.urlBuilder.pullRequest(ctx, Number.parseInt(target, 10));
30572
+ return this.urlBuilder.pullRequest(ctx, this.parsePositiveInt(target, "target"));
30606
30573
  }
30607
30574
  if (SHA_PATTERN.test(target)) {
30608
30575
  return this.urlBuilder.commit(ctx, target);
@@ -30686,17 +30653,6 @@ class BrowseCommand extends BaseCommand {
30686
30653
  return "HEAD";
30687
30654
  }
30688
30655
  }
30689
- parsePositiveInt(value, name) {
30690
- const parsed = Number.parseInt(value, 10);
30691
- if (!Number.isFinite(parsed) || parsed <= 0 || String(parsed) !== value.trim()) {
30692
- throw new BBError({
30693
- code: 5002 /* VALIDATION_INVALID */,
30694
- message: this.appendHelpHint(`--${name} must be a positive integer.`),
30695
- context: { [name]: value }
30696
- });
30697
- }
30698
- return parsed;
30699
- }
30700
30656
  async openInBrowser(url2) {
30701
30657
  this.output.info(`Opening ${url2} in your browser...`);
30702
30658
  const open2 = (await Promise.resolve().then(() => (init_open(), exports_open))).default;
@@ -31841,3 +31797,6 @@ if (typeof Bun === "undefined") {
31841
31797
  process.exit(1);
31842
31798
  }
31843
31799
  cli.parse(process.argv);
31800
+
31801
+ //# debugId=A7729A51C3738B3664756E2164756E21
31802
+ //# sourceMappingURL=index.js.map