prreviewbuddy 0.19.0 → 0.19.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/CHANGELOG.md +24 -0
- package/dist/server.js +42 -1
- package/package.json +1 -1
- package/static/shell.css +55 -6
- package/static/sidebar.css +63 -0
- package/static/workspace.js +19 -19
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.19.1
|
|
4
|
+
|
|
5
|
+
*An answer worth keeping can now be taken out whole.*
|
|
6
|
+
|
|
7
|
+
**Every Buddy AI answer carries a copy control.** It sits under the answer, and it copies the
|
|
8
|
+
Markdown the assistant actually wrote, not the text on the screen: the backticks, the fenced
|
|
9
|
+
blocks and the lists survive, so an answer pasted into a pull request comment arrives formatted
|
|
10
|
+
rather than flattened into one run of prose. The question above it does not get one, because the
|
|
11
|
+
question is yours and you still have it.
|
|
12
|
+
|
|
13
|
+
Per-block copy is unchanged and still there. The two answer different questions: that one lifts a
|
|
14
|
+
snippet out of an answer, this one lifts the answer.
|
|
15
|
+
|
|
16
|
+
If the clipboard is unavailable, the control says so and does nothing else. It deliberately does
|
|
17
|
+
not fall back to selecting the answer on the page and asking you to press ⌘C, because what that
|
|
18
|
+
would put on the clipboard is the rendered text, which is the one thing this control exists to
|
|
19
|
+
avoid handing you.
|
|
20
|
+
|
|
21
|
+
**The strips at the top of a review use the whole width of the page.** The notice that you are
|
|
22
|
+
reading an older review, the list of the other reviews of that branch, and the sentence that says
|
|
23
|
+
new commits have landed were each capped part-way across, so on a wide window they stopped
|
|
24
|
+
two-thirds of the way along a band that visibly carried on. They now run to the edge of the
|
|
25
|
+
section they sit in, which puts each row's `Open review` where the eye already expects it.
|
|
26
|
+
|
|
3
27
|
## 0.19.0
|
|
4
28
|
|
|
5
29
|
*It asks before it sends anything, and the npm page stops reading like a manual.*
|
package/dist/server.js
CHANGED
|
@@ -301,6 +301,47 @@ function deriveReviewMetrics(result) {
|
|
|
301
301
|
};
|
|
302
302
|
}
|
|
303
303
|
//#endregion
|
|
304
|
+
//#region ../../packages/review-harness/src/domain/ui/components/message_copy.ts
|
|
305
|
+
var MESSAGE_COPY_CLASS = "pr-helper-msg-copy";
|
|
306
|
+
var MESSAGE_ACTIONS_CLASS = "pr-helper-chat-actions";
|
|
307
|
+
/** The Markdown itself, for surfaces that hold no message state to resolve an id against. */
|
|
308
|
+
var MESSAGE_SOURCE_ATTR = "data-copy-source";
|
|
309
|
+
var STATES = {
|
|
310
|
+
idle: {
|
|
311
|
+
icon: "<path d=\"M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z\"></path><path d=\"M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z\"></path>",
|
|
312
|
+
label: "",
|
|
313
|
+
aria: "Copy message"
|
|
314
|
+
},
|
|
315
|
+
copied: {
|
|
316
|
+
icon: "<path d=\"M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z\"></path>",
|
|
317
|
+
label: "Copied",
|
|
318
|
+
aria: "Copied"
|
|
319
|
+
},
|
|
320
|
+
failed: {
|
|
321
|
+
icon: "<path d=\"M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\"></path>",
|
|
322
|
+
label: "Copy failed",
|
|
323
|
+
aria: "Copy failed"
|
|
324
|
+
}
|
|
325
|
+
};
|
|
326
|
+
/**
|
|
327
|
+
* The same row, carrying the Markdown itself.
|
|
328
|
+
*
|
|
329
|
+
* For a surface with nothing to resolve an id against — the local workspace renders its stored
|
|
330
|
+
* transcript to HTML server-side and appends live answers straight to the DOM, so there is no
|
|
331
|
+
* conversation object on the client at all. Duplicating the source into the attribute is the
|
|
332
|
+
* honest trade there, and it is the same shape the prompt bank already uses to ship its data.
|
|
333
|
+
*/
|
|
334
|
+
function renderMessageCopySource(source) {
|
|
335
|
+
return button(`${MESSAGE_SOURCE_ATTR}="${escapeHtml(source)}"`);
|
|
336
|
+
}
|
|
337
|
+
function button(handle) {
|
|
338
|
+
const { icon, label, aria } = STATES.idle;
|
|
339
|
+
return `<div class="${MESSAGE_ACTIONS_CLASS}"><button type="button" class="${MESSAGE_COPY_CLASS}" ${handle} aria-label="${aria}"><span class="${MESSAGE_COPY_CLASS}-icon" aria-hidden="true">${svg(icon)}</span><span class="${MESSAGE_COPY_CLASS}-label"${label ? "" : " hidden"}>${label}</span></button></div>`;
|
|
340
|
+
}
|
|
341
|
+
function svg(paths) {
|
|
342
|
+
return `<svg viewBox="0 0 16 16" width="14" height="14" fill="currentColor">${paths}</svg>`;
|
|
343
|
+
}
|
|
344
|
+
//#endregion
|
|
304
345
|
//#region ../../packages/review-harness/src/domain/utils/sha.ts
|
|
305
346
|
/**
|
|
306
347
|
* Commit SHA handling for analysis staleness.
|
|
@@ -3045,7 +3086,7 @@ function renderAsk(view, sections) {
|
|
|
3045
3086
|
${renderPromptBank(view.prompts ?? [])}
|
|
3046
3087
|
<div class="prb-ask-log" data-ask-log>
|
|
3047
3088
|
${transcript.length > 0 ? transcript.map((exchange) => `<div class="prb-msg prb-msg-user">${escapeHtml(exchange.question)}</div>
|
|
3048
|
-
<div class="prb-msg prb-msg-assistant prb-md">${renderMarkdown(exchange.answer)}</div>`).join("") : `<div class="prb-ask-empty">
|
|
3089
|
+
<div class="prb-msg prb-msg-assistant prb-md">${renderMarkdown(exchange.answer)}${renderMessageCopySource(exchange.answer)}</div>`).join("") : `<div class="prb-ask-empty">
|
|
3049
3090
|
<p>Ask about this change. Answers come from the review, the diff and the repository on disk — not from anywhere else.</p>
|
|
3050
3091
|
${suggestions.map((text) => `<button type="button" class="prb-suggestion" data-suggestion>${escapeHtml(text)}</button>`).join("")}
|
|
3051
3092
|
</div>`}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prreviewbuddy",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.1",
|
|
4
4
|
"description": "Review a branch or pull request in an isolated checkout, from your terminal, with the coding agent you already have installed.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"homepage": "https://prreviewbuddy.com",
|
package/static/shell.css
CHANGED
|
@@ -1113,6 +1113,54 @@ a.prb-rail-item { text-decoration: none; }
|
|
|
1113
1113
|
color: var(--success);
|
|
1114
1114
|
}
|
|
1115
1115
|
|
|
1116
|
+
/* ── Copying a whole answer ──
|
|
1117
|
+
Same control as the extension sidebar's, restyled for this dark pane, and on the answer only:
|
|
1118
|
+
the question above it is the reviewer's own words, which they already have.
|
|
1119
|
+
|
|
1120
|
+
The row states its own gap; the last block above it carries a bottom margin of its own that
|
|
1121
|
+
would stack with it, zeroed by its relationship to the row rather than by position so the
|
|
1122
|
+
spacing survives any change to the markdown margins. */
|
|
1123
|
+
.prb-md .pr-helper-chat-actions {
|
|
1124
|
+
display: flex;
|
|
1125
|
+
margin-top: 8px;
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
.prb-md > *:has(+ .pr-helper-chat-actions) { margin-bottom: 0; }
|
|
1129
|
+
|
|
1130
|
+
.prb-md .pr-helper-msg-copy {
|
|
1131
|
+
display: inline-flex;
|
|
1132
|
+
align-items: center;
|
|
1133
|
+
gap: 5px;
|
|
1134
|
+
padding: 3px 6px;
|
|
1135
|
+
border: 0;
|
|
1136
|
+
border-radius: 5px;
|
|
1137
|
+
background: none;
|
|
1138
|
+
color: var(--text-secondary);
|
|
1139
|
+
font-family: inherit;
|
|
1140
|
+
font-size: 11px;
|
|
1141
|
+
font-weight: 600;
|
|
1142
|
+
line-height: 1;
|
|
1143
|
+
cursor: pointer;
|
|
1144
|
+
opacity: 0.6;
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
.prb-md .pr-helper-msg-copy:hover {
|
|
1148
|
+
opacity: 1;
|
|
1149
|
+
color: #c4b5fd;
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
.prb-md .pr-helper-msg-copy.copied {
|
|
1153
|
+
color: var(--success);
|
|
1154
|
+
opacity: 1;
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1157
|
+
.prb-md .pr-helper-msg-copy.failed {
|
|
1158
|
+
color: var(--danger);
|
|
1159
|
+
opacity: 1;
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
.prb-md .pr-helper-msg-copy svg { display: block; }
|
|
1163
|
+
|
|
1116
1164
|
/* Inline code is a chip; inside a block that background and padding would double up. */
|
|
1117
1165
|
.prb-md pre code {
|
|
1118
1166
|
padding: 0;
|
|
@@ -1509,7 +1557,7 @@ a.prb-rail-item { text-decoration: none; }
|
|
|
1509
1557
|
font-size: 12.5px;
|
|
1510
1558
|
line-height: 1.55;
|
|
1511
1559
|
}
|
|
1512
|
-
.prb-lineage p { margin: 0; color: var(--text-secondary);
|
|
1560
|
+
.prb-lineage p { margin: 0; color: var(--text-secondary); }
|
|
1513
1561
|
.prb-lineage strong { color: var(--text-primary); font-weight: 600; }
|
|
1514
1562
|
|
|
1515
1563
|
/* The other reviews, listed here rather than linked to. Open by default, because this strip only
|
|
@@ -1533,13 +1581,14 @@ a.prb-rail-item { text-decoration: none; }
|
|
|
1533
1581
|
}
|
|
1534
1582
|
.prb-lineage-more[open] > summary::after { transform: rotate(-180deg); }
|
|
1535
1583
|
.prb-lineage-more > summary:hover { color: var(--text-primary); }
|
|
1536
|
-
/*
|
|
1537
|
-
|
|
1538
|
-
|
|
1584
|
+
/* Full width, like the strip it sits in. This was capped at 92ch to keep each row's name near its
|
|
1585
|
+
`Open review`, but a capped list inside an uncapped banner reads as broken rather than as tidy:
|
|
1586
|
+
the rows stop two-thirds of the way across a section that clearly continues. The row is a flex
|
|
1587
|
+
line whose slack is absorbed by `.prb-lineage-left`, so widening it spreads the facts out rather
|
|
1588
|
+
than stranding the button. */
|
|
1539
1589
|
.prb-lineage-list {
|
|
1540
1590
|
margin: 5px 0 0;
|
|
1541
1591
|
padding: 0;
|
|
1542
|
-
max-width: 92ch;
|
|
1543
1592
|
list-style: none;
|
|
1544
1593
|
}
|
|
1545
1594
|
.prb-lineage-row {
|
|
@@ -1698,7 +1747,7 @@ a.prb-rail-item { text-decoration: none; }
|
|
|
1698
1747
|
.prb-update-result[data-state='refused'],
|
|
1699
1748
|
.prb-update-result[data-state='stopped'] { border-left-color: var(--warning); }
|
|
1700
1749
|
.prb-update-result-body { flex: 1 1 auto; min-width: 0; }
|
|
1701
|
-
.prb-update-result p { margin: 0; color: var(--text-secondary);
|
|
1750
|
+
.prb-update-result p { margin: 0; color: var(--text-secondary); }
|
|
1702
1751
|
.prb-update-result strong { color: var(--text-primary); font-weight: 600; }
|
|
1703
1752
|
.prb-update-result .prb-update-footnote { margin-top: 5px; color: var(--text-muted); font-size: 11.5px; }
|
|
1704
1753
|
.prb-update-result .prb-fresh-dismiss {
|
package/static/sidebar.css
CHANGED
|
@@ -1884,6 +1884,69 @@
|
|
|
1884
1884
|
opacity: 1;
|
|
1885
1885
|
}
|
|
1886
1886
|
|
|
1887
|
+
/* ── The copy control under a whole message ──
|
|
1888
|
+
A different job from the block button above: that one lifts a snippet, this one lifts the
|
|
1889
|
+
entire reply as Markdown so it can be pasted into a GitHub comment intact. Deliberately
|
|
1890
|
+
lighter than the block pill — no border, no ground of its own — because it sits under the
|
|
1891
|
+
review content rather than on top of it and must not compete with it. Shown rather than
|
|
1892
|
+
revealed on hover, for the same reason the block button is.
|
|
1893
|
+
|
|
1894
|
+
The row states its own gap above. The last Markdown element in the bubble carries a 10px
|
|
1895
|
+
bottom margin (p, ul, .pr-helper-code-block all do) which would stack with it, so it is
|
|
1896
|
+
zeroed by its relationship to the row rather than by position: the spacing stays 8px whatever
|
|
1897
|
+
a reply happens to end with, and whatever those margins are changed to later. The existing
|
|
1898
|
+
`.pr-helper-markdown > *:last-child` rule now lands on the row itself, which is correct. */
|
|
1899
|
+
.pr-helper-chat-actions {
|
|
1900
|
+
display: flex;
|
|
1901
|
+
margin-top: 8px;
|
|
1902
|
+
}
|
|
1903
|
+
|
|
1904
|
+
.pr-helper-markdown > *:has(+ .pr-helper-chat-actions) { margin-bottom: 0; }
|
|
1905
|
+
|
|
1906
|
+
/* The user bubble is right-aligned, so its action tucks under the text rather than orphaning
|
|
1907
|
+
itself at the far left of a narrow bubble. */
|
|
1908
|
+
.pr-helper-chat-msg.role-user .pr-helper-chat-actions { justify-content: flex-end; }
|
|
1909
|
+
|
|
1910
|
+
.pr-helper-msg-copy {
|
|
1911
|
+
display: inline-flex;
|
|
1912
|
+
align-items: center;
|
|
1913
|
+
gap: 5px;
|
|
1914
|
+
padding: 3px 6px;
|
|
1915
|
+
border: 0;
|
|
1916
|
+
border-radius: 5px;
|
|
1917
|
+
background: none;
|
|
1918
|
+
color: var(--color-fg-muted, #57606a);
|
|
1919
|
+
font-family: inherit;
|
|
1920
|
+
font-size: 11px;
|
|
1921
|
+
font-weight: 600;
|
|
1922
|
+
line-height: 1;
|
|
1923
|
+
cursor: pointer;
|
|
1924
|
+
opacity: 0.65;
|
|
1925
|
+
}
|
|
1926
|
+
|
|
1927
|
+
.pr-helper-msg-copy:hover {
|
|
1928
|
+
opacity: 1;
|
|
1929
|
+
color: #9333ea;
|
|
1930
|
+
}
|
|
1931
|
+
|
|
1932
|
+
/* None of the .pr-helper-markdown colours reach the dark user bubble, so it states its own. */
|
|
1933
|
+
.pr-helper-chat-msg.role-user .pr-helper-msg-copy { color: rgba(248, 250, 252, 0.7); }
|
|
1934
|
+
.pr-helper-chat-msg.role-user .pr-helper-msg-copy:hover { color: #fff; }
|
|
1935
|
+
|
|
1936
|
+
.pr-helper-msg-copy.copied,
|
|
1937
|
+
.pr-helper-chat-msg.role-user .pr-helper-msg-copy.copied {
|
|
1938
|
+
color: #1a7f37;
|
|
1939
|
+
opacity: 1;
|
|
1940
|
+
}
|
|
1941
|
+
|
|
1942
|
+
.pr-helper-msg-copy.failed,
|
|
1943
|
+
.pr-helper-chat-msg.role-user .pr-helper-msg-copy.failed {
|
|
1944
|
+
color: #cf222e;
|
|
1945
|
+
opacity: 1;
|
|
1946
|
+
}
|
|
1947
|
+
|
|
1948
|
+
.pr-helper-msg-copy svg { display: block; }
|
|
1949
|
+
|
|
1887
1950
|
/* Inline code is a chip; inside a block that background and padding would double up. */
|
|
1888
1951
|
.pr-helper-markdown pre code {
|
|
1889
1952
|
background: none;
|
package/static/workspace.js
CHANGED
|
@@ -26,34 +26,34 @@ import{t as e}from"./chunk-B9H2wUlQ.js";function t(e){return e.replace(/&/g,`&am
|
|
|
26
26
|
`}function fe(e){return`<div class="pr-helper-selection-menu">
|
|
27
27
|
${e.actions.map(e=>`<button type="button" class="pr-helper-selection-menu-item" data-selection-action="${t(e.id)}">${t(e.label)}</button>`).join(``)}
|
|
28
28
|
<button type="button" class="pr-helper-selection-menu-item pr-helper-selection-copy-item" data-selection-copy>${ce}</button>
|
|
29
|
-
</div>`}function pe(e,t){let{width:n,height:r}=e.getBoundingClientRect(),i=t.top-r-ae,a=i>=p?i:Math.min(t.bottom+ae,window.innerHeight-r-p),o=Math.max(p,Math.min(t.left,window.innerWidth-n-p));e.style.top=`${Math.max(p,a)}px`,e.style.left=`${o}px`}function h(){g&&=(window.clearTimeout(g),0),m?.popover.remove(),m=null}var g=0;function me(e){let t=e.querySelector(`.pr-helper-selection-tip`),n=e.querySelector(`.pr-helper-selection-copy-item`);e.classList.add(ie),t&&(t.textContent=le),n&&(n.textContent=le),g&&window.clearTimeout(g),g=window.setTimeout(()=>he(e),oe)}function he(e){g&&=(window.clearTimeout(g),0),e.classList.remove(ie);let t=e.querySelector(`.pr-helper-selection-tip`);t&&(t.textContent=se);let n=e.querySelector(`.pr-helper-selection-copy-item`);n&&(n.textContent=ce)}async function ge(e,t){try{await navigator.clipboard.writeText(t)}catch(e){console.warn(`PR Helper: clipboard write failed, falling back to execCommand`,e);let t=!1;try{t=document.execCommand(`copy`)}catch(e){console.warn(`PR Helper: clipboard fallback failed`,e)}if(!t)return}me(e)}function _e(e,t){let n=window.getSelection();if(!n||n.isCollapsed||n.rangeCount===0)return null;let r=n.toString().trim();if(!r)return null;let i=n.getRangeAt(0);if(!e.contains(i.commonAncestorContainer))return null;if(t.onlyWithin||t.ignoreWithin){let e=i.commonAncestorContainer,n=e instanceof HTMLElement?e:e.parentElement;if(t.onlyWithin&&!n?.closest(t.onlyWithin)||t.ignoreWithin&&n?.closest(t.ignoreWithin))return null}let a=i.getBoundingClientRect();return a.width===0&&a.height===0?null:{text:r,rect:a}}function ve(e,t){let n={},r=()=>{let r=_e(e,t);if(!r){(!m||m.owner===n)&&h();return}if(m&&m.owner!==n&&h(),m)m.popover.classList.remove(re),he(m.popover),m.text=r.text;else{let i=document.createElement(`div`);i.className=t.layout===`flat`?`${ne} ${ue}`:ne,i.innerHTML=de(t),i.addEventListener(`mousedown`,e=>e.preventDefault()),i.addEventListener(`click`,n=>{let r=n.target;if(r.closest(`[data-selection-copy]`)){m?.text&&ge(i,m.text);return}if(r.closest(`[data-selection-open]`)){i.classList.add(re);let n=_e(e,t);pe(i,n?.rect??i.getBoundingClientRect());return}let a=r.closest(`[data-selection-action]`)?.dataset.selectionAction;if(!a||!m)return;let o=m.text;h(),t.onChoose(a,o)}),document.body.appendChild(i),m={popover:i,text:r.text,owner:n}}pe(m.popover,r.rect)},i=e=>{m&&e.target instanceof Node&&m.popover.contains(e.target)||window.setTimeout(r,0)},a=e=>{(e.shiftKey||e.key===`Shift`)&&r()},o=()=>{if(!m)return;let e=window.getSelection();(!e||e.isCollapsed)&&h()},s=e=>{e.key===`Escape`&&h()},c=()=>h();return document.addEventListener(`mouseup`,i,!0),document.addEventListener(`keyup`,a,!0),e.addEventListener(`scroll`,c,!0),document.addEventListener(`selectionchange`,o),document.addEventListener(`keydown`,s),window.addEventListener(`scroll`,c,!0),()=>{document.removeEventListener(`mouseup`,i,!0),document.removeEventListener(`keyup`,a,!0),e.removeEventListener(`scroll`,c,!0),document.removeEventListener(`selectionchange`,o),document.removeEventListener(`keydown`,s),window.removeEventListener(`scroll`,c,!0),h()}}async function ye(e){try{return await navigator.clipboard.writeText(e),!0}catch(t){return console.warn(`PR Helper: clipboard write failed, falling back to execCommand`,t),be(e)}}function be(e){let t=document.createElement(`textarea`);t.value=e,t.setAttribute(`aria-hidden`,`true`),t.style.cssText=`position:fixed;top:-9999px;left:-9999px;opacity:0;`,document.body.appendChild(t);try{return t.select(),document.execCommand(`copy`)}catch(e){return console.warn(`PR Helper: clipboard fallback failed`,e),!1}finally{t.remove()}}var xe=1400,
|
|
29
|
+
</div>`}function pe(e,t){let{width:n,height:r}=e.getBoundingClientRect(),i=t.top-r-ae,a=i>=p?i:Math.min(t.bottom+ae,window.innerHeight-r-p),o=Math.max(p,Math.min(t.left,window.innerWidth-n-p));e.style.top=`${Math.max(p,a)}px`,e.style.left=`${o}px`}function h(){g&&=(window.clearTimeout(g),0),m?.popover.remove(),m=null}var g=0;function me(e){let t=e.querySelector(`.pr-helper-selection-tip`),n=e.querySelector(`.pr-helper-selection-copy-item`);e.classList.add(ie),t&&(t.textContent=le),n&&(n.textContent=le),g&&window.clearTimeout(g),g=window.setTimeout(()=>he(e),oe)}function he(e){g&&=(window.clearTimeout(g),0),e.classList.remove(ie);let t=e.querySelector(`.pr-helper-selection-tip`);t&&(t.textContent=se);let n=e.querySelector(`.pr-helper-selection-copy-item`);n&&(n.textContent=ce)}async function ge(e,t){try{await navigator.clipboard.writeText(t)}catch(e){console.warn(`PR Helper: clipboard write failed, falling back to execCommand`,e);let t=!1;try{t=document.execCommand(`copy`)}catch(e){console.warn(`PR Helper: clipboard fallback failed`,e)}if(!t)return}me(e)}function _e(e,t){let n=window.getSelection();if(!n||n.isCollapsed||n.rangeCount===0)return null;let r=n.toString().trim();if(!r)return null;let i=n.getRangeAt(0);if(!e.contains(i.commonAncestorContainer))return null;if(t.onlyWithin||t.ignoreWithin){let e=i.commonAncestorContainer,n=e instanceof HTMLElement?e:e.parentElement;if(t.onlyWithin&&!n?.closest(t.onlyWithin)||t.ignoreWithin&&n?.closest(t.ignoreWithin))return null}let a=i.getBoundingClientRect();return a.width===0&&a.height===0?null:{text:r,rect:a}}function ve(e,t){let n={},r=()=>{let r=_e(e,t);if(!r){(!m||m.owner===n)&&h();return}if(m&&m.owner!==n&&h(),m)m.popover.classList.remove(re),he(m.popover),m.text=r.text;else{let i=document.createElement(`div`);i.className=t.layout===`flat`?`${ne} ${ue}`:ne,i.innerHTML=de(t),i.addEventListener(`mousedown`,e=>e.preventDefault()),i.addEventListener(`click`,n=>{let r=n.target;if(r.closest(`[data-selection-copy]`)){m?.text&&ge(i,m.text);return}if(r.closest(`[data-selection-open]`)){i.classList.add(re);let n=_e(e,t);pe(i,n?.rect??i.getBoundingClientRect());return}let a=r.closest(`[data-selection-action]`)?.dataset.selectionAction;if(!a||!m)return;let o=m.text;h(),t.onChoose(a,o)}),document.body.appendChild(i),m={popover:i,text:r.text,owner:n}}pe(m.popover,r.rect)},i=e=>{m&&e.target instanceof Node&&m.popover.contains(e.target)||window.setTimeout(r,0)},a=e=>{(e.shiftKey||e.key===`Shift`)&&r()},o=()=>{if(!m)return;let e=window.getSelection();(!e||e.isCollapsed)&&h()},s=e=>{e.key===`Escape`&&h()},c=()=>h();return document.addEventListener(`mouseup`,i,!0),document.addEventListener(`keyup`,a,!0),e.addEventListener(`scroll`,c,!0),document.addEventListener(`selectionchange`,o),document.addEventListener(`keydown`,s),window.addEventListener(`scroll`,c,!0),()=>{document.removeEventListener(`mouseup`,i,!0),document.removeEventListener(`keyup`,a,!0),e.removeEventListener(`scroll`,c,!0),document.removeEventListener(`selectionchange`,o),document.removeEventListener(`keydown`,s),window.removeEventListener(`scroll`,c,!0),h()}}async function ye(e){try{return await navigator.clipboard.writeText(e),!0}catch(t){return console.warn(`PR Helper: clipboard write failed, falling back to execCommand`,t),be(e)}}function be(e){let t=document.createElement(`textarea`);t.value=e,t.setAttribute(`aria-hidden`,`true`),t.style.cssText=`position:fixed;top:-9999px;left:-9999px;opacity:0;`,document.body.appendChild(t);try{return t.select(),document.execCommand(`copy`)}catch(e){return console.warn(`PR Helper: clipboard fallback failed`,e),!1}finally{t.remove()}}var _=`pr-helper-msg-copy`,xe=`pr-helper-chat-actions`,Se=`data-message-id`,Ce=`data-copy-source`,we={idle:{icon:`<path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path>`,label:``,aria:`Copy message`},copied:{icon:`<path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path>`,label:`Copied`,aria:`Copied`},failed:{icon:`<path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>`,label:`Copy failed`,aria:`Copy failed`}};function Te(e){return Ee(`${Ce}="${t(e)}"`)}function Ee(e){let{icon:t,label:n,aria:r}=we.idle;return`<div class="${xe}"><button type="button" class="${_}" ${e} aria-label="${r}"><span class="${_}-icon" aria-hidden="true">${Oe(t)}</span><span class="${_}-label"${n?``:` hidden`}>${n}</span></button></div>`}function De(e,t){let n=we[t],r=e.querySelector(`.${_}-icon`),i=e.querySelector(`.${_}-label`);r&&(r.innerHTML=Oe(n.icon)),i instanceof HTMLElement&&(i.textContent=n.label,i.hidden=n.label===``),e.setAttribute(`aria-label`,n.aria),e.classList.toggle(`copied`,t===`copied`),e.classList.toggle(`failed`,t===`failed`)}function Oe(e){return`<svg viewBox="0 0 16 16" width="14" height="14" fill="currentColor">${e}</svg>`}var ke=1400,Ae=`Copy`,je=`Copied`,Me=/Mac|iPhone|iPad/.test(navigator.userAgent)?`Press ⌘C`:`Press Ctrl C`,v=new WeakMap;function Ne(e,t={}){let n=e=>{let n=e.target;if(!(n instanceof Element))return;let i=n.closest(`.${r}`),a=i?null:n.closest(`.${_}`);!i&&!a||(e.preventDefault(),e.stopPropagation(),i?Ie(i):a&&Pe(a,t.messageSource))};return e.addEventListener(`click`,n,!0),()=>e.removeEventListener(`click`,n,!0)}async function Pe(e,t){let n=Fe(e,t);Re(e,n!==null&&await ye(n)?`copied`:`failed`)}function Fe(e,t){let n=e.getAttribute(Ce);if(n!==null)return n;let r=e.getAttribute(Se);return r&&t?t(r):null}async function Ie(e){let t=e.parentElement?.querySelector(`pre code`),n=t?await ye(t.textContent??``):!1;!n&&t&&Le(t),ze(e,n?je:Me,n)}function Le(e){let t=window.getSelection();if(!t)return;let n=document.createRange();n.selectNodeContents(e),t.removeAllRanges(),t.addRange(n)}function Re(e,t){let n=v.get(e);n&&window.clearTimeout(n),De(e,t),v.set(e,window.setTimeout(()=>{De(e,`idle`),v.delete(e)},ke))}function ze(e,t,n){let r=v.get(e);r&&window.clearTimeout(r),e.textContent=t,e.classList.toggle(`copied`,n),v.set(e,window.setTimeout(()=>{e.textContent=Ae,e.classList.remove(`copied`),v.delete(e)},ke))}var Be=[{id:`explain`,label:`Explain`,instruction:`Explain this in simpler terms.`},{id:`is-problem`,label:`Is this actually a problem?`,instruction:`Is this actually a problem? Be specific about when it would and would not matter.`},{id:`better-implementation`,label:`Suggest a better implementation`,instruction:`Suggest a better implementation for this.`},{id:`author-question`,label:`Generate a question for the author`,instruction:`Generate a question I could ask the author about this.`},{id:`custom`,label:`Ask a question`}],Ve=[{id:`add-to-chat`,label:`Add to chat`}],He=800;function Ue(e){let t=e.replace(/\r\n/g,`
|
|
30
30
|
`).split(`
|
|
31
31
|
`).map(e=>e.replace(/\s+$/,``));for(;t.length&&!t[0].trim();)t.shift();for(;t.length&&!t[t.length-1].trim();)t.pop();let n=t.filter(e=>e.trim()).map(e=>e.match(/^[ \t]*/)[0].length),r=n.length?Math.min(...n):0,i=t.map(e=>e.slice(r)).join(`
|
|
32
32
|
`).replace(/\n{3,}/g,`
|
|
33
33
|
|
|
34
|
-
`);return i.trim()?(i.length>
|
|
34
|
+
`);return i.trim()?(i.length>He?`${i.slice(0,He).trimEnd()}…`:i).split(`
|
|
35
35
|
`).map(e=>`> ${e}`.trimEnd()).join(`
|
|
36
|
-
`):``}function
|
|
36
|
+
`):``}function We(e,t){let n=Ue(e);if(!n)return null;let r=[...Be,...Ve].find(e=>e.id===t);return r?r.instruction?`${n}\n\n${r.instruction}`:`${n}\n\n`:null}var Ge=`saved:`;function Ke(e){return`${Ge}${e}`}function qe(e){return e.startsWith(`saved:`)?e.slice(6):null}function Je(e){return e.reviewerClosed>0?`dealt with`:`resolved`}var Ye=`Dismissed by you — you decided this finding needs no action. It stops counting towards what is left, and stays here so the decision is visible rather than lost.`;function Xe(e,t,n=`resolved`){return t===0?`<span class="pr-helper-questions-progress-check" aria-hidden="true">\u2713</span><span class="pr-helper-questions-progress-count">All ${e} issues ${n}</span>`:`<span class="pr-helper-questions-progress-count">${t} of ${e} still open</span>`}function Ze(e){let t=e.done-e.reviewerClosed;return e.reviewerClosed===0?`Resolved by the new commits (${e.done})`:t===0?`Dismissed by you (${e.done})`:`Dealt with (${e.done})`}function Qe(e,t){return t===0?`<span class="pr-helper-questions-progress-check" aria-hidden="true">✓</span><span class="pr-helper-questions-progress-count">All ${e} questions answered</span>`:`<span class="pr-helper-questions-progress-count">${t} of ${e} unanswered</span>`}function $e(e,t){let n=e.trim();return n?`${n}\n\n${t}`:t}var et=[`overview`,`guide`,`issues`,`questions`,`files`,`prcontext`],tt=`#theme-`;function nt(e){return`#${e}`}function rt(e){return`${tt}${encodeURIComponent(e)}`}function it(e){return e.kind===`view`?nt(e.view):rt(e.sectionId)}function at(e){if(e.startsWith(tt)){let t=e.slice(7);if(!t)return null;try{return{kind:`section`,sectionId:decodeURIComponent(t)}}catch{return null}}let t=e.replace(/^#/,``);return et.includes(t)?{kind:`view`,view:t}:null}function ot(e){if(!Number.isFinite(e))return``;let t=Math.round((Date.now()-e)/6e4);if(t<1)return`just now`;if(t<60)return`${t} minute${t===1?``:`s`} ago`;let n=Math.round(t/60);if(n<24)return`${n} hour${n===1?``:`s`} ago`;let r=Math.round(n/24);return`${r} day${r===1?``:`s`} ago`}function st(){return`<button type="button" class="prb-update-btn" data-review-update>Update review</button>`}var ct=`Updating this review checks the latest commits and refreshes the PR conversation. Your progress and Buddy AI history will be kept.`;function lt(e){return`<details class="prb-update-alt">
|
|
37
37
|
<summary>Start a new review</summary>
|
|
38
38
|
<span>A brand new review, with its own findings and its own path through the change. Run <code>${t(e)}</code> in your session.<button type="button" class="prb-fresh-quiet" data-copy-command="${t(e)}">Copy</button></span>
|
|
39
|
-
</details>`}var
|
|
39
|
+
</details>`}var ut=`prreviewbuddy review --fresh`;function dt(e){return e?e.code.state===`changed`?{label:e.code.rewritten?`Code rewritten`:`Code changed`,state:`changed`}:e.code.state===`current`?{label:`Review up to date`,state:`current`}:{label:`Freshness unknown`,state:`unknown`}:{label:`Check for updates`,state:`unknown`}}function ft(e,n={}){if(!e)return``;let r=e.code.state===`changed`,i=e.code.reason===`missing-commit`,a=n.dismissedSha!==void 0&&n.dismissedSha===e.code.latestSha;if(!n.open&&(!(r||i)||a))return``;let o=_t(e.code),s=[...o.facts,`checked ${t(ot(e.checkedAt))}`];return`<div class="prb-fresh" data-state="${r||i?`changed`:`quiet`}" role="status">
|
|
40
40
|
<div class="prb-fresh-head">
|
|
41
41
|
<span class="prb-fresh-dot" data-freshness="${o.state}" aria-hidden="true"></span>
|
|
42
42
|
<strong class="prb-fresh-title">${t(o.title)}</strong>
|
|
43
43
|
<span class="prb-fresh-facts">${s.join(` · `)}</span>
|
|
44
44
|
</div>
|
|
45
45
|
${o.consequence?`<p class="prb-fresh-say">${o.consequence}</p>`:``}
|
|
46
|
-
${
|
|
47
|
-
</div>`}function
|
|
48
|
-
${r?
|
|
46
|
+
${pt(e,n,r||i)}
|
|
47
|
+
</div>`}function pt(e,t,n){let r=t.actions&&n,i=n?``:`<button type="button" class="prb-fresh-close" data-fresh-close aria-label="Close">×</button>`;return`<div class="prb-fresh-actions">
|
|
48
|
+
${r?st():``}
|
|
49
49
|
<button type="button" class="prb-fresh-quiet" data-fresh-recheck>Check review status</button>
|
|
50
|
-
${r
|
|
50
|
+
${r?lt(ut):``}
|
|
51
51
|
${i}
|
|
52
|
-
${
|
|
53
|
-
</div>`}function
|
|
52
|
+
${mt(e,t,n,r===!0)}
|
|
53
|
+
</div>`}function mt(e,n,r,i){let a=[i?t(ct):``,vt(e.code,e.checkout.reason!==`no-pull-request`),yt(e,n.actions===!0),r?`<button type="button" class="prb-fresh-quiet" data-fresh-dismiss="${t(e.code.latestSha??``)}">Dismiss this warning</button>`:``].filter(e=>e!==``);if(a.length===0)return``;let o=`<div class="prb-fresh-notes">${a.map(e=>`<p>${e}</p>`).join(``)}</div>`;return r?`<details class="prb-fresh-more">
|
|
54
54
|
<summary>More details</summary>
|
|
55
55
|
${o}
|
|
56
|
-
</details>`:o}function
|
|
56
|
+
</details>`:o}function ht(e,t){return e===null?[]:[`${e} file${e===1?``:`s`} ${t}`]}function gt(e){return e?`<code title="${t(e)}">${t(e.slice(0,7))}</code>`:``}function y(e){return e?[`reviewed ${gt(e)}`]:[]}function _t(e){if(e.state===`current`)return{state:`current`,title:`Review up to date`,facts:y(e.reviewedSha),consequence:``};if(e.state===`changed`){if(e.rewritten)return{state:`changed`,title:`Code rewritten`,facts:[...y(e.reviewedSha),...ht(e.changedFiles,`differ`)],consequence:`The branch was rebased or amended, so this review describes older code.`};let t=e.newCommits===null?[]:[`${e.newCommits} new commit${e.newCommits===1?``:`s`}`];return{state:`changed`,title:`Code changed`,facts:[...y(e.reviewedSha),...t,...ht(e.changedFiles,`changed`)],consequence:`New commits landed, so the lines these findings cite may have moved.`}}switch(e.reason){case`uncommitted`:return{state:`unknown`,title:`Cannot be compared`,facts:y(e.reviewedSha),consequence:`This review read uncommitted work and nothing recorded what the working tree held, so whether the files still match cannot be told from here.`};case`missing-commit`:return{state:`unknown`,title:`Reviewed commit is gone`,facts:y(e.reviewedSha),consequence:`It is not in this repository any more, after a force-push or a branch rebuilt from scratch, so nothing can be measured against it.`};case`no-branch`:return{state:`unknown`,title:`Cannot be compared`,facts:y(e.reviewedSha),consequence:`This review’s branch is not in this repository, which is what a pull request from a fork or a branch deleted after merging looks like, so whether the findings still describe it cannot be told from here.`};default:return{state:`unknown`,title:`Cannot be compared`,facts:[],consequence:`Git could not be read in this checkout.`}}}function vt(e,n){if(!e.comparison)return``;let r=`<code>${t(e.comparison.ref)}</code>`;return e.state===`current`?n?`This review is based on the latest PR commit ${gt(e.reviewedSha)}.`:`This review is based on ${gt(e.reviewedSha)}, the latest commit on ${r}.`:e.comparison.remote?`This review is currently based on ${r}. <strong>Check review status</strong> compares against the latest version you already have locally. <strong>Update review</strong> fetches the newest version first.`:`This review is currently based on ${r}, the branch it is of.`}function yt(e,n){if(!e.conversation.attached)return``;let r=t(ot(e.conversation.importedAt));return n?`<button type="button" class="prb-fresh-quiet" data-pr-recheck>Re-check the conversation</button> to refresh comments and resolved threads without re-running the code review. Last checked ${r}.`:`The PR conversation was last checked ${r}.`}function bt(e){return e<3e4?1e3:e<12e4?3e3:e<6e5?8e3:15e3}function xt(e,i,a){let o=e.scope===`change`?`Whole change`:i.get(e.scope)??`A theme of this change`,s=e.scope===`change`?``:e.scope;return`<article class="prb-diagram" id="prb-diagram-${t(e.scope)}" data-diagram-card="${t(e.scope)}">
|
|
57
57
|
<header class="prb-diagram-head">
|
|
58
58
|
<div class="prb-diagram-heading">
|
|
59
59
|
<h4 class="prb-diagram-title">
|
|
@@ -72,25 +72,25 @@ import{t as e}from"./chunk-B9H2wUlQ.js";function t(e){return e.replace(/&/g,`&am
|
|
|
72
72
|
</div>
|
|
73
73
|
</header>
|
|
74
74
|
${e.caption?`<p class="prb-diagram-caption">${t(e.caption)}</p>`:``}
|
|
75
|
-
${
|
|
75
|
+
${St(e,a)}
|
|
76
76
|
<div class="prb-diagram-canvas" data-diagram-canvas></div>
|
|
77
77
|
<details class="prb-diagram-source">
|
|
78
78
|
<summary>Diagram source</summary>
|
|
79
79
|
<div class="${n}"><pre><code data-mermaid-source>${t(e.mermaid)}</code></pre><button type="button" class="${r}" aria-label="Copy code">Copy</button></div>
|
|
80
80
|
</details>
|
|
81
|
-
</article>`}function
|
|
81
|
+
</article>`}function St(e,n){return!e.commitSha||!n||e.commitSha===n?``:`<p class="prb-diagram-stale">Drawn from <code>${t(e.commitSha.slice(0,7))}</code>, before this review was brought up to date. Regenerate to draw it from the commit the review now describes.</p>`}var Ct=`modulepreload`,wt=function(e){return`/`+e},Tt={},Et=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}function s(e){return import.meta.resolve?import.meta.resolve(e):new URL(e,import.meta.url).href}r=o(t.map(t=>{if(t=wt(t,n),t=s(t),t in Tt)return;Tt[t]=!0;let r=t.endsWith(`.css`);for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}let i=document.createElement(`link`);if(i.rel=r?`stylesheet`:Ct,r||(i.as=`script`),i.crossOrigin=``,i.href=t,a&&i.setAttribute(`nonce`,a),document.head.appendChild(i),r)return new Promise((e,n)=>{i.addEventListener(`load`,e),i.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})},Dt=.5,Ot=3,kt=1.25,At=null;function jt(){return At??=Et(()=>import(`./chunk-B80S6zbH.js`).then(e=>(e.default.initialize({startOnLoad:!1,securityLevel:`strict`,htmlLabels:!1,flowchart:{htmlLabels:!1},theme:`neutral`,fontFamily:`inherit`}),e.default)),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17])),At}var Mt=new WeakSet,Nt=new WeakMap,Pt=new WeakMap,b=null;function Ft(e){return document.addEventListener(`click`,t=>{let n=t.target;if(!(n instanceof Element))return;let r=n.closest(`[data-diagram-stop]`);if(r){r.setAttribute(`disabled`,``),r.textContent=`Stopping…`,b?.abort();return}let i=n.closest(`[data-diagram-toggle]`);if(i){Ht(i.closest(`[data-diagram-card]`),i.getAttribute(`aria-expanded`)===`true`);return}let a=n.closest(`[data-diagram-zoom]`);if(a){Gt(a.closest(`[data-diagram-card]`),a.dataset.diagramZoom??`reset`);return}let o=n.closest(`[data-diagram-request]`);o&&It(e,o.dataset.diagramRequest||null)}),{drawPane:Ut}}async function It(e,t){if(b)return;let n=t??`change`,r=document.querySelector(`[data-diagram-pane]`),i=r?.querySelector(`[data-diagram-card="${$t(n)}"]`)??null??Rt(r,n,t);if(!i)return;Lt(),e.showDiagrams();let a=zt(i);b=new AbortController,Jt(!1);try{let n=await fetch(e.endpoint(`/diagram`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({sectionId:t}),signal:b.signal}),r=await n.json().catch(()=>null);if(!n.ok||!r?.diagram)return Bt(i,a,r?.error??`Buddy AI did not return a diagram. Check the terminal running PR Review Buddy.`);Vt(i,r.diagram,t)}catch(e){if(e instanceof DOMException&&e.name===`AbortError`){i.hasAttribute(`data-diagram-pending`)?(i.remove(),Lt()):a.remove();return}Bt(i,a,`Could not reach PR Review Buddy. The workspace server may have stopped.`)}finally{b=null,Jt(!0)}}function Lt(){let e=document.querySelectorAll(`[data-diagram-pane] [data-diagram-card]`).length,t=document.querySelector(`[data-view-nav="diagram"]`);if(e===0){t?.remove();return}if(!t){let e=document.querySelector(`[data-view-nav="issues"]`);if(!e)return;t=document.createElement(`button`),t.setAttribute(`type`,`button`),t.className=`prb-rail-item`,t.dataset.viewNav=`diagram`,t.innerHTML=`<span class="prb-rail-order"></span><span class="prb-rail-label"><span class="prb-rail-title">Diagrams</span></span><span class="prb-rail-count"></span>`,e.before(t)}let n=t.querySelector(`.prb-rail-count`);n&&(n.textContent=String(e),n.setAttribute(`aria-label`,e===1?`1 diagram`:`${e} diagrams`))}function Rt(e,t,n){if(!e)return null;let r=document.createElement(`article`);return r.className=`prb-diagram`,r.dataset.diagramCard=t,r.setAttribute(`data-diagram-pending`,``),r.innerHTML=`<header class="prb-diagram-head">
|
|
82
82
|
<div class="prb-diagram-heading">
|
|
83
83
|
<h4 class="prb-diagram-title">Drawing…</h4>
|
|
84
|
-
<p class="prb-diagram-scope">${t===`change`?`Whole change`:
|
|
84
|
+
<p class="prb-diagram-scope">${t===`change`?`Whole change`:Qt(Yt(n))}</p>
|
|
85
85
|
</div>
|
|
86
|
-
</header>`,
|
|
86
|
+
</header>`,Xt(e,r,n),r}function zt(e){e.querySelector(`[data-diagram-status]`)?.remove();let t=document.createElement(`p`);t.className=`prb-diagram-status`,t.setAttribute(`data-diagram-status`,``),t.innerHTML=`<span class="prb-thinking"><i></i><i></i><i></i></span><span>Reading the change…</span>`;let n=document.createElement(`button`);return n.type=`button`,n.className=`prb-diagram-redraw`,n.setAttribute(`data-diagram-stop`,``),n.textContent=`Stop`,t.appendChild(n),e.querySelector(`.prb-diagram-head`)?.insertAdjacentElement(`afterend`,t),e.scrollIntoView({behavior:en()?`auto`:`smooth`,block:`start`}),t}function Bt(e,t,n){if(t.className=`prb-diagram-failed`,t.textContent=n,e.hasAttribute(`data-diagram-pending`)){let n=document.createElement(`button`);n.type=`button`,n.className=`prb-diagram-redraw`,n.dataset.diagramRequest=e.dataset.diagramCard===`change`?``:e.dataset.diagramCard??``,n.textContent=`Try again`,t.appendChild(document.createTextNode(` `)),t.appendChild(n)}}function Vt(e,t,n){let r=xt(t,new Map(n?[[n,Yt(n)]]:[]),t.commitSha),i=document.createElement(`div`);i.innerHTML=r;let a=i.firstElementChild;a&&(e.replaceWith(a),Lt(),Wt(a))}function Ht(e,t){e&&(e.toggleAttribute(`data-diagram-collapsed`,t),e.querySelector(`[data-diagram-toggle]`)?.setAttribute(`aria-expanded`,String(!t)),t||Wt(e))}function Ut(){for(let e of document.querySelectorAll(`[data-diagram-pane] [data-diagram-card]`))Wt(e)}async function Wt(e){let t=e.querySelector(`[data-diagram-canvas]`),n=e.querySelector(`[data-mermaid-source]`)?.textContent??``;if(!(!t||!n||Mt.has(e)||e.hasAttribute(`data-diagram-collapsed`))){Mt.add(e);try{let e=await jt();await e.parse(n);let{svg:r}=await e.render(`prb-mermaid-${Math.random().toString(36).slice(2)}`,n);t.innerHTML=r}catch{Mt.delete(e),t.innerHTML=``;let n=document.createElement(`p`);n.className=`prb-diagram-failed`,n.textContent=`This diagram could not be drawn. Its source is below, and Regenerate will ask for another.`,t.replaceWith(n),e.querySelector(`details`)?.setAttribute(`open`,``)}}}function Gt(e,t){let n=e?.querySelector(`[data-diagram-canvas] svg`),r=e?.querySelector(`[data-diagram-canvas]`);if(!e||!n||!r)return;if(t===`reset`){Pt.delete(e),r.removeAttribute(`data-zoomed`),n.style.removeProperty(`width`);return}let i=Kt(e,n);if(i<=0)return;let a=qt((Pt.get(e)??1)*(t===`in`?kt:1/kt));Pt.set(e,a),r.setAttribute(`data-zoomed`,``),n.style.width=`${Math.round(i*a)}px`}function Kt(e,t){let n=Nt.get(e);if(n)return n;let r=t.getBoundingClientRect().width;if(r>0)return Nt.set(e,r),r;let i=t.getAttribute(`viewBox`)?.split(/[\s,]+/),a=Number(i?.[2]??0);return Number.isFinite(a)?a:0}function qt(e){return Math.min(Ot,Math.max(Dt,e))}function Jt(e){for(let t of document.querySelectorAll(`[data-diagram-request]`))t.disabled=!e}function Yt(e){return e?document.querySelector(`[data-goto-section="${$t(e)}"]`)?.querySelector(`.prb-rail-title`)?.textContent?.trim()||`A theme of this change`:`Whole change`}function Xt(e,t,n){let r=Zt(n);for(let n of e.querySelectorAll(`[data-diagram-card]`)){let e=n.dataset.diagramCard??``;if(Zt(e===`change`?null:e)>r){n.before(t);return}}e.appendChild(t)}function Zt(e){if(!e)return-1;let t=document.querySelector(`[data-goto-section="${$t(e)}"]`);return Number(t?.dataset.themeIndex??0)}function Qt(e){let t=document.createElement(`span`);return t.textContent=e,t.innerHTML}function $t(e){return CSS.escape(e)}function en(){return window.matchMedia(`(prefers-reduced-motion: reduce)`).matches}var x=document.body,tn=x.dataset.apiBase??``,nn=x.dataset.token??``,rn=x.dataset.editorLabel??``,an=x.dataset.editorTemplate??``,on=x.dataset.repoPath??``,sn=x.dataset.explainPrompt??``,cn=x.dataset.sessionId??``;function S(e){return`${tn}${e}?t=${encodeURIComponent(nn)}`}function C(e){fetch(S(`/event`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(e),keepalive:!0}).catch(()=>{})}var ln=Ft({endpoint:S,showDiagrams:()=>pn(`diagram`)}),un=null,w=`whole change`;function dn(e){let t=it(e);window.location.hash!==t&&history.pushState(e,``,t),fn(e)}function fn(e){e.kind===`view`?hn(e.view):vn(e.sectionId)}function pn(e){dn({kind:`view`,view:e})}function mn(e){dn({kind:`section`,sectionId:e})}function hn(e){for(let t of document.querySelectorAll(`.prb-view`))t.hidden=t.dataset.view!==e;for(let t of document.querySelectorAll(`[data-view-nav]`))t.setAttribute(`aria-current`,String(t.dataset.viewNav===e));C({event:`view_opened`,view:e}),e===`diagram`&&ln.drawPane(),gn(),document.querySelector(`.prb-doc`)?.scrollTo({top:0})}function gn(){for(let e of document.querySelectorAll(`[data-goto-section]`))e.setAttribute(`aria-current`,`false`);un=null,w=`whole change`,bn()}function _n(e){let t=document.querySelector(`[data-rail-toggle]`),n=document.getElementById(`prb-rail-path`);!t||!n||(t.setAttribute(`aria-expanded`,String(e)),t.setAttribute(`aria-label`,e?`Collapse the review path`:`Expand the review path`),n.hidden=!e)}function vn(e){hn(`guide`),_n(!0);for(let t of document.querySelectorAll(`[data-goto-section]`))t.setAttribute(`aria-current`,String(t.dataset.gotoSection===e));let t=document.getElementById(`pr-helper-guide-section-${e}`);if(!t)return;t.classList.remove(`pr-helper-guide-section-collapsed`),t.scrollIntoView({behavior:yn()?`auto`:`smooth`,block:`start`});let n=document.querySelector(`[data-goto-section="${CSS.escape(e)}"]`);C({event:`theme_opened`,themeIndex:Number(n?.dataset.themeIndex??-1),attention:n?.querySelector(`.prb-attention`)?.dataset.attention??`medium`,isRecommendedStart:n?.dataset.recommendedStart===`true`}),un=e,w=t.querySelector(`.pr-helper-guide-section-title`)?.textContent?.trim()??`this theme`,bn()}function yn(){return window.matchMedia(`(prefers-reduced-motion: reduce)`).matches}function bn(){let e=document.querySelector(`[data-ask-scope]`);e&&(e.textContent=w,e.title=un?`Questions are answered about "${w}"`:`Questions cover the whole change`)}function T(e){return e.replace(/&/g,`&`).replace(/</g,`<`).replace(/>/g,`>`).replace(/"/g,`"`)}function xn(e){return e.tagName===`LI`?{parent:e,position:`beforeend`}:{parent:e,position:`afterend`}}async function Sn(e){let t=e.tagName===`LI`?e.querySelector(`:scope > .prb-code`):e.nextElementSibling;if(t?.classList.contains(`prb-code`)){t.remove(),e.setAttribute(`aria-expanded`,`false`);return}let n=e.dataset.file;if(!n)return;let r=Number(e.dataset.line)||0,i=e.tagName!==`LI`,a=document.createElement(`div`);a.className=`prb-code`,a.innerHTML=`<p class="prb-code-status">Reading…</p>`;let{parent:o,position:s}=xn(e);o.insertAdjacentElement(s,a),e.setAttribute(`aria-expanded`,`true`),C({event:`file_opened`,fromFinding:i,targeted:r>0}),await Cn(a,n,r,!1)}async function Cn(e,t,n,r){try{let i=`&path=${encodeURIComponent(t)}${n?`&line=${n}`:``}${r?`&expand=1`:``}`,a=await fetch(`${S(`/file`)}${i}`),o=await a.json();if(!a.ok){e.innerHTML=`<p class="prb-code-status">${T(o?.error??`Could not read that file.`)}</p>`;return}wn(e,o,n)}catch{e.innerHTML=`<p class="prb-code-status">Could not reach PR Review Buddy. The workspace server may have stopped.</p>`}}function wn(e,t,n){let r=new Set(t.addedLines),i=t.lines.map((e,i)=>{let a=t.from+i;return`<tr class="${[r.has(a)?`prb-code-added`:``,a===n?`prb-code-target`:``].filter(Boolean).join(` `)}"><td class="prb-code-num">${a}</td><td class="prb-code-line">${T(e)||` `}</td></tr>`}).join(``),a=an&&on?t.checkout===`absent`?`<button type="button" class="prb-code-open" disabled>Not in your working folder</button>`:`<button type="button" class="prb-code-open" data-open-editor="${T(t.path)}" data-open-line="${n||t.from}">${T(`Open in ${rn||`editor`}`)}</button>`:``,o=t.pullRequest&&t.pullRequest.precise?`<a class="prb-code-open prb-code-pr" href="${T(t.pullRequest.href)}" target="_blank" rel="noopener noreferrer">${T(t.pullRequest.label)}</a>`:``,s=t.truncated?`<button type="button" class="prb-code-more" data-expand-file="${T(t.path)}">Show more of this file</button>`:``,c=t.checkout===`differs`?` · your editor will show a different version`:t.checkout===`absent`?` · not in your working folder`:``,l=t.source===`commit`?`<p class="prb-code-source">Viewing reviewed version${t.sourceSha?` <code>${T(t.sourceSha.slice(0,7))}</code>`:``}${c}</p>`:`<p class="prb-code-source">Viewing your working folder</p>`;e.innerHTML=`<div class="prb-code-header">
|
|
87
87
|
<span class="prb-code-range">lines ${t.from}\u2013${t.to} of ${t.totalLines}</span>
|
|
88
88
|
${o}
|
|
89
89
|
${a}
|
|
90
90
|
</div>
|
|
91
91
|
${l}
|
|
92
92
|
<div class="prb-code-scroll"><table class="prb-code-table"><tbody>${i}</tbody></table></div>
|
|
93
|
-
${s}`,e.querySelector(`.prb-code-target`)?.scrollIntoView({block:`center`})}function mn(e,t,n){let r=`${Yt.replace(/\/$/,``)}/${e}`,i=Jt.replace(`{path}`,r).replace(`{line}`,String(Math.max(1,t)));x({event:`editor_opened`,fromFinding:n}),window.location.href=i}var T=document.querySelector(`[data-ask-log]`);T&&T.querySelector(`.prb-msg`)&&T.scrollTo({top:T.scrollHeight});var E=document.querySelector(`[data-ask-form]`),D=E?.querySelector(`textarea`);function O(e,t){let n=document.createElement(`div`);return n.className=e===`user`?`prb-msg prb-msg-user`:`prb-msg prb-msg-${e===`error`?`error`:`assistant`}`,e===`assistant`?(n.classList.add(`prb-md`),n.innerHTML=u(t)):n.textContent=t,T?.appendChild(n),T?.scrollTo({top:T.scrollHeight}),n}function hn(){let e=document.createElement(`div`);return e.className=`prb-thinking`,e.innerHTML=`<i></i><i></i><i></i><span>Reading the change…</span>`,T?.appendChild(e),T?.scrollTo({top:T.scrollHeight}),e}var k=null;function gn(){let e=document.createElement(`div`);e.className=`prb-stopped`,e.textContent=`Stopped.`,T?.appendChild(e),T?.scrollTo({top:T.scrollHeight})}async function _n(e,t=`free_text`){let n=e.trim();if(!n)return;document.querySelector(`.prb-ask-empty`)?.remove(),O(`user`,n);let r=hn();k=new AbortController,vn(!0);try{let e=await fetch(b(`/ask`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({question:n,sectionId:S,source:t}),signal:k.signal}),i=await e.json().catch(()=>null);if(r.remove(),!e.ok||!i?.answer){O(`error`,i?.error??`Buddy AI did not answer. Check the terminal running PR Review Buddy.`);return}O(`assistant`,i.answer)}catch(e){r.remove(),e instanceof DOMException&&e.name===`AbortError`?(gn(),D&&(D.value=n)):O(`error`,`Could not reach PR Review Buddy. The workspace server may have stopped.`)}finally{k=null,vn(!1)}}function vn(e){let t=E?.querySelector(`button`);t&&(t.textContent=e?`Stop`:`Ask`,t.toggleAttribute(`data-stop`,e),t.disabled=!1),D&&(D.disabled=e),e||D?.focus()}function yn(){let e=E?.querySelector(`button`);e&&(e.textContent=`Stopping…`,e.disabled=!0),k?.abort()}E?.addEventListener(`submit`,e=>{if(e.preventDefault(),k)return yn();let t=D?.value??``;D&&(D.value=``),_n(t,xn(t))});var bn=null;function xn(e){return bn&&e.includes(bn)?`selection`:`free_text`}D?.addEventListener(`keydown`,e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),E?.requestSubmit())}),D?.addEventListener(`input`,()=>{D&&(D.style.height=`auto`,D.style.height=`${Math.min(D.scrollHeight,140)}px`)});async function Sn(e){try{await fetch(b(`/state`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({answeredQuestionIds:e})})}catch{}}function Cn(){return[...document.querySelectorAll(`[data-question-answered][data-answered="true"]`)].map(e=>e.dataset.questionAnswered??``).filter(Boolean)}function wn(e,t){e.dataset.answered=String(t),e.textContent=t?`Mark as unanswered`:`Mark answered`;let n=e.closest(`[data-finding-card]`);n?.classList.toggle(`pr-helper-question-card-answered`,t),n&&An(n,t,`questions`),In()}function Tn(){return[...document.querySelectorAll(`[data-issue-dismissed][data-dismissed="true"]`)].map(e=>({id:e.dataset.issueDismissed??``,sessionId:e.dataset.dismissedIn||Zt})).filter(e=>e.id)}async function En(e){try{await fetch(b(`/state`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({dismissedIssues:e})})}catch{}}function Dn(e,t){e.dataset.dismissed=String(t),e.textContent=t?`Reopen`:`Dismiss`,delete e.dataset.stale,t?e.dataset.dismissedIn=Zt:delete e.dataset.dismissedIn;let n=e.closest(`[data-finding-card]`);n&&(n.classList.toggle(`pr-helper-issue-card-dismissed`,t),n.querySelector(`.pr-helper-dismissal-stale`)?.remove(),n.querySelector(`.pr-helper-finding-status-dismissed`)?.remove(),t&&n.querySelector(`.pr-helper-issue-badges`)?.prepend(On()),An(n,t||e.dataset.settled===`true`,`issues`),Rn())}function On(){let e=document.createElement(`span`);return e.className=`pr-helper-finding-status pr-helper-finding-status-dismissed pr-helper-tip`,e.dataset.tip=ze,e.textContent=`Dismissed by you`,e}var kn=new WeakMap;function An(e,t,n){let r=e.closest(`.pr-helper-closed-findings-list`);if(t!==!!r){if(t){let t=e.parentElement;t&&kn.set(e,{parent:t,before:e.nextElementSibling}),Pn(n).append(e),t&&Nn(t)}else jn(e,n),(r?.children.length===0?r.closest(`.pr-helper-closed-findings`):null)?.remove();Fn(n)}}function jn(e,t){let n=kn.get(e);if(n?.parent.isConnected)n.parent.insertBefore(e,n.before);else{let n=Mn(e)??document.querySelector(`[data-view="${t}"]`);n?.insertBefore(e,n.querySelector(`.pr-helper-closed-findings`))}e.closest(`.pr-helper-question-group`)?.removeAttribute(`hidden`)}function Mn(e){let t=e.dataset.sectionId;return t?document.querySelector(`[data-question-group="${CSS.escape(t)}"]`):null}function Nn(e){let t=e.closest(`.pr-helper-question-group`);t&&!t.querySelector(`[data-finding-card]`)&&(t.hidden=!0)}function Pn(e){let t=document.querySelector(`[data-view="${e}"]`),n=t?.querySelector(`[data-closed-findings="${e}"] .pr-helper-closed-findings-list`);if(n)return n;let r=document.createElement(`details`);r.className=`pr-helper-closed-findings`,r.dataset.closedFindings=e;let i=document.createElement(`summary`);i.className=`pr-helper-closed-findings-summary`,i.setAttribute(`data-closed-findings-summary`,``);let a=document.createElement(`div`);return a.className=`pr-helper-closed-findings-list`,r.append(i,a),t?.append(r),a}function Fn(e){let t=document.querySelector(`[data-closed-findings="${e}"]`),n=t?.querySelector(`[data-closed-findings-summary]`);if(!t||!n)return;let r=document.querySelectorAll(`[data-view="${e}"] [data-finding-card]`).length,i=t.querySelectorAll(`[data-finding-card]`).length;if(t.toggleAttribute(`data-nothing-open`,r===i),e===`questions`){n.textContent=`Answered (${i})`;return}n.textContent=Ve(Ln())}function In(){let e=[...document.querySelectorAll(`[data-question-answered]`)];if(e.length===0)return;let t=e.filter(e=>e.dataset.answered!==`true`&&e.dataset.settled!==`true`).length,n=document.querySelector(`.pr-helper-questions-progress`);n&&(n.innerHTML=He(e.length,t)),zn(`questions`,e.length,t,`question`,`answered`)}function Ln(){let e=[...document.querySelectorAll(`[data-issue-dismissed]`)],t=0,n=0;for(let r of e){let e=r.dataset.settled===`true`,i=r.dataset.dismissed===`true`&&r.dataset.stale!==`true`;!e&&!i?t+=1:!e&&i&&(n+=1)}return{total:e.length,open:t,done:e.length-t,reviewerClosed:n}}function Rn(){let e=Ln();if(e.total===0)return;let t=document.querySelector(`[data-view="issues"]`),n=t?.querySelector(`.pr-helper-findings-progress`);!n&&t&&e.done>0&&(n=document.createElement(`div`),n.className=`pr-helper-findings-progress`,n.setAttribute(`role`,`status`),t.querySelector(`.prb-doc-title`)?.after(n)),n&&(n.innerHTML=Be(e.total,e.open,Re(e))),zn(`issues`,e.total,e.open,`issue`,Re(e))}function zn(e,t,n,r,i){let a=document.querySelector(`[data-view-nav="${e}"] .prb-rail-count`);if(!a)return;let o=e=>`${e} ${r}${e===1?``:`s`}`,s=t-n;a.classList.toggle(`prb-rail-count-done`,t>0&&n===0),t===0?(a.textContent=`0`,a.setAttribute(`aria-label`,`No ${r}s`)):n===0?(a.textContent=`✓`,a.setAttribute(`aria-label`,`All ${o(t)} ${i}`)):(a.textContent=String(n),a.setAttribute(`aria-label`,s===0?o(t):`${n} of ${o(t)} left, ${s} ${i}`))}document.addEventListener(`click`,e=>{let t=e.target,n=t.closest(`[data-rail-toggle]`);if(n){on(n.getAttribute(`aria-expanded`)!==`true`);return}let r=t.closest(`[data-view-nav]`);if(r?.dataset.viewNav){tn(r.dataset.viewNav);return}let i=t.closest(`[data-overview-nav]`);if(i?.dataset.overviewNav){tn(i.dataset.overviewNav===`guide`?`guide`:i.dataset.overviewNav);return}let a=t.closest(`[data-goto-section]`);if(a?.dataset.gotoSection){nn(a.dataset.gotoSection);return}let o=t.closest(`[data-open-editor]`);if(o?.dataset.openEditor){mn(o.dataset.openEditor,Number(o.dataset.openLine)||1,!0);return}let s=t.closest(`[data-expand-file]`);if(s?.dataset.expandFile){let e=s.closest(`.prb-code`);e&&fn(e,s.dataset.expandFile,0,!0);return}let c=t.closest(`[data-file]`);if(c?.dataset.file){dn(c);return}let l=t.closest(`[data-guide-toggle]`);if(l?.dataset.guideToggle){document.getElementById(`pr-helper-guide-section-${l.dataset.guideToggle}`)?.classList.toggle(`pr-helper-guide-section-collapsed`);return}let u=t.closest(`[data-question-answered]`);if(u?.dataset.questionAnswered){wn(u,u.dataset.answered!==`true`);let e=Cn();Sn(e),x({event:`question_marked_answered`,answered:e.length,total:document.querySelectorAll(`[data-question-answered]`).length});return}let d=t.closest(`[data-issue-dismissed]`);if(d?.dataset.issueDismissed){Dn(d,d.dataset.stale===`true`||d.dataset.dismissed!==`true`);let e=Tn();En(e),x({event:`issue_dismissed`,dismissed:e.length,total:document.querySelectorAll(`[data-issue-dismissed]`).length});return}let ee=t.closest(`[data-suggestion]`);if(ee){_n(ee.textContent??``,`suggestion`);return}if(t.closest(`.pr-helper-explain-simply-button`)){Hn(),_n(Xt,`explain_simply`);return}let te=t.closest(`[data-prompt-use]`);if(te?.dataset.promptUse){sr(te.dataset.promptUse);return}let f=t.closest(`[data-prompt-edit]`);if(f?.dataset.promptEdit){_r(f.dataset.promptEdit);return}if(t.closest(`[data-prompt-add]`)){_r(``);return}t.closest(`[data-ask-toggle]`)&&Vn(!Bn())});var A=document.querySelector(`.prb-body`),j=document.querySelector(`.prb-ask`);function Bn(){return!!j&&getComputedStyle(j).display!==`none`}function Vn(e){A&&(A.dataset.ask=e?`open`:`closed`),document.querySelector(`[data-ask-toggle]`)?.setAttribute(`aria-expanded`,String(e))}function Hn(){Vn(!0)}function Un(){document.querySelector(`[data-ask-toggle]`)?.setAttribute(`aria-expanded`,String(Bn()))}window.addEventListener(`resize`,Un);var M=document.querySelector(`[data-shutdown]`),Wn=document.querySelector(`[data-shutdown-dialog]`),N=document.querySelector(`[data-shutdown-confirm]`);M?.addEventListener(`click`,()=>Wn?.showModal()),document.querySelector(`[data-shutdown-cancel]`)?.addEventListener(`click`,()=>Wn?.close()),N?.addEventListener(`click`,()=>{N.disabled=!0,N.textContent=`Stopping…`,fetch(b(`/shutdown`),{method:`POST`}).then(()=>{Wn?.close(),Gn()}).catch(()=>{N.disabled=!1,N.textContent=`Stop server`})});function Gn(){document.body.dataset.serverStopped=`true`;let e=document.createElement(`div`);e.className=`prb-stopped-notice`,e.setAttribute(`role`,`status`);let t=document.body.dataset.wayBack;e.textContent=t?`Workspace server stopped. This page is no longer being served. Run ${t} to bring it back.`:`Workspace server stopped. This page is no longer being served.`,document.body.prepend(e),M&&(M.textContent=`Server stopped`,M.disabled=!0)}var P=document.querySelector(`[data-file-filter]`),Kn=document.querySelector(`[data-file-count]`),qn=document.querySelector(`[data-file-none]`);function Jn(){let e=(P?.value??``).trim().toLowerCase(),t=0;for(let n of document.querySelectorAll(`[data-view="files"] .prb-file`)){let r=e===``||(n.dataset.search??``).includes(e);n.hidden=!r,r&&(t+=1);let i=n.nextElementSibling;i?.classList.contains(`prb-code`)&&(i.hidden=!r)}for(let t of document.querySelectorAll(`[data-file-group]`)){let n=t.querySelectorAll(`.prb-file:not([hidden])`).length;t.hidden=n===0;let r=t.querySelector(`[data-group-heading]`);if(!r)continue;let i=Number(r.dataset.groupTotal)||0;r.textContent=e&&n!==i?`${r.dataset.groupHeading} · ${n} of ${i}`:`${r.dataset.groupHeading} · ${i}`}qn&&(qn.hidden=t>0),Kn&&(Kn.textContent=e?`${t} of ${F} file${F===1?``:`s`}`:`${F} file${F===1?``:`s`}`)}var F=document.querySelectorAll(`[data-view="files"] .prb-file`).length;P?.addEventListener(`input`,Jn),P?.addEventListener(`keydown`,e=>{e.key===`Escape`&&P.value!==``&&(e.preventDefault(),P.value=``,Jn())}),document.addEventListener(`keydown`,e=>{if(e.key!==`Enter`&&e.key!==` `)return;let t=e.target,n=t.closest(`.prb-file[data-file][role="button"]`);!n||n!==t||(e.preventDefault(),dn(n))});var Yn=320,Xn=()=>Math.round(window.innerWidth/2),Zn=e=>Math.round(Math.min(Xn(),Math.max(Yn,e)));function I(e){A&&(e===null?A.style.removeProperty(`--ask-width`):A.style.setProperty(`--ask-width`,`${e}px`))}function L(){return j?Math.round(j.getBoundingClientRect().width):Yn}function R(e){fetch(b(`/prefs`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({askWidth:e})}).catch(()=>{})}var z=document.querySelector(`[data-ask-resize]`);z?.addEventListener(`pointerdown`,e=>{if(e.button!==0||!A||!j)return;e.preventDefault(),z.setPointerCapture(e.pointerId),A.dataset.resizing=`true`;let t=e.clientX,n=L(),r=e=>{I(Zn(n+(t-e.clientX)))},i=()=>{z.removeEventListener(`pointermove`,r),z.removeEventListener(`pointerup`,i),z.removeEventListener(`pointercancel`,i),delete A.dataset.resizing,R(L())};z.addEventListener(`pointermove`,r),z.addEventListener(`pointerup`,i),z.addEventListener(`pointercancel`,i)}),z?.addEventListener(`keydown`,e=>{let t=e.shiftKey?64:16;if(e.key===`ArrowLeft`||e.key===`ArrowRight`){e.preventDefault();let n=e.key===`ArrowLeft`?t:-t,r=Zn(L()+n);I(r),R(r);return}(e.key===`Home`||e.key===`Escape`)&&(e.preventDefault(),I(null),R(null))}),z?.addEventListener(`dblclick`,()=>{I(null),R(null)}),window.addEventListener(`resize`,()=>{Bn()&&A?.style.getPropertyValue(`--ask-width`)&&I(Zn(L()))});var Qn=3e4,B=document.visibilityState===`visible`?Date.now():null,$n=0;function er(){B!==null&&($n+=Date.now()-B,B=Date.now())}function tr(){er();let e=Math.round($n/1e3);return $n-=e*1e3,e}document.addEventListener(`visibilitychange`,()=>{document.visibilityState===`visible`?B=Date.now():(er(),B=null)}),setInterval(()=>{let e=tr();e>0&&x({event:`workspace_heartbeat`,visibleSeconds:e})},Qn),window.addEventListener(`pagehide`,()=>{let e=b(`/event`),t=JSON.stringify({event:`review_completed`,trailingSeconds:tr()});navigator.sendBeacon?.(e,new Blob([t],{type:`application/json`}))||fetch(e,{method:`POST`,headers:{"content-type":`application/json`},body:t,keepalive:!0}).catch(()=>{})});var nr=document.querySelector(`[data-prompt-bank]`),rr=document.querySelector(`[data-prompt-list]`),V=ir();function ir(){try{let e=JSON.parse(nr?.dataset.prompts??`[]`);return Array.isArray(e)?e:[]}catch{return[]}}function ar(){rr&&(rr.innerHTML=V.map(e=>`<span class="prb-bank-item">
|
|
94
|
-
<button type="button" class="prb-bank-use" data-prompt-use="${
|
|
95
|
-
<button type="button" class="prb-bank-edit" data-prompt-edit="${
|
|
96
|
-
</span>`).join(``),
|
|
93
|
+
${s}`,e.querySelector(`.prb-code-target`)?.scrollIntoView({block:`center`})}function Tn(e,t,n){let r=`${on.replace(/\/$/,``)}/${e}`,i=an.replace(`{path}`,r).replace(`{line}`,String(Math.max(1,t)));C({event:`editor_opened`,fromFinding:n}),window.location.href=i}var E=document.querySelector(`[data-ask-log]`);E&&E.querySelector(`.prb-msg`)&&E.scrollTo({top:E.scrollHeight});var D=document.querySelector(`[data-ask-form]`),O=D?.querySelector(`textarea`);function k(e,t){let n=document.createElement(`div`);return n.className=e===`user`?`prb-msg prb-msg-user`:`prb-msg prb-msg-${e===`error`?`error`:`assistant`}`,e===`assistant`?(n.classList.add(`prb-md`),n.innerHTML=u(t)+Te(t)):n.textContent=t,E?.appendChild(n),E?.scrollTo({top:E.scrollHeight}),n}function En(){let e=document.createElement(`div`);return e.className=`prb-thinking`,e.innerHTML=`<i></i><i></i><i></i><span>Reading the change…</span>`,E?.appendChild(e),E?.scrollTo({top:E.scrollHeight}),e}var A=null;function Dn(){let e=document.createElement(`div`);e.className=`prb-stopped`,e.textContent=`Stopped.`,E?.appendChild(e),E?.scrollTo({top:E.scrollHeight})}async function On(e,t=`free_text`){let n=e.trim();if(!n)return;document.querySelector(`.prb-ask-empty`)?.remove(),k(`user`,n);let r=En();A=new AbortController,kn(!0);try{let e=await fetch(S(`/ask`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({question:n,sectionId:un,source:t}),signal:A.signal}),i=await e.json().catch(()=>null);if(r.remove(),!e.ok||!i?.answer){k(`error`,i?.error??`Buddy AI did not answer. Check the terminal running PR Review Buddy.`);return}k(`assistant`,i.answer)}catch(e){r.remove(),e instanceof DOMException&&e.name===`AbortError`?(Dn(),O&&(O.value=n)):k(`error`,`Could not reach PR Review Buddy. The workspace server may have stopped.`)}finally{A=null,kn(!1)}}function kn(e){let t=D?.querySelector(`button`);t&&(t.textContent=e?`Stop`:`Ask`,t.toggleAttribute(`data-stop`,e),t.disabled=!1),O&&(O.disabled=e),e||O?.focus()}function An(){let e=D?.querySelector(`button`);e&&(e.textContent=`Stopping…`,e.disabled=!0),A?.abort()}D?.addEventListener(`submit`,e=>{if(e.preventDefault(),A)return An();let t=O?.value??``;O&&(O.value=``),On(t,Mn(t))});var jn=null;function Mn(e){return jn&&e.includes(jn)?`selection`:`free_text`}O?.addEventListener(`keydown`,e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),D?.requestSubmit())}),O?.addEventListener(`input`,()=>{O&&(O.style.height=`auto`,O.style.height=`${Math.min(O.scrollHeight,140)}px`)});async function Nn(e){try{await fetch(S(`/state`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({answeredQuestionIds:e})})}catch{}}function Pn(){return[...document.querySelectorAll(`[data-question-answered][data-answered="true"]`)].map(e=>e.dataset.questionAnswered??``).filter(Boolean)}function Fn(e,t){e.dataset.answered=String(t),e.textContent=t?`Mark as unanswered`:`Mark answered`;let n=e.closest(`[data-finding-card]`);n?.classList.toggle(`pr-helper-question-card-answered`,t),n&&Vn(n,t,`questions`),qn()}function In(){return[...document.querySelectorAll(`[data-issue-dismissed][data-dismissed="true"]`)].map(e=>({id:e.dataset.issueDismissed??``,sessionId:e.dataset.dismissedIn||cn})).filter(e=>e.id)}async function Ln(e){try{await fetch(S(`/state`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({dismissedIssues:e})})}catch{}}function Rn(e,t){e.dataset.dismissed=String(t),e.textContent=t?`Reopen`:`Dismiss`,delete e.dataset.stale,t?e.dataset.dismissedIn=cn:delete e.dataset.dismissedIn;let n=e.closest(`[data-finding-card]`);n&&(n.classList.toggle(`pr-helper-issue-card-dismissed`,t),n.querySelector(`.pr-helper-dismissal-stale`)?.remove(),n.querySelector(`.pr-helper-finding-status-dismissed`)?.remove(),t&&n.querySelector(`.pr-helper-issue-badges`)?.prepend(zn()),Vn(n,t||e.dataset.settled===`true`,`issues`),Yn())}function zn(){let e=document.createElement(`span`);return e.className=`pr-helper-finding-status pr-helper-finding-status-dismissed pr-helper-tip`,e.dataset.tip=Ye,e.textContent=`Dismissed by you`,e}var Bn=new WeakMap;function Vn(e,t,n){let r=e.closest(`.pr-helper-closed-findings-list`);if(t!==!!r){if(t){let t=e.parentElement;t&&Bn.set(e,{parent:t,before:e.nextElementSibling}),Gn(n).append(e),t&&Wn(t)}else Hn(e,n),(r?.children.length===0?r.closest(`.pr-helper-closed-findings`):null)?.remove();Kn(n)}}function Hn(e,t){let n=Bn.get(e);if(n?.parent.isConnected)n.parent.insertBefore(e,n.before);else{let n=Un(e)??document.querySelector(`[data-view="${t}"]`);n?.insertBefore(e,n.querySelector(`.pr-helper-closed-findings`))}e.closest(`.pr-helper-question-group`)?.removeAttribute(`hidden`)}function Un(e){let t=e.dataset.sectionId;return t?document.querySelector(`[data-question-group="${CSS.escape(t)}"]`):null}function Wn(e){let t=e.closest(`.pr-helper-question-group`);t&&!t.querySelector(`[data-finding-card]`)&&(t.hidden=!0)}function Gn(e){let t=document.querySelector(`[data-view="${e}"]`),n=t?.querySelector(`[data-closed-findings="${e}"] .pr-helper-closed-findings-list`);if(n)return n;let r=document.createElement(`details`);r.className=`pr-helper-closed-findings`,r.dataset.closedFindings=e;let i=document.createElement(`summary`);i.className=`pr-helper-closed-findings-summary`,i.setAttribute(`data-closed-findings-summary`,``);let a=document.createElement(`div`);return a.className=`pr-helper-closed-findings-list`,r.append(i,a),t?.append(r),a}function Kn(e){let t=document.querySelector(`[data-closed-findings="${e}"]`),n=t?.querySelector(`[data-closed-findings-summary]`);if(!t||!n)return;let r=document.querySelectorAll(`[data-view="${e}"] [data-finding-card]`).length,i=t.querySelectorAll(`[data-finding-card]`).length;if(t.toggleAttribute(`data-nothing-open`,r===i),e===`questions`){n.textContent=`Answered (${i})`;return}n.textContent=Ze(Jn())}function qn(){let e=[...document.querySelectorAll(`[data-question-answered]`)];if(e.length===0)return;let t=e.filter(e=>e.dataset.answered!==`true`&&e.dataset.settled!==`true`).length,n=document.querySelector(`.pr-helper-questions-progress`);n&&(n.innerHTML=Qe(e.length,t)),Xn(`questions`,e.length,t,`question`,`answered`)}function Jn(){let e=[...document.querySelectorAll(`[data-issue-dismissed]`)],t=0,n=0;for(let r of e){let e=r.dataset.settled===`true`,i=r.dataset.dismissed===`true`&&r.dataset.stale!==`true`;!e&&!i?t+=1:!e&&i&&(n+=1)}return{total:e.length,open:t,done:e.length-t,reviewerClosed:n}}function Yn(){let e=Jn();if(e.total===0)return;let t=document.querySelector(`[data-view="issues"]`),n=t?.querySelector(`.pr-helper-findings-progress`);!n&&t&&e.done>0&&(n=document.createElement(`div`),n.className=`pr-helper-findings-progress`,n.setAttribute(`role`,`status`),t.querySelector(`.prb-doc-title`)?.after(n)),n&&(n.innerHTML=Xe(e.total,e.open,Je(e))),Xn(`issues`,e.total,e.open,`issue`,Je(e))}function Xn(e,t,n,r,i){let a=document.querySelector(`[data-view-nav="${e}"] .prb-rail-count`);if(!a)return;let o=e=>`${e} ${r}${e===1?``:`s`}`,s=t-n;a.classList.toggle(`prb-rail-count-done`,t>0&&n===0),t===0?(a.textContent=`0`,a.setAttribute(`aria-label`,`No ${r}s`)):n===0?(a.textContent=`✓`,a.setAttribute(`aria-label`,`All ${o(t)} ${i}`)):(a.textContent=String(n),a.setAttribute(`aria-label`,s===0?o(t):`${n} of ${o(t)} left, ${s} ${i}`))}document.addEventListener(`click`,e=>{let t=e.target,n=t.closest(`[data-rail-toggle]`);if(n){_n(n.getAttribute(`aria-expanded`)!==`true`);return}let r=t.closest(`[data-view-nav]`);if(r?.dataset.viewNav){pn(r.dataset.viewNav);return}let i=t.closest(`[data-overview-nav]`);if(i?.dataset.overviewNav){pn(i.dataset.overviewNav===`guide`?`guide`:i.dataset.overviewNav);return}let a=t.closest(`[data-goto-section]`);if(a?.dataset.gotoSection){mn(a.dataset.gotoSection);return}let o=t.closest(`[data-open-editor]`);if(o?.dataset.openEditor){Tn(o.dataset.openEditor,Number(o.dataset.openLine)||1,!0);return}let s=t.closest(`[data-expand-file]`);if(s?.dataset.expandFile){let e=s.closest(`.prb-code`);e&&Cn(e,s.dataset.expandFile,0,!0);return}let c=t.closest(`[data-file]`);if(c?.dataset.file){Sn(c);return}let l=t.closest(`[data-guide-toggle]`);if(l?.dataset.guideToggle){document.getElementById(`pr-helper-guide-section-${l.dataset.guideToggle}`)?.classList.toggle(`pr-helper-guide-section-collapsed`);return}let u=t.closest(`[data-question-answered]`);if(u?.dataset.questionAnswered){Fn(u,u.dataset.answered!==`true`);let e=Pn();Nn(e),C({event:`question_marked_answered`,answered:e.length,total:document.querySelectorAll(`[data-question-answered]`).length});return}let d=t.closest(`[data-issue-dismissed]`);if(d?.dataset.issueDismissed){Rn(d,d.dataset.stale===`true`||d.dataset.dismissed!==`true`);let e=In();Ln(e),C({event:`issue_dismissed`,dismissed:e.length,total:document.querySelectorAll(`[data-issue-dismissed]`).length});return}let ee=t.closest(`[data-suggestion]`);if(ee){On(ee.textContent??``,`suggestion`);return}if(t.closest(`.pr-helper-explain-simply-button`)){$n(),On(sn,`explain_simply`);return}let te=t.closest(`[data-prompt-use]`);if(te?.dataset.promptUse){vr(te.dataset.promptUse);return}let f=t.closest(`[data-prompt-edit]`);if(f?.dataset.promptEdit){kr(f.dataset.promptEdit);return}if(t.closest(`[data-prompt-add]`)){kr(``);return}t.closest(`[data-ask-toggle]`)&&Qn(!Zn())});var j=document.querySelector(`.prb-body`),M=document.querySelector(`.prb-ask`);function Zn(){return!!M&&getComputedStyle(M).display!==`none`}function Qn(e){j&&(j.dataset.ask=e?`open`:`closed`),document.querySelector(`[data-ask-toggle]`)?.setAttribute(`aria-expanded`,String(e))}function $n(){Qn(!0)}function er(){document.querySelector(`[data-ask-toggle]`)?.setAttribute(`aria-expanded`,String(Zn()))}window.addEventListener(`resize`,er);var N=document.querySelector(`[data-shutdown]`),tr=document.querySelector(`[data-shutdown-dialog]`),P=document.querySelector(`[data-shutdown-confirm]`);N?.addEventListener(`click`,()=>tr?.showModal()),document.querySelector(`[data-shutdown-cancel]`)?.addEventListener(`click`,()=>tr?.close()),P?.addEventListener(`click`,()=>{P.disabled=!0,P.textContent=`Stopping…`,fetch(S(`/shutdown`),{method:`POST`}).then(()=>{tr?.close(),nr()}).catch(()=>{P.disabled=!1,P.textContent=`Stop server`})});function nr(){document.body.dataset.serverStopped=`true`;let e=document.createElement(`div`);e.className=`prb-stopped-notice`,e.setAttribute(`role`,`status`);let t=document.body.dataset.wayBack;e.textContent=t?`Workspace server stopped. This page is no longer being served. Run ${t} to bring it back.`:`Workspace server stopped. This page is no longer being served.`,document.body.prepend(e),N&&(N.textContent=`Server stopped`,N.disabled=!0)}var F=document.querySelector(`[data-file-filter]`),rr=document.querySelector(`[data-file-count]`),ir=document.querySelector(`[data-file-none]`);function ar(){let e=(F?.value??``).trim().toLowerCase(),t=0;for(let n of document.querySelectorAll(`[data-view="files"] .prb-file`)){let r=e===``||(n.dataset.search??``).includes(e);n.hidden=!r,r&&(t+=1);let i=n.nextElementSibling;i?.classList.contains(`prb-code`)&&(i.hidden=!r)}for(let t of document.querySelectorAll(`[data-file-group]`)){let n=t.querySelectorAll(`.prb-file:not([hidden])`).length;t.hidden=n===0;let r=t.querySelector(`[data-group-heading]`);if(!r)continue;let i=Number(r.dataset.groupTotal)||0;r.textContent=e&&n!==i?`${r.dataset.groupHeading} · ${n} of ${i}`:`${r.dataset.groupHeading} · ${i}`}ir&&(ir.hidden=t>0),rr&&(rr.textContent=e?`${t} of ${I} file${I===1?``:`s`}`:`${I} file${I===1?``:`s`}`)}var I=document.querySelectorAll(`[data-view="files"] .prb-file`).length;F?.addEventListener(`input`,ar),F?.addEventListener(`keydown`,e=>{e.key===`Escape`&&F.value!==``&&(e.preventDefault(),F.value=``,ar())}),document.addEventListener(`keydown`,e=>{if(e.key!==`Enter`&&e.key!==` `)return;let t=e.target,n=t.closest(`.prb-file[data-file][role="button"]`);!n||n!==t||(e.preventDefault(),Sn(n))});var or=320,sr=()=>Math.round(window.innerWidth/2),cr=e=>Math.round(Math.min(sr(),Math.max(or,e)));function L(e){j&&(e===null?j.style.removeProperty(`--ask-width`):j.style.setProperty(`--ask-width`,`${e}px`))}function R(){return M?Math.round(M.getBoundingClientRect().width):or}function z(e){fetch(S(`/prefs`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({askWidth:e})}).catch(()=>{})}var B=document.querySelector(`[data-ask-resize]`);B?.addEventListener(`pointerdown`,e=>{if(e.button!==0||!j||!M)return;e.preventDefault(),B.setPointerCapture(e.pointerId),j.dataset.resizing=`true`;let t=e.clientX,n=R(),r=e=>{L(cr(n+(t-e.clientX)))},i=()=>{B.removeEventListener(`pointermove`,r),B.removeEventListener(`pointerup`,i),B.removeEventListener(`pointercancel`,i),delete j.dataset.resizing,z(R())};B.addEventListener(`pointermove`,r),B.addEventListener(`pointerup`,i),B.addEventListener(`pointercancel`,i)}),B?.addEventListener(`keydown`,e=>{let t=e.shiftKey?64:16;if(e.key===`ArrowLeft`||e.key===`ArrowRight`){e.preventDefault();let n=e.key===`ArrowLeft`?t:-t,r=cr(R()+n);L(r),z(r);return}(e.key===`Home`||e.key===`Escape`)&&(e.preventDefault(),L(null),z(null))}),B?.addEventListener(`dblclick`,()=>{L(null),z(null)}),window.addEventListener(`resize`,()=>{Zn()&&j?.style.getPropertyValue(`--ask-width`)&&L(cr(R()))});var lr=3e4,V=document.visibilityState===`visible`?Date.now():null,ur=0;function dr(){V!==null&&(ur+=Date.now()-V,V=Date.now())}function fr(){dr();let e=Math.round(ur/1e3);return ur-=e*1e3,e}document.addEventListener(`visibilitychange`,()=>{document.visibilityState===`visible`?V=Date.now():(dr(),V=null)}),setInterval(()=>{let e=fr();e>0&&C({event:`workspace_heartbeat`,visibleSeconds:e})},lr),window.addEventListener(`pagehide`,()=>{let e=S(`/event`),t=JSON.stringify({event:`review_completed`,trailingSeconds:fr()});navigator.sendBeacon?.(e,new Blob([t],{type:`application/json`}))||fetch(e,{method:`POST`,headers:{"content-type":`application/json`},body:t,keepalive:!0}).catch(()=>{})});var pr=document.querySelector(`[data-prompt-bank]`),mr=document.querySelector(`[data-prompt-list]`),H=hr();function hr(){try{let e=JSON.parse(pr?.dataset.prompts??`[]`);return Array.isArray(e)?e:[]}catch{return[]}}function gr(){mr&&(mr.innerHTML=H.map(e=>`<span class="prb-bank-item">
|
|
94
|
+
<button type="button" class="prb-bank-use" data-prompt-use="${T(e.id)}" title="${T(e.prompt)}">${T(e.name)}</button>
|
|
95
|
+
<button type="button" class="prb-bank-edit" data-prompt-edit="${T(e.id)}" aria-label="Edit ${T(e.name)}">✎</button>
|
|
96
|
+
</span>`).join(``),Cr())}async function _r(e){try{let t=await(await fetch(S(`/prompts`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({prompts:e})})).json().catch(()=>null);H=Array.isArray(t?.prompts)?t.prompts:H}catch{}gr()}function vr(e){let t=H.find(t=>t.id===e);!t||!O||(O.value=$e(O.value,t.prompt),$n(),O.focus(),O.setSelectionRange(O.value.length,O.value.length),O.dispatchEvent(new Event(`input`)))}var yr=document.querySelector(`.prb-doc`),br=null,xr=null;function Sr(){E&&(xr?.(),xr=ve(E,{layout:`flat`,actions:Ve.map(e=>({id:e.id,label:e.label})),onChoose:(e,t)=>wr(e,t)}))}function Cr(){yr&&(br?.(),br=ve(yr,{triggerLabel:`Ask Buddy AI`,actions:[...Be.map(e=>({id:e.id,label:e.label})),...H.map(e=>({id:Ke(e.id),label:e.name}))],onChoose:(e,t)=>wr(e,t)}))}function wr(e,t){let n=Tr(e,t);!n||!O||(jn=n,O.value=$e(O.value,n),$n(),O.focus(),O.setSelectionRange(O.value.length,O.value.length),O.dispatchEvent(new Event(`input`)))}function Tr(e,t){let n=qe(e);if(n===null)return We(t,e);let r=H.find(e=>e.id===n);if(!r)return null;let i=Ue(t);return i?`${i}\n\n${r.prompt}`:null}Cr(),Sr(),Ne(document);var U=document.querySelector(`[data-prompt-dialog]`),W=document.querySelector(`[data-prompt-name]`),Er=document.querySelector(`[data-prompt-text]`),Dr=document.querySelector(`[data-prompt-delete]`),Or=document.getElementById(`prb-prompt-title`),G=``;function kr(e){let t=H.find(t=>t.id===e);G=t?.id??``,Or&&(Or.textContent=t?`Edit prompt`:`Save a prompt`),W&&(W.value=t?.name??``),Er&&(Er.value=t?.prompt??``),Dr&&(Dr.hidden=!t),U?.showModal(),W?.focus()}async function Ar(){let e=W?.value.trim()??``,t=Er?.value.trim()??``;if(!e||!t){(e?Er:W)?.focus();return}let n=G?H.map(n=>n.id===G?{...n,name:e,prompt:t}:n):[...H,{id:crypto.randomUUID(),name:e,prompt:t}];U?.close(),await _r(n)}async function jr(){if(!G)return;let e=H.filter(e=>e.id!==G);U?.close(),await _r(e)}document.querySelector(`[data-prompt-cancel]`)?.addEventListener(`click`,()=>U?.close()),Dr?.addEventListener(`click`,()=>void jr()),document.querySelector(`[data-prompt-save]`)?.addEventListener(`click`,()=>void Ar());var K=document.querySelector(`[data-complete]`);K?.addEventListener(`click`,()=>{let e=K.getAttribute(`aria-pressed`)!==`true`;Mr(e),fetch(S(`/state`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({complete:e})}).then(async e=>{let t=await e.json().catch(()=>null);t&&Mr(t.completedAt!==null)}).catch(()=>Mr(!e))});function Mr(e){K&&(K.setAttribute(`aria-pressed`,String(e)),K.textContent=e?`Reviewed`:`Mark review complete`)}var q=document.querySelector(`[data-fresh-region]`),J=document.querySelector(`[data-fresh-check]`),Y=Ir(q?.dataset.report),Nr=`prb-fresh-reopen`,X=Fr(),Pr=q?.dataset.dismissedSha;function Fr(){try{return sessionStorage.getItem(Nr)!==null&&(sessionStorage.removeItem(Nr),!0)}catch{return!1}}X&&(J?.setAttribute(`aria-expanded`,`true`),Z()),J?.addEventListener(`click`,()=>{X=!X,J.setAttribute(`aria-expanded`,String(X)),X?Rr():Z()}),q?.addEventListener(`click`,e=>{let t=e.target;if(t.closest(`[data-fresh-recheck]`))return void Rr();if(t.closest(`[data-fresh-close]`))return X=!1,J?.setAttribute(`aria-expanded`,`false`),Z();let n=t.closest(`[data-fresh-dismiss]`);n&&(Pr=n.dataset.freshDismiss||void 0,X=!1,J?.setAttribute(`aria-expanded`,`false`),Z(),fetch(S(`/state`),{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({dismissFreshnessSha:Pr??null})}).catch(()=>{}))});function Ir(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}var Lr=!1;async function Rr(){if(Lr)return;Lr=!0,zr(!0);let e=Br(Y),t=!1;try{Y=(await(await fetch(S(`/freshness`))).json()).report??null,t=!0}catch{}Lr=!1,Z();let n=t?Br(Y)===e?`No change`:`Updated`:`Could not check`,r=q?.querySelector(`[data-fresh-recheck]`)??J;r&&Hr(r,n,2600)}function zr(e){let t=[...q?.querySelectorAll(`[data-fresh-recheck]`)??[]];for(let n of t)n.disabled=e,e&&(n.textContent=`Checking…`);t.length===0&&J&&e&&(J.textContent=`Checking…`)}function Br(e){if(!e)return`none`;let{checkedAt:t,...n}=e;return JSON.stringify(n)}function Z(){if(q&&(q.innerHTML=ft(Y,{dismissedSha:Pr,open:X,actions:nn!==``}),J&&Y)){let{label:e,state:t}=dt(Y);J.textContent=e,J.dataset.state=t}}document.addEventListener(`click`,e=>{let t=e.target,n=t.closest(`[data-copy-command]`);if(n)return Vr(n);let r=t.closest(`[data-pr-recheck]`);if(r)return void Ur(r);let i=t.closest(`[data-review-update]`);if(i)return void Kr(i);t.closest(`[data-update-close]`)&&document.querySelector(`[data-update-result]`)?.remove()});function Vr(e){let t=e.dataset.copyCommand??``;navigator.clipboard?.writeText(t).then(()=>Hr(e,`Copied`),()=>Hr(e,`Select it`))}function Hr(e,t,n=1400){let r=e.textContent;e.textContent=t,setTimeout(()=>{e.textContent=r},n)}async function Ur(e){let t=[...document.querySelectorAll(`[data-pr-recheck]`)];for(let e of t)e.disabled=!0;let n=Date.now(),r=()=>{let e=Math.max(1,Math.round((Date.now()-n)/1e3));for(let n of t){let t=Wr(n);t?t.innerHTML=`<span class="prb-spinner" aria-hidden="true"></span>Re-checking the conversation, ${e}s. ${Yr}`:n.innerHTML=`<span class="prb-spinner" aria-hidden="true"></span>Checking… ${e}s`}};r();let i=window.setInterval(r,1e3),a=Wr(e)?null:Xr(e);try{await fetch(S(`/refresh`),{method:`POST`})}catch{}finally{window.clearInterval(i),a?.remove()}Wr(e)&&Gr(),window.location.reload()}function Wr(e){return e.closest(`.prb-fresh-notes p`)}function Gr(){try{sessionStorage.setItem(Nr,`1`)}catch{}}async function Kr(e){let t=[...document.querySelectorAll(`[data-review-update]`)];for(let e of t)e.disabled=!0;let n=Date.now(),r=()=>{let e=Math.max(1,Math.round((Date.now()-n)/1e3));for(let n of t)n.innerHTML=`<span class="prb-spinner" aria-hidden="true"></span>Updating… ${e}s`;i&&(i.textContent=qr(e))},i=Jr(e);r();let a=window.setInterval(r,1e3);try{await fetch(S(`/update`),{method:`POST`})}catch{}finally{window.clearInterval(a),i?.remove()}window.location.reload()}function qr(e){return e<5?`Bringing your branch up to date.`:e<25?`Re-reading the pull request conversation.`:`The coding agent is reading the new commits and working out what they did to each finding. This usually takes a few minutes.`}function Jr(e){let t=e.parentElement;if(!t)return null;let n=document.createElement(`span`);return n.className=`prb-recheck-status`,n.setAttribute(`role`,`status`),t.appendChild(n),n}var Yr=`Fetching the latest threads from your pull request. This usually takes under a minute.`;function Xr(e){let t=e.parentElement;if(!t)return null;let n=document.createElement(`span`);return n.className=`prb-recheck-status`,n.setAttribute(`role`,`status`),n.textContent=Yr,t.appendChild(n),n}var Q=document.querySelector(`[data-job-phase]`);function Zr(e){return e===`done`||e===`failed`}var Qr=null,$r=Date.now();function ei(){Qr===null&&(Qr=window.setTimeout(()=>{Qr=null,ti()},bt(Date.now()-$r)))}async function ti(){try{let e=await(await fetch(S(`/job`))).json();if(Zr(e.phase)||e.failed){window.location.reload();return}ni(e.progress)}catch{}ei()}function ni(e){if(!Q||!e)return;let t=Q.querySelector(`.prb-job-progress`);t||(t=document.createElement(`span`),t.className=`prb-job-progress`,Q.querySelector(`p`)?.appendChild(t)),t.textContent=` ${e}`}Q&&!Zr(Q.dataset.jobPhase)&&($r=Date.now(),ei());function ri(e){let t=e.parentElement;if(!t)return;let n=t.querySelector(`.prb-job-retry-status`);n||(n=document.createElement(`p`),n.className=`prb-job-retry-status`,n.setAttribute(`role`,`status`),t.insertBefore(n,e.nextSibling)),n.textContent=`The retry could not be started. You can try again.`}function ii(e){e.parentElement?.querySelector(`.prb-job-retry-status`)?.remove()}document.addEventListener(`click`,e=>{let t=e.target.closest(`[data-job-retry]`);t&&(t.disabled=!0,t.textContent=`Retrying…`,ii(t),fetch(S(`/retry`),{method:`POST`}).then(e=>{if(!e.ok)throw Error(`refused`);$r=Date.now(),ei()}).catch(()=>{t.disabled=!1,t.textContent=`Retry`,ri(t)}))}),window.addEventListener(`popstate`,e=>{fn(e.state??at(window.location.hash)??{kind:`view`,view:`overview`})});var ai=at(window.location.hash);ai?fn(ai):history.replaceState({kind:`view`,view:`overview`},``,window.location.pathname+window.location.search),er(),bn();var $=document.querySelector(`.prb-header [data-menu]`);if($){let t=$.querySelector(`[data-menu-trigger]`),n=$.querySelector(`[data-menu-panel]`),r=()=>{n&&(n.hidden=!0),t?.setAttribute(`aria-expanded`,`false`)};t?.addEventListener(`click`,e=>{if(e.stopPropagation(),!n)return;let r=n.hidden;n.hidden=!r,t.setAttribute(`aria-expanded`,String(r))}),$.addEventListener(`click`,t=>{let n=t.target?.closest(`[data-copy-id]`);n?.dataset.copyId&&(t.stopPropagation(),e(n,n.dataset.copyId))}),document.addEventListener(`click`,e=>{$.contains(e.target)||r()}),document.addEventListener(`keydown`,e=>{e.key===`Escape`&&n&&!n.hidden&&(r(),t?.focus())})}export{Et as t};
|