paperclip-github-plugin 0.5.0 → 0.5.2

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/ui/index.js CHANGED
@@ -22817,6 +22817,14 @@ var HOST_DESTRUCTIVE_BUTTON_CLASSNAME = [
22817
22817
  "bg-destructive text-white hover:bg-destructive/90",
22818
22818
  "focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40"
22819
22819
  ].join(" ");
22820
+ var HOST_SUCCESS_BUTTON_CLASSNAME = [
22821
+ HOST_BUTTON_BASE_CLASSNAME,
22822
+ "ghsync__button-tone ghsync__button-tone--success"
22823
+ ].join(" ");
22824
+ var HOST_WARNING_BUTTON_CLASSNAME = [
22825
+ HOST_BUTTON_BASE_CLASSNAME,
22826
+ "ghsync__button-tone ghsync__button-tone--warning"
22827
+ ].join(" ");
22820
22828
  var HOST_TOOLBAR_BUTTON_SIZE_CLASSNAME = "px-3 has-[>svg]:px-2.5";
22821
22829
  var HOST_ACTION_BUTTON_SIZE_CLASSNAME = "h-9 px-4 py-2 has-[>svg]:px-3";
22822
22830
  var HOST_INLINE_BUTTON_SIZE_CLASSNAME = "h-8 px-3 has-[>svg]:px-2.5";
@@ -22845,7 +22853,7 @@ var PREVIEW_MARKDOWN_REHYPE_PLUGINS = [rehypeRaw, PREVIEW_MARKDOWN_SANITIZE_REHY
22845
22853
  function getPluginActionClassName(options) {
22846
22854
  const variant = options?.variant ?? "secondary";
22847
22855
  const size = options?.size ?? "default";
22848
- const variantClassName = variant === "primary" ? HOST_DEFAULT_BUTTON_CLASSNAME : variant === "danger" ? HOST_DESTRUCTIVE_BUTTON_CLASSNAME : HOST_OUTLINE_BUTTON_CLASSNAME;
22856
+ const variantClassName = variant === "primary" ? HOST_DEFAULT_BUTTON_CLASSNAME : variant === "success" ? HOST_SUCCESS_BUTTON_CLASSNAME : variant === "warning" ? HOST_WARNING_BUTTON_CLASSNAME : variant === "danger" ? HOST_DESTRUCTIVE_BUTTON_CLASSNAME : HOST_OUTLINE_BUTTON_CLASSNAME;
22849
22857
  const sizeClassName = size === "sm" ? HOST_INLINE_BUTTON_SIZE_CLASSNAME : HOST_ACTION_BUTTON_SIZE_CLASSNAME;
22850
22858
  return ["ghsync__button", variantClassName, sizeClassName, options?.extraClassName].filter(Boolean).join(" ");
22851
22859
  }
@@ -22882,6 +22890,7 @@ function GitHubButtonLabel(props) {
22882
22890
  ] });
22883
22891
  }
22884
22892
  var PROJECT_PULL_REQUESTS_PAGE_ROUTE_PATH = "github-pull-requests";
22893
+ var QUICK_REQUEST_CHANGES_REVIEW_SUMMARY = "Requested changes.";
22885
22894
  var LIGHT_PALETTE = {
22886
22895
  text: "#18181b",
22887
22896
  title: "#09090b",
@@ -23356,6 +23365,32 @@ var SHARED_LOADING_STYLES = `
23356
23365
  min-width: 0;
23357
23366
  }
23358
23367
 
23368
+ .ghsync__button-tone {
23369
+ border: 1px solid transparent;
23370
+ }
23371
+
23372
+ .ghsync__button-tone--success {
23373
+ border-color: var(--ghsync-success-border);
23374
+ background: var(--ghsync-success-bg);
23375
+ color: var(--ghsync-success-text);
23376
+ }
23377
+
23378
+ .ghsync__button-tone--success:hover {
23379
+ background: color-mix(in srgb, var(--ghsync-success-bg) 72%, var(--ghsync-success-border));
23380
+ color: var(--ghsync-success-text);
23381
+ }
23382
+
23383
+ .ghsync__button-tone--warning {
23384
+ border-color: var(--ghsync-warning-border);
23385
+ background: var(--ghsync-warning-bg);
23386
+ color: var(--ghsync-warning-text);
23387
+ }
23388
+
23389
+ .ghsync__button-tone--warning:hover {
23390
+ background: color-mix(in srgb, var(--ghsync-warning-bg) 72%, var(--ghsync-warning-border));
23391
+ color: var(--ghsync-warning-text);
23392
+ }
23393
+
23359
23394
  .ghsync__loading-inline {
23360
23395
  display: inline-flex;
23361
23396
  align-items: center;
@@ -25063,6 +25098,36 @@ var PROJECT_PULL_REQUESTS_PAGE_STYLES = `
25063
25098
  opacity: 0.42;
25064
25099
  }
25065
25100
 
25101
+ .ghsync-prs-table__icon-button--success {
25102
+ color: var(--ghsync-success-text);
25103
+ }
25104
+
25105
+ .ghsync-prs-table__icon-button--warning {
25106
+ color: var(--ghsync-warning-text);
25107
+ }
25108
+
25109
+ .ghsync-prs-table__icon-button--danger {
25110
+ color: var(--ghsync-danger-text);
25111
+ }
25112
+
25113
+ .ghsync-prs-table__icon-button--success:hover {
25114
+ color: var(--ghsync-success-text);
25115
+ border-color: var(--ghsync-success-border);
25116
+ background: color-mix(in srgb, var(--ghsync-success-bg) 68%, var(--ghsync-surfaceRaised));
25117
+ }
25118
+
25119
+ .ghsync-prs-table__icon-button--warning:hover {
25120
+ color: var(--ghsync-warning-text);
25121
+ border-color: var(--ghsync-warning-border);
25122
+ background: color-mix(in srgb, var(--ghsync-warning-bg) 68%, var(--ghsync-surfaceRaised));
25123
+ }
25124
+
25125
+ .ghsync-prs-table__icon-button--danger:hover {
25126
+ color: var(--ghsync-danger-text);
25127
+ border-color: var(--ghsync-danger-border);
25128
+ background: color-mix(in srgb, var(--ghsync-danger-bg) 68%, var(--ghsync-surfaceRaised));
25129
+ }
25130
+
25066
25131
  .ghsync-prs-table__status--passed {
25067
25132
  color: var(--ghsync-success-text);
25068
25133
  }
@@ -27560,6 +27625,16 @@ function getPreviewPullRequestCheckToneClass(status) {
27560
27625
  return "ghsync-prs-table__status--pending";
27561
27626
  }
27562
27627
  }
27628
+ function getPreviewPullRequestInlineActionToneClass(tone) {
27629
+ switch (tone) {
27630
+ case "success":
27631
+ return "ghsync-prs-table__icon-button--success";
27632
+ case "warning":
27633
+ return "ghsync-prs-table__icon-button--warning";
27634
+ default:
27635
+ return "ghsync-prs-table__icon-button--danger";
27636
+ }
27637
+ }
27563
27638
  function getPreviewPullRequestUpToDateMeta(status) {
27564
27639
  switch (status) {
27565
27640
  case "up_to_date":
@@ -27714,8 +27789,13 @@ function resolvePreviewPullRequestReviewable(record) {
27714
27789
  const unresolvedCopilotThreads = typeof record.copilotUnresolvedReviewThreads === "number" ? record.copilotUnresolvedReviewThreads : record.unresolvedReviewThreads;
27715
27790
  return record.githubMergeable === true && record.checksStatus === "passed" && unresolvedCopilotThreads === 0;
27716
27791
  }
27717
- function resolvePreviewPullRequestMergeable(record) {
27718
- return record.githubMergeable === true && record.checksStatus === "passed" && record.reviewApprovals > 0 && record.unresolvedReviewThreads === 0;
27792
+ function resolvePreviewPullRequestTargetsDefaultBranch(record, options) {
27793
+ const baseBranch = record.baseBranch.trim();
27794
+ const defaultBranchName = options?.defaultBranchName?.trim();
27795
+ return Boolean(baseBranch && defaultBranchName && baseBranch === defaultBranchName);
27796
+ }
27797
+ function resolvePreviewPullRequestMergeable(record, options) {
27798
+ return record.githubMergeable === true && record.checksStatus === "passed" && record.reviewApprovals > 0 && record.reviewChangesRequested === 0 && record.unresolvedReviewThreads === 0 && resolvePreviewPullRequestTargetsDefaultBranch(record, options);
27719
27799
  }
27720
27800
  function matchesPreviewPullRequestFilter(record, filter) {
27721
27801
  switch (filter) {
@@ -28770,6 +28850,26 @@ function formatSyncFailureRepository(repositoryUrl) {
28770
28850
  }
28771
28851
  return repositoryUrl.trim();
28772
28852
  }
28853
+ function getLinkedPullRequestsForIssueDetails(issueDetails) {
28854
+ if (issueDetails.linkedPullRequests && issueDetails.linkedPullRequests.length > 0) {
28855
+ return issueDetails.linkedPullRequests;
28856
+ }
28857
+ return issueDetails.linkedPullRequestNumbers.map((pullRequestNumber) => ({
28858
+ number: pullRequestNumber,
28859
+ repositoryUrl: issueDetails.repositoryUrl
28860
+ }));
28861
+ }
28862
+ function formatIssueDetailLinkedPullRequestLabel(pullRequest, issueRepositoryUrl) {
28863
+ const pullRequestRepository = parseRepositoryReference(pullRequest.repositoryUrl);
28864
+ if (!pullRequestRepository) {
28865
+ return `PR #${pullRequest.number}`;
28866
+ }
28867
+ const issueRepository = parseRepositoryReference(issueRepositoryUrl);
28868
+ if (issueRepository && issueRepository.owner.toLowerCase() === pullRequestRepository.owner.toLowerCase() && issueRepository.repo.toLowerCase() === pullRequestRepository.repo.toLowerCase()) {
28869
+ return `PR #${pullRequest.number}`;
28870
+ }
28871
+ return `${pullRequestRepository.owner}/${pullRequestRepository.repo}#${pullRequest.number}`;
28872
+ }
28773
28873
  function getSyncFailureLogEntries(syncState) {
28774
28874
  if (syncState.recentFailures?.length) {
28775
28875
  return syncState.recentFailures.filter((entry) => typeof entry.message === "string" && entry.message.trim());
@@ -29353,6 +29453,7 @@ function GitHubSyncProjectPullRequestsPage() {
29353
29453
  const issueModalPending = issueModalPullRequest ? pendingActionKey === `create-issue:${issueModalPullRequest.id}` : false;
29354
29454
  const commentModalPending = commentModalPullRequest ? pendingActionKey === `comment-modal:${commentModalPullRequest.id}` : false;
29355
29455
  const reviewModalApprovePending = reviewModalPullRequest ? pendingActionKey === `review:${reviewModalPullRequest.id}:approve` : false;
29456
+ const reviewModalCommentPending = reviewModalPullRequest ? pendingActionKey === `review:${reviewModalPullRequest.id}:comment` : false;
29356
29457
  const reviewModalRequestChangesPending = reviewModalPullRequest ? pendingActionKey === `review:${reviewModalPullRequest.id}:request_changes` : false;
29357
29458
  const reviewModalPending = reviewModalPullRequest ? Boolean(pendingActionKey?.startsWith(`review:${reviewModalPullRequest.id}:`)) : false;
29358
29459
  const rerunCiModalPending = rerunCiModalPullRequest ? pendingActionKey === `rerun-ci:${rerunCiModalPullRequest.id}` : false;
@@ -29515,6 +29616,10 @@ function GitHubSyncProjectPullRequestsPage() {
29515
29616
  setCommentModalPullRequestId(pullRequestId);
29516
29617
  setCommentModalDraft("");
29517
29618
  }
29619
+ function openReviewModal(pullRequestId) {
29620
+ setReviewModalPullRequestId(pullRequestId);
29621
+ setReviewModalDraft("");
29622
+ }
29518
29623
  function openClosePullRequestModal(pullRequest) {
29519
29624
  setCloseModalPullRequest(pullRequest);
29520
29625
  }
@@ -29801,23 +29906,42 @@ function GitHubSyncProjectPullRequestsPage() {
29801
29906
  setPendingActionKey((current) => current === actionKey ? null : current);
29802
29907
  }
29803
29908
  }
29804
- async function handleReviewPullRequest(review) {
29805
- if (!reviewModalPullRequest || !hostContext.companyId || !projectId) {
29909
+ function getSubmittedReviewToast(review, pullRequestNumber) {
29910
+ switch (review) {
29911
+ case "approved":
29912
+ return {
29913
+ title: `Approved #${pullRequestNumber}`,
29914
+ body: "GitHub review submitted."
29915
+ };
29916
+ case "changes_requested":
29917
+ return {
29918
+ title: `Requested changes on #${pullRequestNumber}`,
29919
+ body: "GitHub change request submitted."
29920
+ };
29921
+ default:
29922
+ return {
29923
+ title: `Commented on #${pullRequestNumber}`,
29924
+ body: "GitHub review comment submitted."
29925
+ };
29926
+ }
29927
+ }
29928
+ async function submitPullRequestReview(pullRequest, review, body, options) {
29929
+ if (!hostContext.companyId || !projectId) {
29806
29930
  return;
29807
29931
  }
29808
- const actionKey = `review:${reviewModalPullRequest.id}:${review}`;
29932
+ const actionKey = `review:${pullRequest.id}:${review}`;
29809
29933
  setPendingActionKey(actionKey);
29810
29934
  try {
29811
29935
  const result = await reviewPullRequest({
29812
29936
  companyId: hostContext.companyId,
29813
29937
  projectId,
29814
29938
  repositoryUrl: pageData.repositoryUrl,
29815
- pullRequestNumber: reviewModalPullRequest.number,
29939
+ pullRequestNumber: pullRequest.number,
29816
29940
  review,
29817
- body: reviewModalDraft.trim()
29941
+ body
29818
29942
  });
29819
29943
  const updatedAt = (/* @__PURE__ */ new Date()).toISOString();
29820
- patchPullRequestRow(reviewModalPullRequest.id, (current) => {
29944
+ patchPullRequestRow(pullRequest.id, (current) => {
29821
29945
  const nextReviewApprovals = current.reviewApprovals + (result.review === "approved" ? 1 : 0);
29822
29946
  const nextReviewChangesRequested = current.reviewChangesRequested + (result.review === "changes_requested" ? 1 : 0);
29823
29947
  const nextRecord = {
@@ -29829,16 +29953,21 @@ function GitHubSyncProjectPullRequestsPage() {
29829
29953
  return {
29830
29954
  ...nextRecord,
29831
29955
  reviewable: resolvePreviewPullRequestReviewable(nextRecord),
29832
- mergeable: resolvePreviewPullRequestMergeable(nextRecord)
29956
+ mergeable: resolvePreviewPullRequestMergeable(nextRecord, {
29957
+ defaultBranchName: pageData.defaultBranchName
29958
+ })
29833
29959
  };
29834
29960
  });
29835
- closeReviewModal();
29836
- refreshSelectedPullRequestDetails(reviewModalPullRequest.id);
29961
+ if (options?.closeModal) {
29962
+ closeReviewModal();
29963
+ }
29964
+ refreshSelectedPullRequestDetails(pullRequest.id);
29837
29965
  refreshPullRequestMetricsPanel();
29838
29966
  notifyGitHubSyncPullRequestsChanged();
29967
+ const submittedReviewToast = getSubmittedReviewToast(result.review, pullRequest.number);
29839
29968
  toast({
29840
- title: result.review === "approved" ? `Approved #${reviewModalPullRequest.number}` : `Requested changes on #${reviewModalPullRequest.number}`,
29841
- body: result.review === "approved" ? "GitHub review submitted." : "GitHub change request submitted.",
29969
+ title: submittedReviewToast.title,
29970
+ body: submittedReviewToast.body,
29842
29971
  tone: "success"
29843
29972
  });
29844
29973
  } catch (error) {
@@ -29851,6 +29980,19 @@ function GitHubSyncProjectPullRequestsPage() {
29851
29980
  setPendingActionKey((current) => current === actionKey ? null : current);
29852
29981
  }
29853
29982
  }
29983
+ async function handleReviewPullRequest(review) {
29984
+ if (!reviewModalPullRequest) {
29985
+ return;
29986
+ }
29987
+ await submitPullRequestReview(reviewModalPullRequest, review, reviewModalDraft.trim(), { closeModal: true });
29988
+ }
29989
+ async function handleQuickPullRequestReview(pullRequest, review) {
29990
+ await submitPullRequestReview(
29991
+ pullRequest,
29992
+ review,
29993
+ review === "request_changes" ? QUICK_REQUEST_CHANGES_REVIEW_SUMMARY : ""
29994
+ );
29995
+ }
29854
29996
  async function handleRerunCi() {
29855
29997
  if (!rerunCiModalPullRequest || !hostContext.companyId || !projectId) {
29856
29998
  return;
@@ -29874,7 +30016,9 @@ function GitHubSyncProjectPullRequestsPage() {
29874
30016
  return {
29875
30017
  ...nextRecord,
29876
30018
  reviewable: resolvePreviewPullRequestReviewable(nextRecord),
29877
- mergeable: resolvePreviewPullRequestMergeable(nextRecord)
30019
+ mergeable: resolvePreviewPullRequestMergeable(nextRecord, {
30020
+ defaultBranchName: pageData.defaultBranchName
30021
+ })
29878
30022
  };
29879
30023
  });
29880
30024
  closeRerunCiModal();
@@ -29908,7 +30052,7 @@ function GitHubSyncProjectPullRequestsPage() {
29908
30052
  /* @__PURE__ */ jsx2("th", { scope: "col", className: "ghsync-prs-table__cell--center", children: "Checks" }),
29909
30053
  /* @__PURE__ */ jsx2("th", { scope: "col", className: "ghsync-prs-table__cell--center", children: "Up to date" }),
29910
30054
  /* @__PURE__ */ jsx2("th", { scope: "col", className: "ghsync-prs-table__cell--center", children: "Target branch" }),
29911
- /* @__PURE__ */ jsx2("th", { scope: "col", className: "ghsync-prs-table__cell--center", children: "Reviews" }),
30055
+ /* @__PURE__ */ jsx2("th", { scope: "col", className: "ghsync-prs-table__cell--center", children: "Approvals" }),
29912
30056
  /* @__PURE__ */ jsx2("th", { scope: "col", className: "ghsync-prs-table__cell--center", children: "Review threads" }),
29913
30057
  /* @__PURE__ */ jsx2("th", { scope: "col", className: "ghsync-prs-table__cell--center", children: "Comments" }),
29914
30058
  /* @__PURE__ */ jsx2("th", { scope: "col", className: "ghsync-prs-table__cell--center", children: "Last updated" }),
@@ -30130,12 +30274,16 @@ function GitHubSyncProjectPullRequestsPage() {
30130
30274
  const mergeActionKey = `merge:${pullRequest.id}`;
30131
30275
  const commentModalActionKey = `comment-modal:${pullRequest.id}`;
30132
30276
  const reviewActionPrefix = `review:${pullRequest.id}:`;
30277
+ const reviewApproveActionKey = `review:${pullRequest.id}:approve`;
30278
+ const reviewRequestChangesActionKey = `review:${pullRequest.id}:request_changes`;
30133
30279
  const rerunCiActionKey = `rerun-ci:${pullRequest.id}`;
30134
30280
  const updateBranchActionKey = `update-branch:${pullRequest.id}`;
30135
30281
  const closeActionKey = `close:${pullRequest.id}`;
30136
30282
  const copilotPending = Boolean(pendingActionKey?.startsWith(copilotActionPrefix));
30137
30283
  const commentModalPending2 = pendingActionKey === commentModalActionKey;
30138
30284
  const reviewPending = Boolean(pendingActionKey?.startsWith(reviewActionPrefix));
30285
+ const reviewApprovePending = pendingActionKey === reviewApproveActionKey;
30286
+ const reviewRequestChangesPending = pendingActionKey === reviewRequestChangesActionKey;
30139
30287
  const rerunCiPending = pendingActionKey === rerunCiActionKey;
30140
30288
  const updateBranchPending = pendingActionKey === updateBranchActionKey;
30141
30289
  const mergePending = pendingActionKey === mergeActionKey;
@@ -30216,7 +30364,7 @@ function GitHubSyncProjectPullRequestsPage() {
30216
30364
  "button",
30217
30365
  {
30218
30366
  type: "button",
30219
- className: "ghsync-prs-table__icon-button",
30367
+ className: `ghsync-prs-table__icon-button ${getPreviewPullRequestInlineActionToneClass("warning")}`,
30220
30368
  title: `Re-run CI for #${pullRequest.number}`,
30221
30369
  onClick: () => setRerunCiPullRequestId(pullRequest.id),
30222
30370
  disabled: rerunCiPending,
@@ -30272,40 +30420,82 @@ function GitHubSyncProjectPullRequestsPage() {
30272
30420
  /* @__PURE__ */ jsx2("td", { className: "ghsync-prs-table__cell--center", children: /* @__PURE__ */ jsxs2("div", { className: "ghsync-prs-table__metric-group", children: [
30273
30421
  hasReviewSummary ? /* @__PURE__ */ jsxs2("a", { className: "ghsync-prs-table__metric-link", href: pullRequest.reviewsUrl, target: "_blank", rel: "noreferrer", children: [
30274
30422
  pullRequest.reviewApprovals > 0 ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
30275
- /* @__PURE__ */ jsx2(CheckPassedIcon, { className: "ghsync-prs-icon" }),
30423
+ /* @__PURE__ */ jsx2(CheckPassedIcon, { className: "ghsync-prs-icon ghsync-prs-table__status--passed" }),
30276
30424
  /* @__PURE__ */ jsx2("span", { children: pullRequest.reviewApprovals })
30277
30425
  ] }) : null,
30278
30426
  pullRequest.reviewChangesRequested > 0 ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
30279
- /* @__PURE__ */ jsx2(CheckFailedIcon, { className: "ghsync-prs-icon" }),
30427
+ /* @__PURE__ */ jsx2(CheckFailedIcon, { className: "ghsync-prs-icon ghsync-prs-table__status--failed" }),
30280
30428
  /* @__PURE__ */ jsx2("span", { children: pullRequest.reviewChangesRequested })
30281
30429
  ] }) : null
30282
30430
  ] }) : null,
30283
- pullRequest.reviewable && canReviewPullRequests ? /* @__PURE__ */ jsx2(
30284
- "button",
30285
- {
30286
- type: "button",
30287
- className: "ghsync-prs-table__icon-button",
30288
- title: `Review #${pullRequest.number}`,
30289
- onClick: () => {
30290
- setReviewModalPullRequestId(pullRequest.id);
30291
- setReviewModalDraft("");
30292
- },
30293
- disabled: reviewPending,
30294
- children: /* @__PURE__ */ jsx2(
30295
- LoadingIconButtonContent,
30296
- {
30297
- busy: reviewPending,
30298
- busyLabel: `Reviewing #${pullRequest.number}`,
30299
- icon: /* @__PURE__ */ jsx2(ReviewIcon, { className: "ghsync-prs-icon" })
30300
- }
30301
- )
30302
- }
30303
- ) : null
30431
+ pullRequest.reviewable && canReviewPullRequests ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
30432
+ /* @__PURE__ */ jsx2(
30433
+ "button",
30434
+ {
30435
+ type: "button",
30436
+ className: "ghsync-prs-table__icon-button",
30437
+ title: `Review #${pullRequest.number}`,
30438
+ "aria-label": `Review #${pullRequest.number}`,
30439
+ onClick: () => openReviewModal(pullRequest.id),
30440
+ disabled: reviewPending,
30441
+ children: /* @__PURE__ */ jsx2(
30442
+ LoadingIconButtonContent,
30443
+ {
30444
+ busy: false,
30445
+ busyLabel: `Reviewing #${pullRequest.number}`,
30446
+ icon: /* @__PURE__ */ jsx2(ReviewIcon, { className: "ghsync-prs-icon" })
30447
+ }
30448
+ )
30449
+ }
30450
+ ),
30451
+ /* @__PURE__ */ jsx2(
30452
+ "button",
30453
+ {
30454
+ type: "button",
30455
+ className: `ghsync-prs-table__icon-button ${getPreviewPullRequestInlineActionToneClass("success")}`,
30456
+ title: `Approve #${pullRequest.number}`,
30457
+ "aria-label": `Approve #${pullRequest.number}`,
30458
+ onClick: () => {
30459
+ void handleQuickPullRequestReview(pullRequest, "approve");
30460
+ },
30461
+ disabled: reviewPending,
30462
+ children: /* @__PURE__ */ jsx2(
30463
+ LoadingIconButtonContent,
30464
+ {
30465
+ busy: reviewApprovePending,
30466
+ busyLabel: `Approving #${pullRequest.number}`,
30467
+ icon: /* @__PURE__ */ jsx2(CheckPassedIcon, { className: "ghsync-prs-icon" })
30468
+ }
30469
+ )
30470
+ }
30471
+ ),
30472
+ /* @__PURE__ */ jsx2(
30473
+ "button",
30474
+ {
30475
+ type: "button",
30476
+ className: `ghsync-prs-table__icon-button ${getPreviewPullRequestInlineActionToneClass("danger")}`,
30477
+ title: `Request changes on #${pullRequest.number}`,
30478
+ "aria-label": `Request changes on #${pullRequest.number}`,
30479
+ onClick: () => {
30480
+ void handleQuickPullRequestReview(pullRequest, "request_changes");
30481
+ },
30482
+ disabled: reviewPending,
30483
+ children: /* @__PURE__ */ jsx2(
30484
+ LoadingIconButtonContent,
30485
+ {
30486
+ busy: reviewRequestChangesPending,
30487
+ busyLabel: `Requesting changes on #${pullRequest.number}`,
30488
+ icon: /* @__PURE__ */ jsx2(CheckFailedIcon, { className: "ghsync-prs-icon" })
30489
+ }
30490
+ )
30491
+ }
30492
+ )
30493
+ ] }) : null
30304
30494
  ] }) }),
30305
30495
  /* @__PURE__ */ jsx2("td", { className: "ghsync-prs-table__cell--center", children: pullRequest.unresolvedReviewThreads > 0 ? /* @__PURE__ */ jsxs2("a", { className: "ghsync-prs-table__metric-link", href: pullRequest.reviewThreadsUrl, target: "_blank", rel: "noreferrer", children: [
30306
30496
  /* @__PURE__ */ jsx2(CommentIcon, { className: "ghsync-prs-icon" }),
30307
30497
  /* @__PURE__ */ jsx2("span", { children: pullRequest.unresolvedReviewThreads })
30308
- ] }) : hasResolvedReviewThreads ? /* @__PURE__ */ jsx2("a", { className: "ghsync-prs-table__metric-link", href: pullRequest.reviewThreadsUrl, target: "_blank", rel: "noreferrer", children: /* @__PURE__ */ jsx2(CheckPassedIcon, { className: "ghsync-prs-icon" }) }) : null }),
30498
+ ] }) : hasResolvedReviewThreads ? /* @__PURE__ */ jsx2("a", { className: "ghsync-prs-table__metric-link", href: pullRequest.reviewThreadsUrl, target: "_blank", rel: "noreferrer", children: /* @__PURE__ */ jsx2(CheckPassedIcon, { className: "ghsync-prs-icon ghsync-prs-table__status--passed" }) }) : null }),
30309
30499
  /* @__PURE__ */ jsx2("td", { className: "ghsync-prs-table__cell--center", children: /* @__PURE__ */ jsxs2("div", { className: "ghsync-prs-table__metric-group", children: [
30310
30500
  /* @__PURE__ */ jsxs2("a", { className: "ghsync-prs-table__metric-link", href: pullRequest.commentsUrl, target: "_blank", rel: "noreferrer", children: [
30311
30501
  /* @__PURE__ */ jsx2(CommentIcon, { className: "ghsync-prs-icon" }),
@@ -30369,7 +30559,7 @@ function GitHubSyncProjectPullRequestsPage() {
30369
30559
  "button",
30370
30560
  {
30371
30561
  type: "button",
30372
- className: "ghsync-prs-table__icon-button",
30562
+ className: `ghsync-prs-table__icon-button ${getPreviewPullRequestInlineActionToneClass("success")}`,
30373
30563
  title: `Merge #${pullRequest.number}`,
30374
30564
  onClick: () => {
30375
30565
  void handleMergePullRequest(pullRequest);
@@ -30389,7 +30579,7 @@ function GitHubSyncProjectPullRequestsPage() {
30389
30579
  "button",
30390
30580
  {
30391
30581
  type: "button",
30392
- className: "ghsync-prs-table__icon-button",
30582
+ className: `ghsync-prs-table__icon-button ${getPreviewPullRequestInlineActionToneClass("danger")}`,
30393
30583
  title: `Close PR #${pullRequest.number}`,
30394
30584
  "aria-label": `Close PR #${pullRequest.number}`,
30395
30585
  onClick: () => {
@@ -30513,10 +30703,7 @@ function GitHubSyncProjectPullRequestsPage() {
30513
30703
  {
30514
30704
  type: "button",
30515
30705
  className: getPluginActionClassName({ variant: "secondary", size: "sm" }),
30516
- onClick: () => {
30517
- setReviewModalPullRequestId(selectedPullRequest.id);
30518
- setReviewModalDraft("");
30519
- },
30706
+ onClick: () => openReviewModal(selectedPullRequest.id),
30520
30707
  disabled: selectedPullRequestReviewPending,
30521
30708
  children: /* @__PURE__ */ jsx2(
30522
30709
  LoadingButtonContent,
@@ -30533,7 +30720,7 @@ function GitHubSyncProjectPullRequestsPage() {
30533
30720
  "button",
30534
30721
  {
30535
30722
  type: "button",
30536
- className: getPluginActionClassName({ variant: "secondary", size: "sm" }),
30723
+ className: getPluginActionClassName({ variant: "warning", size: "sm" }),
30537
30724
  onClick: () => setRerunCiPullRequestId(selectedPullRequest.id),
30538
30725
  disabled: selectedPullRequestRerunCiPending,
30539
30726
  children: /* @__PURE__ */ jsx2(
@@ -30571,7 +30758,7 @@ function GitHubSyncProjectPullRequestsPage() {
30571
30758
  "button",
30572
30759
  {
30573
30760
  type: "button",
30574
- className: getPluginActionClassName({ variant: "primary", size: "sm" }),
30761
+ className: getPluginActionClassName({ variant: "success", size: "sm" }),
30575
30762
  onClick: () => {
30576
30763
  void handleMergePullRequest(selectedPullRequest);
30577
30764
  },
@@ -30758,7 +30945,7 @@ function GitHubSyncProjectPullRequestsPage() {
30758
30945
  ] }),
30759
30946
  /* @__PURE__ */ jsxs2("div", { className: "ghsync-prs-meta__row", children: [
30760
30947
  /* @__PURE__ */ jsx2("span", { className: "ghsync-prs-meta__label", children: "Mergeability" }),
30761
- /* @__PURE__ */ jsx2("div", { className: "ghsync-prs-meta__value", children: selectedPullRequest.mergeable ? "Mergeable now" : "Blocked until checks and review feedback settle" })
30948
+ /* @__PURE__ */ jsx2("div", { className: "ghsync-prs-meta__value", children: selectedPullRequest.mergeable ? "Mergeable now" : "Blocked by checks, review feedback, or target branch rules" })
30762
30949
  ] })
30763
30950
  ] })
30764
30951
  ] }),
@@ -31200,7 +31387,7 @@ function GitHubSyncProjectPullRequestsPage() {
31200
31387
  className: "ghsync-prs-modal__textarea",
31201
31388
  value: reviewModalDraft,
31202
31389
  onChange: (event) => setReviewModalDraft(event.currentTarget.value),
31203
- placeholder: "Optional comment"
31390
+ placeholder: "Required for Comment and Request changes. Optional for Approve."
31204
31391
  }
31205
31392
  )
31206
31393
  ] }),
@@ -31215,6 +31402,25 @@ function GitHubSyncProjectPullRequestsPage() {
31215
31402
  }
31216
31403
  ),
31217
31404
  /* @__PURE__ */ jsxs2("div", { className: "ghsync-prs-modal__split-actions", children: [
31405
+ /* @__PURE__ */ jsx2(
31406
+ "button",
31407
+ {
31408
+ type: "button",
31409
+ className: getPluginActionClassName({ variant: "secondary" }),
31410
+ onClick: () => {
31411
+ void handleReviewPullRequest("comment");
31412
+ },
31413
+ disabled: !reviewModalDraft.trim() || reviewModalPending,
31414
+ children: /* @__PURE__ */ jsx2(
31415
+ LoadingButtonContent,
31416
+ {
31417
+ busy: reviewModalCommentPending,
31418
+ label: "Comment",
31419
+ busyLabel: "Commenting\u2026"
31420
+ }
31421
+ )
31422
+ }
31423
+ ),
31218
31424
  /* @__PURE__ */ jsx2(
31219
31425
  "button",
31220
31426
  {
@@ -31223,7 +31429,7 @@ function GitHubSyncProjectPullRequestsPage() {
31223
31429
  onClick: () => {
31224
31430
  void handleReviewPullRequest("request_changes");
31225
31431
  },
31226
- disabled: reviewModalPending,
31432
+ disabled: !reviewModalDraft.trim() || reviewModalPending,
31227
31433
  children: /* @__PURE__ */ jsx2(
31228
31434
  LoadingButtonContent,
31229
31435
  {
@@ -31238,7 +31444,7 @@ function GitHubSyncProjectPullRequestsPage() {
31238
31444
  "button",
31239
31445
  {
31240
31446
  type: "button",
31241
- className: getPluginActionClassName({ variant: "primary" }),
31447
+ className: getPluginActionClassName({ variant: "success" }),
31242
31448
  onClick: () => {
31243
31449
  void handleReviewPullRequest("approve");
31244
31450
  },
@@ -31295,7 +31501,7 @@ function GitHubSyncProjectPullRequestsPage() {
31295
31501
  "button",
31296
31502
  {
31297
31503
  type: "button",
31298
- className: getPluginActionClassName({ variant: "primary" }),
31504
+ className: getPluginActionClassName({ variant: "warning" }),
31299
31505
  onClick: () => {
31300
31506
  void handleRerunCi();
31301
31507
  },
@@ -32647,7 +32853,7 @@ function GitHubSyncSettingsPage() {
32647
32853
  }
32648
32854
  }
32649
32855
  ),
32650
- /* @__PURE__ */ jsx2("p", { className: "ghsync__hint", children: "The assignee that resumes work when GitHub Sync sends an issue back to active execution, such as failing CI, unresolved review threads, or a trusted new GitHub comment." })
32856
+ /* @__PURE__ */ jsx2("p", { className: "ghsync__hint", children: "The assignee that resumes work when GitHub Sync sends an issue back to active execution, such as failing CI, non-mergeable linked pull requests, unresolved review threads, or a trusted new GitHub comment." })
32651
32857
  ] }),
32652
32858
  /* @__PURE__ */ jsxs2("div", { className: "ghsync__field", children: [
32653
32859
  /* @__PURE__ */ jsx2("label", { htmlFor: "advanced-reviewer-assignee", children: "Reviewer handoff" }),
@@ -33802,6 +34008,7 @@ function GitHubSyncIssueDetailTabContent(props) {
33802
34008
  if (detailTabState === "hidden") {
33803
34009
  return null;
33804
34010
  }
34011
+ const linkedPullRequests = issueDetails ? getLinkedPullRequestsForIssueDetails(issueDetails) : [];
33805
34012
  return /* @__PURE__ */ jsxs2("section", { className: "ghsync-issue-detail", style: props.themeVars, children: [
33806
34013
  /* @__PURE__ */ jsx2("style", { children: EXTENSION_SURFACE_STYLES }),
33807
34014
  detailTabState === "loading" ? /* @__PURE__ */ jsx2("p", { className: "ghsync-extension-empty", children: "Loading GitHub sync details\u2026" }) : null,
@@ -33882,19 +34089,19 @@ function GitHubSyncIssueDetailTabContent(props) {
33882
34089
  ] }),
33883
34090
  /* @__PURE__ */ jsxs2("div", { className: "ghsync-extension-metric", children: [
33884
34091
  /* @__PURE__ */ jsx2("span", { children: "Linked PRs" }),
33885
- /* @__PURE__ */ jsx2("strong", { children: issueDetails.linkedPullRequestNumbers.length })
34092
+ /* @__PURE__ */ jsx2("strong", { children: linkedPullRequests.length })
33886
34093
  ] }),
33887
34094
  /* @__PURE__ */ jsxs2("div", { className: "ghsync-extension-metric", children: [
33888
34095
  /* @__PURE__ */ jsx2("span", { children: "Last synced" }),
33889
34096
  /* @__PURE__ */ jsx2("strong", { children: issueDetails.syncedAt ? formatDate(issueDetails.syncedAt, "Unknown") : "Pending refresh" })
33890
34097
  ] })
33891
34098
  ] }),
33892
- issueDetails.linkedPullRequestNumbers.length > 0 ? /* @__PURE__ */ jsxs2("div", { className: "ghsync-issue-detail__section", children: [
34099
+ linkedPullRequests.length > 0 ? /* @__PURE__ */ jsxs2("div", { className: "ghsync-issue-detail__section", children: [
33893
34100
  /* @__PURE__ */ jsx2("div", { className: "ghsync-issue-detail__section-heading", children: "Linked pull requests" }),
33894
- /* @__PURE__ */ jsx2("div", { className: "ghsync-extension-links", children: issueDetails.linkedPullRequestNumbers.map((pullRequestNumber) => /* @__PURE__ */ jsx2(
34101
+ /* @__PURE__ */ jsx2("div", { className: "ghsync-extension-links", children: linkedPullRequests.map((pullRequest) => /* @__PURE__ */ jsx2(
33895
34102
  "a",
33896
34103
  {
33897
- href: `${issueDetails.repositoryUrl}/pull/${pullRequestNumber}`,
34104
+ href: `${pullRequest.repositoryUrl}/pull/${pullRequest.number}`,
33898
34105
  target: "_blank",
33899
34106
  rel: "noreferrer",
33900
34107
  className: getPluginActionClassName({
@@ -33902,9 +34109,14 @@ function GitHubSyncIssueDetailTabContent(props) {
33902
34109
  size: "sm",
33903
34110
  extraClassName: "ghsync-extension-link"
33904
34111
  }),
33905
- children: /* @__PURE__ */ jsx2(GitHubButtonLabel, { label: `PR #${pullRequestNumber}` })
34112
+ children: /* @__PURE__ */ jsx2(
34113
+ GitHubButtonLabel,
34114
+ {
34115
+ label: formatIssueDetailLinkedPullRequestLabel(pullRequest, issueDetails.repositoryUrl)
34116
+ }
34117
+ )
33906
34118
  },
33907
- pullRequestNumber
34119
+ `${pullRequest.repositoryUrl}:${pullRequest.number}`
33908
34120
  )) })
33909
34121
  ] }) : null,
33910
34122
  issueDetails.labels && issueDetails.labels.length > 0 ? /* @__PURE__ */ jsxs2("div", { className: "ghsync-issue-detail__section", children: [