prreviewbuddy 0.59.50 → 0.63.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/server.js CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as REPOSITORY_SCOPE, $n as presentedKissRunOf, A as reanalyseReview, An as saveJob, Ar as describeAuthorship, At as renderInlineText, B as RUNTIME_WORDS, Bn as followedRefName, Br as readAgentPreference, Bt as removeWorktree, C as track, Cn as followedBranch, Cr as isIssueOutstanding, Ct as authorPreview, D as endRun, Dn as fail, Dr as reviewerDispositions, Dt as CODE_BLOCK_CLASS, E as completeRun, En as endedAt, Er as questionsOutstanding, Et as renderMarkdown, F as recordTelemetryUploadConsent, Fn as purposeOf, Fr as isCommitReview, Ft as MANAGED_ROOT, G as partFiles, Gn as kissDecisionsOf, Gt as compactQueue, H as ARCHITECTURE_DIR, Hn as indexKeptIds, I as telemetryUploadConsent, Ir as git, It as createWorktree, J as storeArchitecture, Jn as lineagePosition, Jt as readIndexToken, K as readArchitecture, Kn as latestKissRun, L as waitingHistory, Lt as holdWorktree, Mn as isLiveJob, Mr as kissOutcome, Mt as extractJsonText, N as readEvents, Nn as phasesFor, Nt as objectWithAnyOf, O as reportRun, On as isTerminal, Or as processDiscussion, Ot as CODE_COPY_CLASS, P as record, Pn as progressSteps, Pt as ReviewBeingDeletedError, Q as QUOTE_LIMITS, Qt as readServerRecord, R as mapRuntimes, Rn as isClaimed, Rr as resolveModel, Rt as isWorktreeHeld, S as isDriving, Sn as checkReview, Sr as doneVerb, St as UNESTABLISHED_MOTIVATION, T as beginRun, Tn as allJobs, Tr as issuesOutstanding, Tt as GITHUB_MARKDOWN, U as checkArchitecture, Un as indexReviewGroups, Ur as STORE_ROOT, Ut as relativeTime$1, V as describeRuntimes, Vn as groupByLineage, Vr as writeAgentPreference, Vt as requestJobStop, W as loadArchitecture, Wn as kissDecisionRefusal, Wr as AGENT_IDS, Wt as activateQueued, X as trackedFiles, Xr as AgentUnavailableError, Xt as clearServerRecordOwnedBy, Y as storedScopes, Yn as loadWorkspace, Yr as AgentCancelledError, Z as ownersOf, Zn as mutateWorkspace, _ as liveUpdateFor, _r as queueAdd, _t as removeNotification, a as wasBlocked, an as writeServerRecord, ar as touchWorkspace, at as subjectOf, bn as fillFileUrlTemplate, br as queueStamp, bt as withUsageRecorded, c as RefreshUnavailableError, cn as feedbackUrl, cr as LIFECYCLES, ct as createPrUpdate, d as mergeUpdateInto, dn as MIN_WORKSPACE_PORT, dr as lifecycleAction, dt as listNotifications, en as serverEntryExists, er as previousKissResult, et as ancestorsOf, f as updateReview, fn as parseWorkspacePort, fr as lifecycleChip, ft as markAllRead, g as UpdateAlreadyRunningError, gn as claimRequestUrl, gr as sectionOf, gt as readNotification, h as askCheckout, hn as writePortPreference, hr as parseLifecycle, ht as pruneNotifications, i as liveJobsFor, it as branchOf, j as runJob, jr as WITHHELD_REASON, jt as asString, k as stopRun, kn as loadJob, kr as recommendationsOf, kt as escapeHtml$1, l as cancelUpdate, ln as DEFAULT_WORKSPACE_PORT, lr as activityLabel, lt as eventName, m as isUnchanged, mn as statedWorkspacePort, mr as offersLifecycle, mt as markReadForReview, n as deleteReview, nn as stopChild, nr as reviewedCommit, nt as writeJsonAtomically, o as discardJob, on as BUILD_VERSION, or as workspaceRevision, ot as createArchitectureNotification, p as refreshPrContext, pn as resolveWorkspacePort, pr as lifecyclePill, pt as markRead, q as repositoryKey, qr as agentFor, qt as settleQueue, r as lineageIds, rt as announceJob, s as FETCH_TIMEOUT_MS, sr as workspaceStamps, st as createPrState, t as deleteLineage, tn as spawnServer, tr as recentWorkspaces, tt as isArchitectureId, u as cancellableHere, un as MAX_WORKSPACE_PORT, ur as isLifecycle, ut as headline, vn as forgeFor, vr as queueAddMany, vt as toneOf, w as RUN_KINDS, wn as reviewedShaOf, wr as isQuestionOutstanding, wt as hasAuthorContent, x as startKissJob, xn as checkCodeFreshness, xr as readQueue, xt as EXPLAIN_SIMPLY_PROMPT, y as agentEnvOf, yn as remoteHost, yr as queueRemove, yt as unreadCount$1, z as recordRuntimeBestEffort, zn as decideKissRecommendation, zr as clearAgentPreference, zt as readMarker } from "./delete_review-TsYWWNVr.js";
1
+ import { $ as storedScopes, $n as loadWorkspace, A as reanalyseReview, An as endedAt, Ar as issuesOutstanding, At as renderMarkdown, Br as isCommitReview, Bt as createWorktree, C as track, Cn as remoteHost, Cr as queueAddMany, Ct as unreadCount$1, D as endRun, Dn as followedBranch, Dr as doneVerb, Dt as authorPreview, E as completeRun, En as checkReview, Er as readQueue, Et as UNESTABLISHED_MOTIVATION, F as record, Fr as describeAuthorship, Ft as asString, G as describeRuntimes, Gn as groupByLineage, Gr as readAgentPreference, Gt as requestJobStop, H as mapRuntimes, Hn as isClaimed, Ht as isWorktreeHeld, In as isLiveJob, Ir as WITHHELD_REASON, It as extractJsonText, J as loadArchitecture, Jn as kissDecisionRefusal, Jr as STORE_ROOT, Jt as activateQueued, K as ARCHITECTURE_DIR, Kn as indexKeptIds, Kr as writeAgentPreference, Ln as phasesFor, Lr as kissOutcome, Lt as objectWithAnyOf, Mn as isTerminal, Mr as reviewerDispositions, Mt as CODE_COPY_CLASS, Nn as loadJob, Nr as processDiscussion, Nt as escapeHtml$1, O as reportRun, On as reviewedShaOf, Or as isIssueOutstanding, Ot as hasAuthorContent, P as readEvents, Pn as saveJob, Pr as recommendationsOf, Pt as renderInlineText, Q as storeArchitecture, Qn as lineagePosition, Qr as agentFor, Qt as readIndexToken, R as recordTelemetryUploadConsent, Rn as progressSteps, Rt as ReviewBeingDeletedError, S as isDriving, Sn as forgeFor, Sr as queueAdd, St as toneOf, T as beginRun, Tn as checkCodeFreshness, Tr as queueStamp, Tt as EXPLAIN_SIMPLY_PROMPT, U as recordRuntimeBestEffort, Un as decideKissRecommendation, Ur as resolveModel, Ut as readMarker, V as waitingHistory, Vr as git, Vt as holdWorktree, W as RUNTIME_WORDS, Wn as followedRefName, Wr as clearAgentPreference, Wt as removeWorktree, X as readArchitecture, Xn as latestKissRun, Y as partFiles, Yn as kissDecisionsOf, Yr as AGENT_IDS, Yt as compactQueue, Z as repositoryKey, Zt as settleQueue, _ as liveUpdateFor, _n as resolveWorkspacePort, _r as lifecycleItemLabel, _t as markRead, a as wasBlocked, an as spawnServer, ar as recentWorkspaces, at as isArchitectureId, bn as claimRequestUrl, br as parseLifecycle, bt as readNotification, c as RefreshUnavailableError, ct as branchOf, d as mergeUpdateInto, dr as workspaceStamps, dt as createPrState, ei as AgentCancelledError, en as clearServerRecordOwnedBy, et as trackedFiles, f as updateReview, fn as feedbackUrl, fr as LIFECYCLES, ft as createPrUpdate, g as UpdateAlreadyRunningError, gn as parseWorkspacePort, gr as lifecycleChip, gt as markAllRead, h as askCheckout, hn as MIN_WORKSPACE_PORT, hr as isLifecycle, ht as listNotifications, i as liveJobsFor, in as serverEntryExists, ir as previousKissResult, it as ancestorsOf, j as runJob, jn as fail, jr as questionsOutstanding, jt as CODE_BLOCK_CLASS, k as stopRun, kn as allJobs, kr as isQuestionOutstanding, kt as GITHUB_MARKDOWN, l as cancelUpdate, ln as writeServerRecord, lr as touchWorkspace, lt as subjectOf, m as isUnchanged, mn as MAX_WORKSPACE_PORT, mr as activityLabel, mt as headline, n as deleteReview, nn as readServerRecord, nt as QUOTE_LIMITS, o as discardJob, on as stopChild, or as reviewedCommit, ot as writeJsonAtomically, p as refreshPrContext, pn as DEFAULT_WORKSPACE_PORT, pr as activityAttributes, pt as eventName, q as checkArchitecture, qn as indexReviewGroups, qt as relativeTime$1, r as lineageIds, rr as presentedKissRunOf, rt as REPOSITORY_SCOPE, s as FETCH_TIMEOUT_MS, st as announceJob, t as deleteLineage, ti as AgentUnavailableError, tr as mutateWorkspace, tt as ownersOf, u as cancellableHere, un as BUILD_VERSION, ur as workspaceRevision, ut as createArchitectureNotification, vn as statedWorkspacePort, vr as lifecyclePill, vt as markReadForReview, w as RUN_KINDS, wn as fillFileUrlTemplate, wr as queueRemove, wt as withUsageRecorded, x as startKissJob, xr as sectionOf, xt as removeNotification, y as agentEnvOf, yn as writePortPreference, yr as offersLifecycle, yt as pruneNotifications, z as telemetryUploadConsent, zn as purposeOf, zt as MANAGED_ROOT } from "./delete_review-CeJo9t7h.js";
2
2
  import { basename, isAbsolute, join, relative, resolve } from "node:path";
3
3
  import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from "node:fs";
4
4
  import { createHash, randomUUID, timingSafeEqual } from "node:crypto";
@@ -248,6 +248,40 @@ var INDEX_SECTIONS = [
248
248
  "done"
249
249
  ];
250
250
  /**
251
+ * Each section's name, as its heading says it, and the key that folds it from the keyboard
252
+ * (⌘K L and this key). The commands are made from this table, so a section added here is a section
253
+ * the keyboard can fold, with no second list to remember.
254
+ */
255
+ var lifecycleName = (id) => LIFECYCLES.find((lifecycle) => lifecycle.id === id).name;
256
+ var INDEX_SECTION_NAMES = {
257
+ pinned: {
258
+ title: "Pinned",
259
+ key: "p"
260
+ },
261
+ active: {
262
+ title: lifecycleName("active"),
263
+ key: "a"
264
+ },
265
+ waiting: {
266
+ title: lifecycleName("waiting"),
267
+ key: "w"
268
+ },
269
+ done: {
270
+ title: lifecycleName("done"),
271
+ key: "d"
272
+ }
273
+ };
274
+ /**
275
+ * Whether a section starts open. The reviewer's choice wins, and otherwise everything is open but
276
+ * Done, which is the archive. The one place that default is written.
277
+ */
278
+ function sectionOpen(section, collapsed) {
279
+ return !(collapsed?.[section] ?? section === "done");
280
+ }
281
+ function isIndexSection(value) {
282
+ return typeof value === "string" && INDEX_SECTIONS.includes(value);
283
+ }
284
+ /**
251
285
  * Which section a card is drawn in: Pinned when pinned, and otherwise where its lifecycle says.
252
286
  *
253
287
  * Pinning controls prominence in the general list and never overrides an ordering the reviewer
@@ -4899,6 +4933,20 @@ function freshnessLabel(report, remote) {
4899
4933
  * carries the same status in two words; this panel exists to say what it means and offer the way
4900
4934
  * out, so it does not repeat the chip's job.
4901
4935
  */
4936
+ /**
4937
+ * Whether Update review is on offer: the rule the panel draws its button by, and the one the
4938
+ * keyboard's ⌘K A U asks, so the shortcut is never on offer where the button would not be.
4939
+ *
4940
+ * Not "is the button on screen". A notice the reviewer dismissed is not drawn, yet the update it
4941
+ * offered is still one click away through the header's status, and still what the code needs.
4942
+ */
4943
+ function offersUpdate(given, options) {
4944
+ if (!options.actions) return false;
4945
+ const report = given ?? (options.remote ? localUnknown(options.remote) : null);
4946
+ if (!report) return false;
4947
+ const remote = report.code.state === "fixed" ? null : options.remote ?? null;
4948
+ return report.code.state === "changed" || remote !== null || report.code.reason === "missing-commit";
4949
+ }
4902
4950
  function renderFreshness(given, options = {}) {
4903
4951
  const report = given ?? (options.remote ? localUnknown(options.remote) : null);
4904
4952
  if (!report) return "";
@@ -4918,7 +4966,7 @@ function renderFreshness(given, options = {}) {
4918
4966
  <span class="prb-fresh-facts">${facts.join(" &middot; ")}</span>
4919
4967
  </div>
4920
4968
  ${status.consequence ? `<p class="prb-fresh-say">${status.consequence}</p>` : ""}
4921
- ${renderActions(report, options, alarming || lost)}
4969
+ ${renderActions(report, options, alarming || lost, offersUpdate(given, options))}
4922
4970
  </div>`;
4923
4971
  }
4924
4972
  /**
@@ -4932,8 +4980,7 @@ function renderFreshness(given, options = {}) {
4932
4980
  * panel now fits in about ninety pixels. A disclosure is secondary by definition, so it belongs
4933
4981
  * with the secondary controls, and a row spent on a summary is a row spent saying nothing.
4934
4982
  */
4935
- function renderActions(report, options, alarming) {
4936
- const offerUpdate = options.actions && alarming;
4983
+ function renderActions(report, options, alarming, offerUpdate) {
4937
4984
  const close = alarming ? "" : `<button type="button" class="prb-fresh-close" data-fresh-close aria-label="Close">\u00d7</button>`;
4938
4985
  return `<div class="prb-fresh-actions">
4939
4986
  ${offerUpdate ? renderUpdateButton() : ""}
@@ -5890,13 +5937,20 @@ function renderIdMenu(view, freshness) {
5890
5937
  canWrite && (freshness || view.remote) ? "<button type=\"button\" class=\"prb-menu-item\" data-fresh-check>Check for updates</button>" : "",
5891
5938
  branchItems ? `<button type="button" class="prb-menu-item" data-fetch-remote hidden>${escapeHtml$1(FETCH_REVIEW_LABEL)}</button>` : "",
5892
5939
  canWrite ? `<button type="button" class="prb-menu-item" data-mark-status="${mark}">${markItemLabel(mark)}</button>` : "",
5893
- ...branchItems ? LIFECYCLES.map(({ id }) => `<button type="button" class="prb-menu-item" data-lifecycle-set="${id}"${offersLifecycle(id, view.lifecycle, view.activity) ? "" : " hidden"}>${escapeHtml$1(lifecycleAction(id))}</button>`) : [],
5940
+ ...branchItems ? LIFECYCLES.map(({ id }) => `<button type="button" class="prb-menu-item" data-lifecycle-set="${id}"${offersLifecycle(id, view.lifecycle, view.activity) ? "" : " hidden"}>${escapeHtml$1(lifecycleItemLabel(id, view.lifecycle, view.activity))}</button>`) : [],
5894
5941
  branchItems ? `<button type="button" class="prb-menu-item" data-queue-action="${view.queued ? "remove" : "add"}">${queueItemLabel(view.queued === true)}</button>` : "",
5895
5942
  canWrite ? `<button type="button" class="prb-menu-item" data-pin-toggle aria-pressed="${view.pinned === true}">${pinItemLabel(view.pinned === true)}</button>` : "",
5896
5943
  `<button type="button" class="prb-menu-item" data-copy-id="${safe}">Copy review ID</button>`,
5897
5944
  canWrite ? `<button type="button" class="prb-menu-item prb-menu-item-danger" data-delete="${safe}">Delete review</button>` : ""
5898
5945
  ].filter(Boolean);
5899
- return `<div class="prb-menu" data-menu data-review-menu${[view.lifecycle ? ` data-lifecycle-state="${view.lifecycle.state}" data-lifecycle-at="${view.lifecycle.at}"` : "", view.activity ? ` data-activity-at="${view.activity.at}" data-activity-kind="${view.activity.kind}"` : ""].join("")}>
5946
+ return `<div class="prb-menu" data-menu data-review-menu${[
5947
+ view.lifecycle ? ` data-lifecycle-state="${view.lifecycle.state}" data-lifecycle-at="${view.lifecycle.at}"` : "",
5948
+ view.activity ? activityAttributes(view.activity) : "",
5949
+ canWrite ? " data-can-write" : "",
5950
+ branchItems ? " data-branch-actions" : "",
5951
+ canWrite && (freshness || view.remote) ? " data-checkable" : "",
5952
+ branchItems && view.queued ? " data-queued" : ""
5953
+ ].join("")}>
5900
5954
  <button type="button" class="prb-menu-trigger" data-menu-trigger aria-expanded="false" aria-haspopup="true" aria-label="Actions for this review">&#8943;</button>
5901
5955
  <div class="prb-menu-panel" data-menu-panel hidden>
5902
5956
  <div data-menu-items>
@@ -8426,15 +8480,20 @@ function reviewActivity(groups, watch = readWatch(), prStates = readPrStates())
8426
8480
  const at = headChanges.get(review.id);
8427
8481
  if (at !== void 0 && at > current.at) current = {
8428
8482
  at,
8429
- kind: "updated"
8483
+ kind: "updated",
8484
+ movedAt: at
8430
8485
  };
8431
8486
  }
8432
8487
  if (latest.prNumber !== void 0) {
8433
8488
  const entry = prStates[requestKey(latest.repoPath, latest.prNumber)];
8434
- if (entry?.changedAt !== void 0 && entry.changedAt > current.at) current = {
8435
- at: entry.changedAt,
8436
- kind: entry.state === "open" ? "reopened" : entry.state
8437
- };
8489
+ if (entry?.changedAt !== void 0 && entry.changedAt > current.at) {
8490
+ const { movedAt } = current;
8491
+ current = {
8492
+ at: entry.changedAt,
8493
+ kind: entry.state === "open" ? "reopened" : entry.state,
8494
+ ...movedAt === void 0 ? {} : { movedAt }
8495
+ };
8496
+ }
8438
8497
  }
8439
8498
  activity.set(latest.id, current);
8440
8499
  }
@@ -8727,7 +8786,7 @@ ${renderWorkspaceRail({
8727
8786
  <p class="prb-index-count" data-count>${escapeHtml$1(countLabel(storedReviews, ordered.length))}</p>
8728
8787
  <button type="button" class="prb-index-select" data-select-mode aria-pressed="false">Select</button>
8729
8788
  </div>`}
8730
- ${INDEX_SECTIONS.map((section) => renderSection(section, sections[section], renderCards)).join("\n ")}
8789
+ ${INDEX_SECTIONS.map((section) => renderSection(section, sections[section], renderCards, sectionOpen(section, view.sectionsCollapsed))).join("\n ")}
8731
8790
  ${ordered.length === 0 ? `<p class="prb-index-empty">No reviews stored yet. Ask Claude Code to review a change and one will appear here.</p>` : `<p class="prb-index-none" data-no-matches hidden>Nothing matches that.</p>`}
8732
8791
  ${ordered.length === 0 ? "" : renderBulkBar()}
8733
8792
  <p class="prb-index-note">Reviews are kept for thirty days, on this machine only. Pinned reviews, Done reviews and anything in your review queue are kept for ninety days instead, counting from the last time you opened or marked them. Every review has a fixed address, so a link to one is worth keeping and still opens after a restart. Stopping the server deletes nothing; it only stops anything being served until the next review starts it again.</p>
@@ -8804,13 +8863,14 @@ function renderLoadMore$1(section) {
8804
8863
  *
8805
8864
  * Every section is headed, Active included. Active used to go without, because the count line
8806
8865
  * directly above it said what it held; with Pinned drawn first, the count line sits over Pinned and
8807
- * would be heading the wrong list. Everything starts open but Done, which is the archive. Rendered
8866
+ * would be heading the wrong list. Open or folded as the reviewer last left it, which `sectionOpen`
8867
+ * decides, and drawn that way by the server so a live reload never flashes the wrong state. Rendered
8808
8868
  * empty and hidden rather than left out, so a card the browser moves here after a mark or a pin has
8809
- * somewhere to go.
8869
+ * somewhere to go, and an empty section keeps its fold for when something arrives.
8810
8870
  */
8811
- function renderSection(section, groups, renderCards) {
8812
- const title = section === "pinned" ? "Pinned" : LIFECYCLES.find((lifecycle) => lifecycle.id === section).name;
8813
- return `<details class="prb-index-section" data-section="${section}"${section !== "done" ? " open" : ""}${groups.length === 0 ? " hidden" : ""}>
8871
+ function renderSection(section, groups, renderCards, open) {
8872
+ const title = INDEX_SECTION_NAMES[section].title;
8873
+ return `<details class="prb-index-section" data-section="${section}"${open ? " open" : ""}${groups.length === 0 ? " hidden" : ""}>
8814
8874
  <summary class="prb-index-section-head">${title} · <span data-section-count>${groups.length}</span></summary>
8815
8875
  <div class="prb-cards" data-cards="${section}">
8816
8876
  ${renderCards(groups)}
@@ -8881,7 +8941,7 @@ function renderCard(group, now, activity, rank, analysis, queued, moved, prState
8881
8941
  const chip = cardLifecycleChip(review.pinned === true, review.lifecycle, activity);
8882
8942
  const href = `/r/${encodeURIComponent(review.id)}?t=${encodeURIComponent(review.token)}`;
8883
8943
  const followed = review.targetType === "commit" ? `commit ${(review.commitSha ?? review.branch).slice(0, 7)}` : followedRefName(review.branch, review.headResolvedRef) ?? review.branch;
8884
- return `<article class="prb-card" data-card data-id="${escapeHtml$1(review.id)}" data-status="${status}" data-pinned="${review.pinned}"${queued === void 0 ? "" : ` data-queue="${queued}"`}${prState === void 0 ? "" : ` data-pr-state="${prState}"`}${review.authorHandle ? ` data-author="${escapeHtml$1(review.authorHandle)}"` : ""} data-lifecycle="${review.lifecycle?.state ?? "active"}"${review.lifecycle ? ` data-lifecycle-at="${review.lifecycle.at}"` : ""} data-activity-at="${activity.at}" data-activity-kind="${activity.kind}" data-rank="${rank}" data-reviews="${group.history.length}" data-lineage="${escapeHtml$1(group.history.map((entry) => entry.id).join(" "))}" data-search-text="${escapeHtml$1(groupSearchText(group))}">
8944
+ return `<article class="prb-card" data-card data-id="${escapeHtml$1(review.id)}" data-status="${status}" data-pinned="${review.pinned}"${queued === void 0 ? "" : ` data-queue="${queued}"`}${prState === void 0 ? "" : ` data-pr-state="${prState}"`}${review.authorHandle ? ` data-author="${escapeHtml$1(review.authorHandle)}"` : ""} data-lifecycle="${review.lifecycle?.state ?? "active"}"${review.lifecycle ? ` data-lifecycle-at="${review.lifecycle.at}"` : ""}${activityAttributes(activity)} data-rank="${rank}" data-reviews="${group.history.length}" data-lineage="${escapeHtml$1(group.history.map((entry) => entry.id).join(" "))}" data-search-text="${escapeHtml$1(groupSearchText(group))}">
8885
8945
  <input type="checkbox" class="prb-card-select" data-select="${escapeHtml$1(review.id)}" aria-label="Select ${escapeHtml$1(followed)}">
8886
8946
  <button type="button" class="prb-card-pin" data-pin="${escapeHtml$1(review.id)}" aria-pressed="${review.pinned}" aria-label="${review.pinned ? "Unpin" : "Pin"} this review">${review.pinned ? "&#9733;" : "&#9734;"}</button>
8887
8947
  ${renderCardMenu(group, followed, queued !== void 0, status, activity)}
@@ -8981,7 +9041,7 @@ function renderMenu(item) {
8981
9041
  const fetchItem = item.fetch ? `<button type="button" class="prb-menu-item" data-fetch-review="${id}" hidden>${escapeHtml$1(FETCH_REVIEW_LABEL)}</button>` : "";
8982
9042
  const markItem = item.mark === void 0 ? "" : `<button type="button" class="prb-menu-item" data-mark-status="${item.mark}" data-mark-id="${id}">${markItemLabel(item.mark)}</button>`;
8983
9043
  const queueItem = item.queue === void 0 ? "" : `<button type="button" class="prb-menu-item" data-queue-action="${item.queue}" data-queue-id="${id}">${queueItemLabel(item.queue === "remove")}</button>`;
8984
- const lifecycleItems = item.lifecycle === void 0 ? "" : LIFECYCLES.map(({ id: target }) => `<button type="button" class="prb-menu-item" data-lifecycle-set="${target}" data-lifecycle-id="${id}"${offersLifecycle(target, item.lifecycle.stored, item.lifecycle.activity) ? "" : " hidden"}>${escapeHtml$1(lifecycleAction(target))}</button>`).join("\n ");
9044
+ const lifecycleItems = item.lifecycle === void 0 ? "" : LIFECYCLES.map(({ id: target }) => `<button type="button" class="prb-menu-item" data-lifecycle-set="${target}" data-lifecycle-id="${id}"${offersLifecycle(target, item.lifecycle.stored, item.lifecycle.activity) ? "" : " hidden"}>${escapeHtml$1(lifecycleItemLabel(target, item.lifecycle.stored, item.lifecycle.activity))}</button>`).join("\n ");
8985
9045
  return `<div class="prb-menu" data-menu>
8986
9046
  <button type="button" class="prb-menu-trigger" data-menu-trigger aria-expanded="false" aria-haspopup="true" aria-label="${escapeHtml$1(item.label)}">&#8943;</button>
8987
9047
  <div class="prb-menu-panel" data-menu-panel hidden>
@@ -9248,13 +9308,14 @@ function readPreferences() {
9248
9308
  try {
9249
9309
  const parsed = JSON.parse(readFileSync(PREFERENCES_PATH, "utf8"));
9250
9310
  if (!parsed || typeof parsed !== "object") return {};
9251
- const { askWidth, dismissedNotices, promptsCollapsed, changeMapRegister, theme } = parsed;
9311
+ const { askWidth, dismissedNotices, promptsCollapsed, changeMapRegister, theme, reviewSections } = parsed;
9252
9312
  return {
9253
9313
  ...typeof askWidth === "number" && Number.isFinite(askWidth) ? { askWidth: clampAskWidth(askWidth) } : {},
9254
9314
  ...Array.isArray(dismissedNotices) ? { dismissedNotices: dismissedNotices.filter((key) => typeof key === "string" && NOTICE_KEY.test(key)) } : {},
9255
9315
  ...typeof promptsCollapsed === "boolean" ? { promptsCollapsed } : {},
9256
9316
  ...changeMapRegister === "simple" || changeMapRegister === "technical" ? { changeMapRegister } : {},
9257
- ...isTheme(theme) ? { theme } : {}
9317
+ ...isTheme(theme) ? { theme } : {},
9318
+ ...readReviewSections(reviewSections)
9258
9319
  };
9259
9320
  } catch {
9260
9321
  return {};
@@ -9291,6 +9352,35 @@ function writeChangeMapRegister(register) {
9291
9352
  }, null, 2)}\n`);
9292
9353
  } catch {}
9293
9354
  }
9355
+ /** Known sections with a boolean only. A hand-edited key we do not draw is dropped on the next write. */
9356
+ function readReviewSections(value) {
9357
+ if (!value || typeof value !== "object") return {};
9358
+ const sections = {};
9359
+ for (const section of INDEX_SECTIONS) {
9360
+ const collapsed = value[section];
9361
+ if (typeof collapsed === "boolean") sections[section] = collapsed;
9362
+ }
9363
+ return Object.keys(sections).length === 0 ? {} : { reviewSections: sections };
9364
+ }
9365
+ /**
9366
+ * Remember whether one Reviews section is folded. Read-modify-write, like every other field here,
9367
+ * and merged one section at a time: the read and the write are one synchronous step, so two
9368
+ * sections toggled at once cannot each write back a copy that lacks the other.
9369
+ */
9370
+ function writeSectionCollapsed(section, collapsed) {
9371
+ try {
9372
+ const current = readPreferences();
9373
+ mkdirSync(STORE_ROOT, { recursive: true });
9374
+ const reviewSections = {
9375
+ ...current.reviewSections,
9376
+ [section]: collapsed
9377
+ };
9378
+ writeFileSync(PREFERENCES_PATH, `${JSON.stringify({
9379
+ ...current,
9380
+ reviewSections
9381
+ }, null, 2)}\n`);
9382
+ } catch {}
9383
+ }
9294
9384
  /** Remember which palette the workspace is drawn in. Read-modify-write, like every other field here. */
9295
9385
  function writeTheme(theme) {
9296
9386
  try {
@@ -9840,6 +9930,17 @@ feature: E</pre>
9840
9930
  </ul>
9841
9931
  <p>Every review shows its own range. The commit count beside the branch name at the top of a
9842
9932
  review opens its split point and the commits it covers.</p>`
9933
+ }, {
9934
+ id: "keyboard",
9935
+ title: "Keyboard",
9936
+ body: `<p>Press <kbd class="prb-kbd">⌘K</kbd> on a Mac, or <kbd class="prb-kbd">Ctrl+K</kbd>
9937
+ elsewhere, to open the command palette. It lists what you can do on the page you are on, and
9938
+ after a key like <kbd class="prb-kbd">M</kbd> it shows the keys that can follow. It stays open
9939
+ until you choose something or press Escape. <kbd class="prb-kbd">⌘K</kbd> then
9940
+ <kbd class="prb-kbd">?</kbd> opens this table from anywhere in the workspace.</p>
9941
+ <p>Single keys, such as <kbd class="prb-kbd">J</kbd> and <kbd class="prb-kbd">K</kbd> on the
9942
+ Reviews list, never act while you are typing in a field.</p>
9943
+ <div data-shortcut-table></div>`
9843
9944
  }];
9844
9945
  function renderHelpPage(view) {
9845
9946
  return `<!doctype html>
@@ -11156,6 +11257,7 @@ async function handle(req, res, options) {
11156
11257
  if (url.pathname === "/notifications/open") return handleNotificationOpen(req, res, url.searchParams, options.indexToken);
11157
11258
  if (url.pathname === "/notifications/recent") return handleRecentNotifications(req, res, url.searchParams, options.indexToken);
11158
11259
  if (url.pathname === "/pin") return handlePin(req, res, options.indexToken);
11260
+ if (url.pathname === "/sections") return handleSections(req, res, options.indexToken);
11159
11261
  if (url.pathname === "/queue") return handleQueue(req, res, options.indexToken);
11160
11262
  if (url.pathname === "/delete") return handleDelete(req, res, options.indexToken);
11161
11263
  if (url.pathname === "/status") return handleStatus(req, res, options.indexToken);
@@ -11272,7 +11374,8 @@ function handleIndex(req, res, params, indexToken) {
11272
11374
  revision: reviewsRevision(states),
11273
11375
  unreadNotifications: unreadCount$1(),
11274
11376
  driving: isDriving(),
11275
- theme: readPreferences().theme
11377
+ theme: readPreferences().theme,
11378
+ sectionsCollapsed: readPreferences().reviewSections
11276
11379
  }), cookie);
11277
11380
  }
11278
11381
  /**
@@ -11750,6 +11853,20 @@ async function handlePin(req, res, indexToken) {
11750
11853
  send(res, 200, { ok: true });
11751
11854
  }
11752
11855
  /**
11856
+ * Folding or opening one section of the list, remembered for the next load.
11857
+ *
11858
+ * The index cookie, like `handlePin`: the list is the only page with these sections. One section
11859
+ * per request, merged into what is stored, so the page never sends a copy of the others.
11860
+ */
11861
+ async function handleSections(req, res, indexToken) {
11862
+ if (req.method !== "POST") return send(res, 405, { error: "Use POST." });
11863
+ if (!indexToken || !secretMatches(indexToken, indexCookie(req))) return send(res, 403, { error: "Not authorised." });
11864
+ const body = await readJson(req);
11865
+ if (!isIndexSection(body?.section) || typeof body?.collapsed !== "boolean") return send(res, 400, { error: "Not a section this page can fold." });
11866
+ writeSectionCollapsed(body.section, body.collapsed);
11867
+ send(res, 200, { ok: true });
11868
+ }
11869
+ /**
11753
11870
  * Adding to and taking out of the working set.
11754
11871
  *
11755
11872
  * The index cookie for the same reason as `handlePin` above: this is the list acting on itself, and
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prreviewbuddy",
3
- "version": "0.59.50",
3
+ "version": "0.63.0",
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",
@@ -0,0 +1 @@
1
+ function e(e,t,n){if(e.length===0)return null;let r=t===null?-1:e.indexOf(t);return r<0?n===1?e[0]:e[e.length-1]:e[Math.min(Math.max(r+n,0),e.length-1)]}function t(e,t){for(let n of e.querySelectorAll(`[data-keyboard-current]`))n!==t&&delete n.dataset.keyboardCurrent;t&&(t.dataset.keyboardCurrent=``)}function n(n){let{doc:r}=n,i=null,a=e=>e?.querySelector(n.link)??null,o=e=>{i=e,t(r,e)},s=()=>i&&n.walk().includes(i)?i:null;r.addEventListener(`focusin`,e=>{let t=(e.target?.closest?.(n.link))?.closest(n.item);t&&o(t)});let c=r.activeElement?.closest?.(n.link)?.closest(n.item);c&&o(c);let l=(e,t)=>{let r=n.background?.()??null;if(t!==`between`&&r){r.scrollTo({top:t===`first`?0:r.scrollHeight}),e.scrollIntoView({block:`nearest`});return}e.scrollIntoView({block:`nearest`}),n.leadIn?.(e)?.scrollIntoView({block:`nearest`})},u=e=>{let t=a(e);return t?.focus({preventScroll:!0}),t};return{move(t){let r=n.walk(),i=e(r,s(),t);!i||!a(i)||(o(i),u(i),l(i,i===r[0]?`first`:i===r[r.length-1]?`last`:`between`))},current:s,enterOpens(){if(n.enterAllowed&&!n.enterAllowed())return!1;let e=s();if(!e||!a(e))return!1;let t=r.activeElement;return t===a(e)||t===null||t===r.body||t===(n.background?.()??null)},open(){u(s())?.click()},openInNewTab(){let e=u(s());e&&(n.openTab??(e=>r.defaultView?.open(e,`_blank`,`noopener`)))(e.href)}}}export{n as t};
@@ -0,0 +1 @@
1
+ function e(e,t){e.addEventListener(`pageshow`,e=>{e.persisted&&t()})}var t=`prbNav`,n=`prb-workspace`,r=`prb-nav-session`,i=`prb-nav-head`,a=`prb-nav-handoff`,o=`prb-nav-places`,s=`unstored`;function c(e){if(!e||typeof e!=`object`)return null;let n=e[t];if(!n||typeof n!=`object`)return null;let{v:r,owner:i,session:a,idx:o,id:s,ui:c}=n;if(r!==1||i!==`prb-workspace`||typeof a!=`string`||a===``||typeof o!=`number`||!Number.isInteger(o)||o<0)return null;let l=c&&typeof c==`object`&&!Array.isArray(c)?c:null;return{v:r,owner:i,session:a,idx:o,...typeof s==`string`&&s!==``?{id:s}:{},ui:l}}function l(e){if(!e||typeof e!=`object`)return{};let{[t]:n,...r}=e;return r}function u(e,t){if(!e||typeof e!=`object`)return!1;let n=e;return n.owner===`prb-workspace`&&n.session===t}function d(e,t){try{return e?.getItem(t)??null}catch{return null}}function f(e,t,n){try{n===null?e?.removeItem(t):e?.setItem(t,n)}catch{}}function p(e){let{history:p,storage:m,location:h}=e,g=e.navigation??null,_=[],v=null,y=null,b=null,x=t=>{b!==null&&e.clearTimeout(b),b=t?t():null,e.capturePending(b!==null)},S=null,C=(()=>{if(!m)return s;let t=d(m,r);if(t)return t;let n=e.uuid();return f(m,r,n),d(m,r)===n?n:s})(),w=()=>`${h.pathname}${h.search}`,T=e=>`${w()}${e}`,E=()=>{try{g?.updateCurrentEntry({state:{owner:n,session:C}})}catch{}},D=()=>{for(let e of _)e()},O=(e,t)=>{t===void 0?p.replaceState(e,``):p.replaceState(e,``,t),E()},ee=()=>Number(d(m,i)??0)||0,k=()=>{try{let e=JSON.parse(d(m,o)??`{}`);return e&&typeof e==`object`&&!Array.isArray(e)?e:{}}catch{return{}}},A=(e,t)=>{if(!e||!m)return;let n=k();delete n[e],n[e]=t;let r=Object.keys(n);for(let e of r.slice(0,Math.max(0,r.length-200)))delete n[e];f(m,o,JSON.stringify(n))},te=e=>{if(!e)return null;let t=e.id?k()[e.id]:void 0;return t&&typeof t==`object`&&!Array.isArray(t)?t:e.ui},j=()=>{if(!v)return null;try{return v()}catch{return null}},M=()=>{let r=c(p.state);if(r&&r.session===C&&r.id){S=r.id,E();return}let o=r?.idx??0;if(!r){let t=d(m,a);f(m,a,null),o=0;try{let n=t?JSON.parse(t):null,r=e.referrer!==``&&new URL(e.referrer).origin===h.origin;n&&r&&n.session===C&&typeof n.idx==`number`&&typeof n.at==`number`&&e.now()-n.at<15e3&&(o=n.idx+1)}catch{o=0}f(m,i,String(o))}let s=r?.id??e.uuid();S=s;let u={v:1,owner:n,session:C,idx:o,id:s,ui:r?.ui??null};O({...l(p.state),[t]:u})},N=()=>c(p.state)??{v:1,owner:`prb-workspace`,session:C,idx:0,ui:null},P=()=>{b!==null&&x(null);let e=j();if(!e||!S)return;let n=JSON.stringify(e),r=c(p.state);if(!r||r.id!==S){A(S,e);return}(n!==y||JSON.stringify(r.ui)!==n)&&(y=n,A(S,e),O({...l(p.state),[t]:{...r,ui:e}}))},F=e=>{if(g){let t=g.currentEntry?.index;if(typeof t!=`number`||t<0)return!1;let n=g.entries()[t+e];if(!n)return!1;try{return u(n.getState(),C)}catch{return!1}}let t=c(p.state);return!t||t.session!==C||p.length<2?!1:e===-1?t.idx>0:t.idx<ee()};M();try{p.scrollRestoration=`manual`}catch{}return{session:C,current(){return{route:l(p.state),ui:te(c(p.state))}},push(r,a){if(r!==``&&!r.startsWith(`#`))throw Error(`Workspace history pushes within this document only; "${r}" is not a fragment.`);if(T(r)===`${w()}${h.hash}`)return!1;P();let o=N().idx+1;f(m,i,String(o));let s=e.uuid(),c={v:1,owner:n,session:C,idx:o,id:s,ui:null};return S=s,p.pushState({...l(a),[t]:c},``,T(r)),y=null,E(),D(),!0},replace(e,n){if(e!==``&&!e.startsWith(`#`))throw Error(`Workspace history replaces within this document only; "${e}" is not a fragment.`);O({...l(n),[t]:N()},T(e))},setCapturer(e){v=e},captureNow:P,scheduleCapture(){x(()=>e.setTimeout(P,250))},leaving(){P(),f(m,a,JSON.stringify({session:C,idx:N().idx,at:e.now()}))},canGoBack:()=>F(-1),canGoForward:()=>F(1),back(){return F(-1)?(P(),p.back(),!0):!1},forward(){return F(1)?(P(),p.forward(),!0):!1},moved(){b!==null&&x(null);let e=j();e&&A(S,e),y=null,S=c(p.state)?.id??null;let t=c(p.state);!t||!t.id||t.session!==C?M():E(),D()},onAvailability(e){_.push(e)}}}function m(e){return e.button===0&&!e.metaKey&&!e.ctrlKey&&!e.shiftKey&&!e.altKey}function h(e){let t=e?.userAgentData?.platform??e?.platform??``;return/mac|iphone|ipad/i.test(t)}function g(e){if(!e||typeof e.closest!=`function`)return!1;let t=e;return t.isContentEditable?!0:t.closest(`input, textarea, select, [contenteditable=""], [contenteditable="true"]`)!==null}function _(e,t,n){if(e.defaultPrevented||e.isComposing)return null;let r=t?e.metaKey:e.ctrlKey,i=t?e.ctrlKey:e.metaKey;if(!r||i||e.altKey||e.shiftKey)return null;let a=e.key===`[`||e.key!==`]`&&e.code===`BracketLeft`?`back`:e.key===`]`||e.code===`BracketRight`?`forward`:null;return!a||g(e.target)||n.querySelector(`dialog[open], [data-menu-panel]:not([hidden])`)?null:a}var v=[`data-id`,`data-finding-card`,`data-goto-section`,`data-view-nav`,`data-file`,`data-line`,`data-history`,`data-history-toggle`,`data-load-more`,`data-select`,`data-pin`,`data-focus-toggle`,`data-ask-toggle`,`data-rail-toggle`,`data-search`,`data-status-filter`,`data-author-filter`,`data-pr-filter`,`data-card`,`data-notification-id`,`data-guide-section`,`data-guide-detail`,`data-view`];function y(e){if(e.id)return{attrs:[[`id`,e.id]]};let t=v.filter(t=>e.hasAttribute(t)).map(t=>[t,e.getAttribute(t)??``]);return t.length>0?{attrs:t}:null}function b(e,t){if(!e||e===t||!t.contains(e))return null;let n=[],r=e;for(;r&&r!==t&&n.length<3;){let t=y(r);t?n.unshift(t):r===e&&n.unshift({tag:r.tagName.toLowerCase(),...r.classList[0]?{cls:r.classList[0]}:{}}),r=r.parentElement}return n.length>0?n:null}function x(e){if(!e||typeof e!=`object`)return!1;let{attrs:t,tag:n,cls:r}=e;return t===void 0?typeof n==`string`&&/^[a-z][a-z0-9-]*$/.test(n)&&(r===void 0||typeof r==`string`):Array.isArray(t)&&t.length>0&&t.every(e=>Array.isArray(e)&&e.length===2&&v.concat(`id`).includes(e[0])&&typeof e[1]==`string`)}function S(e,t){return t.attrs?t.attrs.every(([t,n])=>e.getAttribute(t)===n):e.tagName.toLowerCase()===t.tag&&(t.cls===void 0||e.classList.contains(t.cls))}function C(e,t){let n=t.attrs?`[${t.attrs[0][0]}]`:t.tag;for(let r of e.querySelectorAll(n))if(S(r,t))return r;return null}function w(e,t){if(!Array.isArray(t)||t.length===0||!t.every(x))return null;let n=null,r=e;for(let e of t){let t=C(r,e);if(!t)return n;n=t,r=t}return n}function T(e,t){let n=w(e,t);if(n){if(n.tabIndex<0&&!n.matches(`a[href], button, input, select, textarea, summary`)){n.querySelector(`a[href], button:not([disabled]), input, select, textarea, [tabindex="0"]`)?.focus({preventScroll:!0});return}n.focus({preventScroll:!0})}}function E(e,t){let n=e?.[t];return typeof n==`number`&&Number.isFinite(n)&&n>=0?n:null}function D(e,t){let n=e?.[t];return Array.isArray(n)?n.filter(e=>typeof e==`string`):[]}function O(e){try{return e.sessionStorage}catch{return null}}function ee(e,t){let n=e===`back`?`[`:`]`;return`${e===`back`?`Back`:`Forward`} (${t?`⌘${n}`:`Ctrl+${n}`})`}function k(e,t){if(e.target&&e.target!==`_self`||e.hasAttribute(`download`))return!1;let n;try{n=new URL(e.getAttribute(`href`)??``,t.href)}catch{return!1}return n.origin===t.origin?n.pathname!==t.pathname||n.search!==t.search:!1}function A(e,t){let n=e.querySelector(`[data-nav-announce]`);!n||!t||(n.textContent=``,e.defaultView?.setTimeout(()=>{n.textContent=t},50))}function te(e={},t=window,n=document){let r=t.navigation??null,i=p({history:t.history,navigation:r,storage:O(t),location:t.location,referrer:n.referrer,now:()=>Date.now(),uuid:()=>t.crypto?.randomUUID?.()??`${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`,setTimeout:(e,n)=>t.setTimeout(e,n),clearTimeout:e=>t.clearTimeout(e),capturePending:e=>n.documentElement.toggleAttribute(`data-nav-capture-pending`,e)}),a=h(t.navigator),o=[...n.querySelectorAll(`[data-history]`)],s=()=>{for(let e of o)e.disabled=!((e.dataset.history===`forward`?`forward`:`back`)==`back`?i.canGoBack():i.canGoForward())};for(let e of o){let t=e.dataset.history===`forward`?`forward`:`back`;e.dataset.tip=ee(t,a),e.addEventListener(`click`,()=>{t===`back`?i.back():i.forward()})}s(),i.onAvailability(s),r?.addEventListener?.(`currententrychange`,s),t.addEventListener(`keydown`,e=>{let t=_(e,a,n);t&&(e.preventDefault(),t===`back`?i.back():i.forward())}),t.addEventListener(`popstate`,()=>i.moved()),t.addEventListener(`pagehide`,()=>i.captureNow()),n.addEventListener(`visibilitychange`,()=>{n.visibilityState===`hidden`&&i.captureNow()}),n.addEventListener(`click`,e=>{let n=e.target?.closest?.(`a[href]`);!n||!m(e)||e.defaultPrevented||k(n,t.location)&&i.leaving()},!0),n.addEventListener(`pointerdown`,e=>{(e.button===3||e.button===4)&&i.captureNow()},!0);let c=()=>i.scheduleCapture();for(let e of[`scroll`,`click`,`input`,`toggle`,`focusin`])n.addEventListener(e,c,{capture:!0,passive:!0});if(!e.ownsRestore){let e=n.querySelector(`.prb-shell > main`);i.setCapturer(()=>({main:e?.scrollTop??0,focus:b(n.activeElement,n.body)}));let{ui:t}=i.current(),r=E(t,`main`);e&&r!==null&&(e.scrollTop=r),t&&T(n,t.focus)}return i}var j=[{id:`active`,name:`Active`,action:`Move to active`},{id:`waiting`,name:`Waiting`,action:`Mark waiting`},{id:`done`,name:`Done`,action:`Mark done`}];function M(e){if(typeof e!=`object`||!e)return;let{state:t,at:n}=e;if(!(t!==`waiting`&&t!==`done`||typeof n!=`number`||!Number.isFinite(n)))return{state:t,at:n}}function N(e){return j.find(t=>t.id===e).action}function P(e,t){if(!e)return;let n=I(e,t);return n===void 0?{text:j.find(t=>t.id===e.state).name,changed:!1}:{text:n,changed:!0}}var F=[`created`,`updated`,`merged`,`closed`,`reopened`];function ne(e){return re({at:Number(e.activityAt),kind:e.activityKind,...e.activityMovedAt===void 0?{}:{movedAt:Number(e.activityMovedAt)}})}function re(e){if(typeof e!=`object`||!e)return;let{at:t,kind:n,movedAt:r}=e;if(!(typeof t!=`number`||!Number.isFinite(t)||!F.includes(n)))return{at:t,kind:n,...typeof r==`number`&&Number.isFinite(r)?{movedAt:r}:{}}}function ie(e,t){return!e||e.state===`waiting`&&ae(e,t)?`active`:e.state}function I(e,t){if(!e||!t)return;if(e.state===`waiting`)return ae(e,t)?`Changed while waiting`:void 0;if(t.kind===`reopened`&&t.at>e.at)return`Reopened since done`;let n=t.movedAt??(t.kind===`updated`?t.at:void 0);return n!==void 0&&n>e.at?`Changed since done`:void 0}function ae(e,t){return t!==void 0&&t.kind!==`created`&&t.at>e.at}function oe(e,t,n){return I(t,n)!==void 0||e!==(t?.state??`active`)}function se(e,t,n){return e===`done`&&t?.state===`done`&&I(t,n)!==void 0?`Keep done`:N(e)}var L=[`pinned`,`active`,`waiting`,`done`],ce=e=>j.find(t=>t.id===e).name,le={pinned:{title:`Pinned`,key:`p`},active:{title:ce(`active`),key:`a`},waiting:{title:ce(`waiting`),key:`w`},done:{title:ce(`done`),key:`d`}};function ue(e){return typeof e==`string`&&L.includes(e)}function de(e,t,n,r){return e&&!pe(r)?`pinned`:ie(t,n)}function fe(e,t){let n=e=>L.indexOf(t(e));return[...e].sort((e,t)=>n(e)-n(t))}function pe(e){return e===`queue`}function me(e,t,n){return e?P(t,n)?.text:I(t,n)}var he=[`all`,`queue`,`in-progress`,`complete`],ge=[`any`,`open`,`merged`,`closed`],_e=[`q`,`f`,`by`,`pr`,`page`];function ve(e,t){let n=`${e} review${e===1?``:`s`}`;return e===t?n:`${n} · ${t} branch${t===1?``:`es`}`}function ye(e,t,n){let r={pinned:{shown:[],total:0},active:{shown:[],total:0},waiting:{shown:[],total:0},done:{shown:[],total:0}};for(let i of e){let e=t(i),a=r[e];a.total<n[e]&&a.shown.push(i),a.total+=1}return r}function be(){return{pinned:15,active:15,waiting:15,done:15}}function xe(e){let t=new URLSearchParams(e.replace(/^#/,``)),n=t.get(`f`)??``,r=t.get(`pr`)??``,i=new URLSearchParams;for(let[e,n]of t)!_e.includes(e)&&/^[a-z][a-z0-9_-]*$/i.test(e)&&n!==``&&i.append(e,n);let a=i.toString();return{query:t.get(`q`)??``,filter:he.includes(n)?n:`all`,author:t.get(`by`)??``,pr:ge.includes(r)?r:`any`,...a===``?{}:{extra:a}}}function Se(e){let t=new URLSearchParams;e.query!==``&&t.set(`q`,e.query),e.filter!==`all`&&t.set(`f`,e.filter),e.author!==``&&t.set(`by`,e.author),e.pr!==`any`&&t.set(`pr`,e.pr);for(let[n,r]of new URLSearchParams(e.extra??``))_e.includes(n)||t.append(n,r);let n=t.toString();return n===``?``:`#${n}`}function Ce(e,t){return t===`all`||t===`queue`||e.status===t}function we(e,t){return t===`any`||e.prState===t}function Te(e,t){return t===``||e===t}function Ee(e){return e===`complete`?`Mark reviewed`:`Mark in progress`}function De(e){return e?`Unpin review`:`Pin review`}function Oe(e){return e?`Remove from review queue`:`Add to review queue`}function ke(e,t){let n=t.query.trim().toLowerCase();return Ae(e.filter(e=>(!n||e.searchText.includes(n))&&Ce(e,t.filter)&&Te(e.author,t.author)&&we(e,t.pr)),t.filter)}function Ae(e,t){return pe(t)?e.filter(e=>e.queue!==void 0).sort((e,t)=>(e.queue??0)-(t.queue??0)):e}function je(e){return e===0?`Queue`:`Queue (${e})`}function Me(e){return e===`complete`?`Reviewed`:e===`in-progress`?`In progress`:`New`}function Ne(e,t){if(e===0)return`Nothing selected`;let n=`${e} selected`;return t>0?`${n} · ${t} not shown`:n}function Pe(e){return e===0?`Select all`:`Select all ${e}`}function Fe(e){return e===0?`Delete`:`Delete ${e} review${e===1?``:`s`}`}function Ie(e){return`${Fe(e)}?`}function Le(e,t,n){return e===``||t===``||t===e?`wait`:n?`hold`:`reload`}var R=[{id:`global`,label:`Global`},{id:`reviews`,label:`Reviews list`},{id:`notifications`,label:`Notifications list`},{id:`sections`,label:`Review sections`},{id:`buddy`,label:`Buddy AI`},{id:`actions`,label:`Review actions`},{id:`workspace`,label:`Workspace and focus`}],z=(...e)=>({kind:`chord`,keys:e}),B=(e,t)=>({kind:`key`,key:e,...t?{shift:t}:{}}),Re=L.map(e=>({id:`reviews.section.${e}`,label:`${le[e].title} section`,group:`reviews`,page:`reviews`,binding:z(`l`,le[e].key)})),V=[{id:`palette.open`,label:`Command palette`,group:`global`,page:`global`,binding:{kind:`combo`,key:`k`}},{id:`navigate.reviews`,label:`Go to Reviews`,group:`global`,page:`global`,binding:z(`r`)},{id:`navigate.notifications`,label:`Go to Notifications`,group:`global`,page:`global`,binding:z(`n`)},{id:`help.shortcuts`,label:`Keyboard shortcuts`,group:`global`,page:`global`,binding:z(`?`)},{id:`reviews.search`,label:`Search reviews`,group:`reviews`,page:`reviews`,binding:z(`s`)},{id:`reviews.filters`,label:`Filters`,group:`reviews`,page:`reviews`,binding:z(`f`)},...Re,{id:`reviews.next`,label:`Next review`,group:`reviews`,page:`reviews`,binding:B(`j`)},{id:`reviews.previous`,label:`Previous review`,group:`reviews`,page:`reviews`,binding:B(`k`)},{id:`reviews.open`,label:`Open review`,group:`reviews`,page:`reviews`,binding:B(`Enter`)},{id:`reviews.openInNewTab`,label:`Open review in new tab`,group:`reviews`,page:`reviews`,binding:B(`Enter`,!0)},{id:`notifications.next`,label:`Next notification`,group:`notifications`,page:`notifications`,binding:B(`j`)},{id:`notifications.previous`,label:`Previous notification`,group:`notifications`,page:`notifications`,binding:B(`k`)},{id:`notifications.open`,label:`Open notification`,group:`notifications`,page:`notifications`,binding:B(`Enter`)},{id:`notifications.openInNewTab`,label:`Open notification in new tab`,group:`notifications`,page:`notifications`,binding:B(`Enter`,!0)},{id:`review.section.kiss`,label:`KISS`,group:`sections`,page:`review`,binding:z(`s`,`k`)},{id:`review.section.issues`,label:`Issues`,group:`sections`,page:`review`,binding:z(`s`,`i`)},{id:`review.section.diagrams`,label:`Diagrams`,group:`sections`,page:`review`,binding:z(`s`,`g`)},{id:`review.section.questions`,label:`Questions`,group:`sections`,page:`review`,binding:z(`s`,`q`)},{id:`review.section.files`,label:`Files`,group:`sections`,page:`review`,binding:z(`s`,`f`)},{id:`review.buddy.open`,label:`Open Buddy AI`,group:`buddy`,page:`review`,binding:z(`b`,`o`)},{id:`review.buddy.prompt`,label:`Choose a prompt`,group:`buddy`,page:`review`,binding:z(`b`,`p`)},{id:`review.mark.reviewed`,label:`Mark reviewed`,group:`actions`,page:`review`,binding:z(`m`,`r`),hint:`[data-review-menu] [data-mark-status]`},{id:`review.mark.waiting`,label:`Mark waiting`,group:`actions`,page:`review`,binding:z(`m`,`w`),hint:`[data-review-menu] [data-lifecycle-set="waiting"]`},{id:`review.mark.done`,label:`Mark done`,group:`actions`,page:`review`,binding:z(`m`,`d`),hint:`[data-review-menu] [data-lifecycle-set="done"]`},{id:`review.checkUpdates`,label:`Check for updates`,group:`actions`,page:`review`,binding:z(`a`,`c`),hint:`[data-review-menu] [data-fresh-check]`},{id:`review.update`,label:`Update review`,group:`actions`,page:`review`,binding:z(`a`,`u`)},{id:`review.queue.toggle`,label:`Queue`,group:`actions`,page:`review`,binding:z(`a`,`q`),hint:`[data-review-menu] [data-queue-action]`},{id:`review.delete`,label:`Delete`,group:`actions`,page:`review`,binding:z(`a`,`d`),hint:`[data-review-menu] [data-delete]`},{id:`review.focus.toggle`,label:`Expand or collapse this section`,group:`workspace`,page:`review`,binding:B(`\\`),hint:`[data-focus-toggle]`},{id:`review.focus.exit`,label:`Leave focus mode`,group:`workspace`,page:`review`,binding:B(`Escape`)}],ze=[{page:`review`,keys:[`s`],label:`Sections`},{page:`review`,keys:[`m`],label:`Mark`},{page:`review`,keys:[`a`],label:`Actions`},{page:`review`,keys:[`b`],label:`Buddy AI`},{page:`reviews`,keys:[`l`],label:`List sections`}];function H(e,t=V){return t.filter(t=>t.page===`global`||t.page===e)}function Be(e,t=V){let n={kind:`node`,key:``,label:`Commands`,children:[]},r=(t,r)=>{let i=n;for(let[n,a]of t.entries()){let o=i.children.find(e=>e.key===a);if(o?.kind===`leaf`)throw Error(`Chord ${t.slice(0,n+1).join(` `)} is a command and a namespace on ${e}`);if(o){i=o;continue}let s={kind:`node`,key:a,label:ze.find(r=>(r.page===e||r.page===`global`)&&r.keys.join(` `)===t.slice(0,n+1).join(` `))?.label??r??a.toUpperCase(),children:[]};i.children.push(s),i=s}return i};for(let n of H(e,t)){if(n.binding.kind!==`chord`)continue;let t=n.binding.keys,i=r(t.slice(0,-1)),a=t[t.length-1];if(i.children.some(e=>e.key===a))throw Error(`Chord ${t.join(` `)} is bound twice on ${e}`);i.children.push({kind:`leaf`,key:a,command:n})}return n}function Ve(e){return H(e).filter(e=>e.binding.kind===`key`)}var He=new Set([`Shift`,`Control`,`Alt`,`Meta`,`CapsLock`,`Fn`,`AltGraph`,`OS`]);function Ue(e){return He.has(e.key)}function U(e){let t=e.key;if(t.length===1){if(/^[a-z]$/i.test(t))return t.toLowerCase();let n=/^Key([A-Z])$/.exec(e.code??``);return n&&/\p{L}/u.test(t)?n[1].toLowerCase():t}return null}function W(e,t){let n=t?e.metaKey:e.ctrlKey,r=t?e.ctrlKey:e.metaKey;return!n||r||e.altKey||e.shiftKey||e.isComposing?!1:U(e)===`k`}function We(e,t){return e.kind!==`key`||t.metaKey||t.ctrlKey||t.altKey||t.isComposing||t.shiftKey!==(e.shift===!0)?!1:e.key===`\\`?t.key===`\\`||t.code===`Backslash`:e.key.length===1?U(t)===e.key:t.key===e.key}function Ge(e){let t=null,n=[];return{get at(){return t},get path(){return n},start(){t=e,n=[]},press(e){let r=t?.children.find(t=>t.key===e);return r?r.kind===`leaf`?(t=null,n=[],{kind:`run`,command:r.command}):(t=r,n=[...n,e],{kind:`descend`,node:r}):(t=null,n=[],{kind:`cancel`})},reset(){t=null,n=[]}}}var Ke={Escape:`Esc`,Enter:`Enter`,"\\":`\\`};function G(e){return Ke[e]??(e.length===1?e.toUpperCase():e)}function K(e){return e?`⌘K`:`Ctrl+K`}function q(e,t){return e.kind===`combo`?t?`⌘${G(e.key)}`:`Ctrl+${G(e.key)}`:e.kind===`chord`?[K(t),...e.keys.map(G)].join(` `):e.shift?`Shift+${G(e.key)}`:G(e.key)}function qe(e,t){return e.kind===`chord`?[K(t),...e.keys.map(G)]:[q(e,t)]}function Je(e,t){if(e.kind===`chord`)return null;if(e.kind===`combo`)return`${t?`Meta`:`Control`}+${e.key.toUpperCase()}`;let n=e.key.length===1?e.key.toUpperCase():e.key;return e.shift?`Shift+${n}`:n}function Ye(e){return R.map(t=>({group:t.id,label:t.label,rows:V.filter(e=>e.group===t.id).map(t=>({id:t.id,keys:qe(t.binding,e),label:t.label}))})).filter(e=>e.rows.length>0)}function J(e,t,n,r){let i=e.createElement(t);return n&&(i.className=n),r!==void 0&&(i.textContent=r),i}function Y(e,t){return J(e,`kbd`,`prb-kbd`,t)}function Xe(e,t,n){let r=J(e,`dialog`,`prb-palette`);r.setAttribute(`data-command-palette`,``),r.setAttribute(`aria-labelledby`,`prb-palette-title`);let i=J(e,`div`,`prb-palette-panel`);i.tabIndex=-1,r.append(i),e.body.append(r),r.addEventListener(`click`,e=>{if(e.stopPropagation(),e.target===r)return n();let i=e.target?.closest?.(`[data-palette-key]`);i?.dataset.paletteKey!==void 0&&i.getAttribute(`aria-disabled`)!==`true`&&t(i.dataset.paletteKey)}),r.addEventListener(`cancel`,e=>{e.preventDefault(),n()});let a=(t,n)=>{let r=J(e,`div`,`prb-palette-head`),i=J(e,`span`,`prb-palette-trail`);for(let[n,r]of t.entries())n>0&&i.append(J(e,`span`,`prb-palette-sep`,`›`)),i.append(Y(e,r));let a=J(e,`h2`,`prb-palette-title`,n);return a.id=`prb-palette-title`,r.append(i,a),r};return{dialog:r,show:t=>{i.replaceChildren(a(t.trail,t.title));let n=J(e,`div`,`prb-palette-list`);n.setAttribute(`role`,`group`),n.setAttribute(`aria-labelledby`,`prb-palette-title`);let o=null;for(let r of t.rows){t.groupLabels&&r.group!==o&&(n.append(J(e,`p`,`prb-palette-group`,t.groupLabels[r.group]??r.group)),o=r.group);let i=J(e,`button`,`prb-palette-row`);i.type=`button`,i.dataset.paletteKey=r.key,r.available||i.setAttribute(`aria-disabled`,`true`),r.namespace&&i.setAttribute(`aria-haspopup`,`true`),i.append(Y(e,r.keyLabel),J(e,`span`,`prb-palette-label`,r.namespace?`${r.label}…`:r.label)),r.state&&i.append(J(e,`span`,`prb-palette-state`,r.state)),n.append(i)}if(t.rows.length===0&&n.append(J(e,`p`,`prb-palette-empty`,`Nothing here on this page.`)),i.append(n),t.footer.length>0){let n=J(e,`div`,`prb-palette-footer`);n.append(J(e,`p`,`prb-palette-group`,`Keys on this page`));let r=J(e,`ul`,`prb-palette-keys`);for(let n of t.footer){let t=J(e,`li`);t.append(Y(e,n.keys),J(e,`span`,void 0,n.label)),r.append(t)}n.append(r),i.append(n)}r.open||r.showModal(),i.focus()},showPanel:(t,n,o)=>{i.replaceChildren(a(t,n.title));let s=J(e,`div`,`prb-palette-body`);i.append(s),r.open||r.showModal(),i.dataset.mode=n.title;let c=n.mount(s,o);return()=>{delete i.dataset.mode,c?.()}},close:()=>{r.open&&r.close()},isOpen:()=>r.open}}function Ze(e,t,n){let r=[...e.querySelectorAll(`[data-palette-key]`)];if(r.length===0)return!1;let i=r.indexOf(n),a=t===`ArrowDown`?r[i<0?0:(i+1)%r.length]:t===`ArrowUp`?r[i<0?r.length-1:(i-1+r.length)%r.length]:t===`Home`?r[0]:t===`End`?r[r.length-1]:null;return a?(a.focus(),!0):!1}function Qe(e,t){let n=J(e,`div`,`prb-shortcuts-table`);for(let r of t){let t=J(e,`section`,`prb-shortcuts-group`);t.append(J(e,`h3`,`prb-shortcuts-heading`,r.label));let i=J(e,`dl`,`prb-shortcuts-list`);for(let t of r.rows){let n=J(e,`dt`,`prb-shortcuts-keys`);n.dataset.commandId=t.id;for(let r of t.keys)n.append(Y(e,r));i.append(n,J(e,`dd`,`prb-shortcuts-label`,t.label))}t.append(i),n.append(t)}return n}function $e(e,t,n,r){let i=J(e,`dialog`,`prb-dialog prb-shortcuts`);i.setAttribute(`data-shortcuts-dialog`,``),i.setAttribute(`aria-labelledby`,`prb-shortcuts-title`);let a=J(e,`div`,`prb-shortcuts-head`),o=J(e,`h2`,void 0,`Keyboard shortcuts`);o.id=`prb-shortcuts-title`;let s=J(e,`button`,`prb-shortcuts-close`,`Close`);s.type=`button`,s.setAttribute(`data-shortcuts-close`,``),a.append(o,s),i.append(a,J(e,`p`,`prb-shortcuts-hint`,n),Qe(e,t)),e.body.append(i);let c=null;return s.addEventListener(`click`,()=>i.close()),i.addEventListener(`click`,e=>{e.target===i&&i.close()}),i.addEventListener(`close`,()=>{c?.isConnected&&c.focus(),c=null,r?.()}),{dialog:i,open:()=>{if(i.open)return;let t=e.activeElement;c=t instanceof HTMLElement&&t!==e.body?t:null,i.showModal(),s.focus()},isOpen:()=>i.open}}function et(e){return e.querySelector(`dialog[open], [data-menu-panel]:not([hidden])`)!==null}function tt(e){for(let t of e.children)return t.kind===`leaf`?t.command.group:tt(t);return`global`}function nt(e,t,n={}){let r=n.win??window,i=n.doc??document,a=n.isMac??h(r.navigator),o=Ge(Be(e)),s=null,c=e=>{let t=i.querySelector(`a[href="${e}"]:not([target])`);t?t.click():r.location.assign(e)},l=$e(i,Ye(a),`${K(a)} opens the command palette from anywhere in the workspace. Single keys never act while you are typing.`,()=>n.onSettle?.()),u={"palette.open":{run:()=>C()},"navigate.reviews":{run:()=>c(`/`)},"navigate.notifications":{run:()=>c(`/notifications`)},"help.shortcuts":{run:()=>l.open()}},d=e=>u[e.id]??t[e.id],f=(e,t)=>{let n=d(e);return!!n&&(n.available?.(t)??!0)},p=null,m=[],_=()=>{p?.(),p=null},v=(e=`dismissed`)=>{_(),o.reset(),y.close();let t=s;s=null,t?.isConnected&&t.focus(),e===`dismissed`&&n.onSettle?.()},y=Xe(i,e=>w(e),v),b=Ve(e).map(e=>({keys:q(e.binding,a),label:e.label})),x=Object.fromEntries(R.map(e=>[e.id,e.label])),S=()=>{let e=o.at;if(!e)return;let t=e.children.map(e=>e.kind===`leaf`?{key:e.key,keyLabel:e.key.toUpperCase(),label:e.command.label,namespace:!1,available:f(e.command),group:e.command.group,state:d(e.command)?.state?.()??null}:{key:e.key,keyLabel:e.key.toUpperCase(),label:e.label,namespace:!0,available:!0,group:tt(e)}),n=o.path.length===0?R.flatMap(e=>t.filter(t=>t.group===e.id)):t;y.show({trail:[K(a),...o.path.map(e=>e.toUpperCase())],title:e.label,rows:n,groupLabels:o.path.length===0?x:null,footer:b})};function C(){if(y.isOpen())return v();n.onOpen?.();let e=i.activeElement;s=e instanceof HTMLElement&&e!==i.body?e:null,o.start(),S()}function w(e){let t=o.press(e);if(t.kind===`descend`)return S();let n=t.kind===`run`&&f(t.command)?d(t.command):null;if(n?.panel&&t.kind===`run`)return T(t.command,n.panel);v(n?`running`:`dismissed`),n?.run?.()}function T(e,t){m=e.binding.kind===`chord`?e.binding.keys.slice(0,-1):[];let n=e.binding.kind===`chord`?e.binding.keys.map(e=>e.toUpperCase()):[];p=y.showPanel([K(a),...n],t,()=>v(`running`))}function E(){_(),o.start();for(let e of m)o.press(e);S()}let D=Ve(e);return r.addEventListener(`keydown`,e=>{if(y.isOpen()){if(Ue(e))return;let t=()=>{e.preventDefault(),e.stopPropagation()};if(p)return e.key===`Escape`&&!e.isComposing?(t(),E()):W(e,a)?(t(),v()):void 0;if(e.key===`Escape`||W(e,a))return t(),v();if([`ArrowDown`,`ArrowUp`,`Home`,`End`].includes(e.key)){t(),Ze(y.dialog,e.key,i.activeElement);return}if(e.target?.closest?.(`[data-palette-key]`)&&(e.key===`Enter`||e.key===` `)||e.key===`Tab`||e.metaKey||e.ctrlKey||e.altKey)return;t(),w(U(e)??``);return}if(!(e.defaultPrevented||e.isComposing)){if(W(e,a)){if(i.querySelector(`dialog[open]`))return;e.preventDefault(),e.stopPropagation(),C();return}for(let t of D)if(We(t.binding,e)){if(t.binding.kind===`key`&&t.binding.key!==`Escape`&&(g(e.target)||et(i)))return;if(f(t,e)){e.preventDefault(),d(t).run?.(e);return}}}},!0),r.addEventListener(`pagehide`,()=>{y.isOpen()&&v(`unloading`)}),rt(i,e,a),{isOpen:()=>y.isOpen()||l.isOpen(),close:()=>v()}}function rt(e,t,n){for(let r of H(t)){let t=r.hint;if(t)for(let i of e.querySelectorAll(t))if(r.binding.kind===`chord`)i.dataset.shortcutHint=q(r.binding,n);else{let e=Je(r.binding,n);e&&i.setAttribute(`aria-keyshortcuts`,e)}}}function it(e){return`${e} more`}function at(e){return e===0?`Nothing unread`:`${e} unread`}function ot(e){return e===`restarting`?`Workspace server restarting`:e===`unreachable`?`Workspace server not running`:`Workspace server running`}function X(e,t){let n=e.querySelector(`[data-server-status]`);if(!n)return;n.dataset.serverStatus=t;let r=n.querySelector(`[data-server-status-label]`);r&&(r.textContent=ot(t))}function Z(e,t){let n=e.querySelector(`[data-server-status]`);!n||n.dataset.serverStatus===`restarting`||X(e,t?`running`:`unreachable`)}var st=6e3,ct=5e3;function lt(e=document){let t=e.querySelector(`.prb-toasts`);if(t)return t;let n=e.createElement(`div`);return n.className=`prb-toasts`,n.setAttribute(`role`,`status`),n.setAttribute(`aria-live`,`polite`),e.body.append(n),n}function ut(e,t,n=window){return dt(e,{kind:t.kind,text:t.text},n)}function dt(e,t,n){let r=e.ownerDocument,i=r.createElement(`div`);i.className=`prb-toast`,i.dataset.kind=t.kind;let a=r.createElement(`span`);a.className=`prb-toast-text`,a.textContent=t.text;let o=r.createElement(`a`);o.className=`prb-toast-open`,t.href!==void 0&&t.link!==void 0&&(o.href=t.href,o.textContent=t.link);let s=r.createElement(`button`);for(s.type=`button`,s.className=`prb-toast-close`,s.setAttribute(`aria-label`,`Dismiss: ${t.text}`),s.textContent=`×`,i.append(a,...t.href===void 0?[]:[o],s),e.append(i);e.children.length>3;)e.firstElementChild?.remove();let c=n.setTimeout(()=>i.remove(),st),l=()=>n.clearTimeout(c),u=()=>{n.clearTimeout(c),c=n.setTimeout(()=>i.remove(),st)};return i.addEventListener(`mouseenter`,l),i.addEventListener(`mouseleave`,u),i.addEventListener(`focusin`,l),i.addEventListener(`focusout`,u),s.addEventListener(`click`,()=>{n.clearTimeout(c),i.remove()}),i}function ft(e,t,n=window){return dt(e,{kind:t.tone,text:t.headline,href:`/notifications/open?id=${encodeURIComponent(t.id)}`,link:`Open`},n)}function pt(e,t,n=window){return dt(e,{kind:`more`,text:it(t),href:`/notifications`,link:`View all`},n)}function mt(e=document,t=window){let n=Number(e.body.dataset.notificationsSince);if(!Number.isFinite(n)||n<=0)return;let r=lt(e),i=async()=>{try{let i=await t.fetch(`/notifications/recent?after=${n}`);if(Z(e,!0),i.status===403)return;if(i.ok){let e=await i.json();typeof e.now==`number`&&(n=e.now);for(let n of[...e.notifications??[]].reverse())ft(r,n,t);typeof e.more==`number`&&e.more>0&&pt(r,e.more,t)}}catch{Z(e,!1)}t.setTimeout(()=>void i(),ct)};t.setTimeout(()=>void i(),ct)}function ht(e,t){if(typeof t==`number`)for(let n of e.querySelectorAll(`[data-unread-count]`))n.dataset.unreadStyle===`rail`&&(n.textContent=t===0?``:at(t)),n.hidden=t===0}function gt(e,t){ht(e,t.unread),typeof t.driving==`boolean`&&_t(e,t.driving)}function _t(e,t){let n=e.querySelector(`[data-restart]`),r=e.querySelector(`[data-restart-note]`);n&&(n.disabled=t),r&&(r.hidden=!t)}var vt=`prb-server-restarted`;function yt(e=document,t=window){let n=null;try{n=t.sessionStorage.getItem(vt),t.sessionStorage.removeItem(vt)}catch{}n!==null&&ut(lt(e),{kind:`ready`,text:`Server restarted. Workspace is back online.`},t)}var bt=2e4,Q=300;function xt(e){yt();let t=document.querySelector(`[data-restart]`),n=document.querySelector(`[data-restart-note]`);t&&t.addEventListener(`click`,()=>{t.disabled=!0,St(e,t,n)})}async function St(e,t,n){let r,i=null;try{let a=await fetch(e,{method:`POST`});if(a.status===409){_t(document,!0);return}if(!a.ok)return void $(t,n,await At(a));let o=await a.json();r=typeof o.startedAt==`number`?o.startedAt:null,i=Ot(window.location.href,o.port)}catch{$(t,n,`The workspace server could not be reached.`);return}if(document.body.dataset.restarting=`true`,X(document,`restarting`),i!==null){if(await Et(Number(new URL(i).port)))return void window.location.assign(i)}else if(await Ct(r)){try{window.sessionStorage.setItem(vt,`1`)}catch{}window.location.reload();return}if(delete document.body.dataset.restarting,await kt()){X(document,`running`),$(t,n,`The server did not restart, and is still the one that was running.`);return}X(document,`unreachable`),$(t,n,`Server restart failed. Run prreviewbuddy open to start the workspace again.`)}async function Ct(e){let t=Date.now()+bt;for(;Date.now()<t;){await new Promise(e=>setTimeout(e,Q));try{let t=await fetch(`/health`,{cache:`no-store`});if(!t.ok)continue;let n=await t.json();if(typeof n.startedAt==`number`&&n.startedAt!==e)return!0}catch{}}return!1}var wt=4,Tt={now:()=>Date.now(),sleep:e=>new Promise(t=>setTimeout(t,e))};async function Et(e,t=()=>Dt(e),n=Tt){let r=n.now()+bt,i=0;for(;n.now()<r;){await n.sleep(Q);let e=await t();if(e===`moved`||(i=e===`gone`?i+1:0,i>=wt))return!0}for(let e=0;e<wt;e+=1){let e=await t();if(e!==`gone`)return e===`moved`;await n.sleep(Q)}return!0}async function Dt(e){try{let t=await fetch(`/health`,{cache:`no-store`});return t.ok&&(await t.json()).movedTo===e?`moved`:`here`}catch{return`gone`}}function Ot(e,t){if(typeof t!=`number`||!Number.isInteger(t))return null;let n=new URL(e);return t===(n.port===``?n.protocol===`https:`?443:80:Number(n.port))?null:(n.port=String(t),n.href)}async function kt(){try{return(await fetch(`/health`,{cache:`no-store`})).ok}catch{return!1}}async function At(e){try{return(await e.json()).error??`The server could not be restarted.`}catch{return`The server could not be restarted.`}}function $(e,t,n){e.disabled=!1,t&&(t.textContent=n,t.hidden=!1)}export{ye as A,A as B,ue as C,Oe as D,De as E,se as F,E as G,b as H,P as I,D as J,T as K,oe as L,Ne as M,Me as N,je as O,ne as P,re as R,be as S,xe as T,h as U,te as V,m as W,e as Y,Ie as _,mt as a,fe as b,X as c,Qe as d,Ye as f,Fe as g,ve as h,ut as i,Pe as j,Le as k,at as l,me as m,gt as n,lt as o,L as p,l as q,ht as r,Z as s,xt as t,nt as u,ke as v,Ee as w,de as x,Se as y,M as z};
package/static/help.js CHANGED
@@ -1 +1 @@
1
- import{d as e,t,v as n}from"./chunk-CyYZeRiG.js";e(),t(`/restart`),n(window,()=>window.location.reload());
1
+ import{U as e,V as t,Y as n,d as r,f as i,t as a,u as o}from"./chunk-CxNfDBSA.js";t(),o(`global`,{}),document.querySelector(`[data-shortcut-table]`)?.replaceChildren(r(document,i(e(navigator)))),a(`/restart`),n(window,()=>window.location.reload());
@@ -1 +1 @@
1
- import{d as e,l as t,r as n,t as r,v as i}from"./chunk-CyYZeRiG.js";function a(e,t,n){let r=[...e.querySelectorAll(`[data-notification-id]`)];r.forEach((e,t)=>{e.hidden=t>=n}),t&&(t.hidden=r.length<=n)}function o(e){let t=e.querySelector(`[data-notifications-more]`),n=15;a(e,t,n),t?.addEventListener(`click`,()=>{n+=15,a(e,t,n)})}e(),r(`/restart`),o(document);var s=document.querySelector(`[data-notifications-count]`),c=document.querySelector(`[data-notifications-read-all]`);async function l(){try{let e=await fetch(`/notifications`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({action:`read-all`})});if(!e.ok)return null;let t=await e.json();return typeof t.unread==`number`?t.unread:null}catch{return null}}function u(e){e.setAttribute(`data-read`,`true`);let t=e.querySelector(`.prb-notification-open`),n=t?.getAttribute(`aria-label`);t&&n?.startsWith(`Unread. `)&&t.setAttribute(`aria-label`,n.slice(8))}c?.addEventListener(`click`,()=>{c.disabled=!0,l().then(e=>{if(e===null){c.disabled=!1;return}document.querySelectorAll(`[data-notification-id]`).forEach(u),s&&(s.textContent=t(e)),n(document,e),c.disabled=e===0})}),i(window,()=>window.location.reload());
1
+ import{V as e,Y as t,l as n,r,t as i,u as a}from"./chunk-CxNfDBSA.js";import{t as o}from"./chunk-BadSI8AL.js";function s(e,t,n){let r=[...e.querySelectorAll(`[data-notification-id]`)];r.forEach((e,t)=>{e.hidden=t>=n}),t&&(t.hidden=r.length<=n)}function c(e){let t=e.querySelector(`[data-notifications-more]`),n=15;s(e,t,n),t?.addEventListener(`click`,()=>{n+=15,s(e,t,n)})}e(),i(`/restart`),c(document);var l=o({doc:document,item:`[data-notification-id]`,link:`a.prb-notification-open`,walk:()=>[...document.querySelectorAll(`[data-notification-id]:not([hidden])`)].filter(e=>e.querySelector(`a.prb-notification-open`)),background:()=>document.querySelector(`.prb-shell > main`)});a(`notifications`,{"notifications.next":{run:()=>l.move(1)},"notifications.previous":{run:()=>l.move(-1)},"notifications.open":{available:()=>l.enterOpens(),run:()=>l.open()},"notifications.openInNewTab":{available:()=>l.enterOpens(),run:()=>l.openInNewTab()}});var u=document.querySelector(`[data-notifications-count]`),d=document.querySelector(`[data-notifications-read-all]`);async function f(){try{let e=await fetch(`/notifications`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({action:`read-all`})});if(!e.ok)return null;let t=await e.json();return typeof t.unread==`number`?t.unread:null}catch{return null}}function p(e){e.setAttribute(`data-read`,`true`);let t=e.querySelector(`.prb-notification-open`),n=t?.getAttribute(`aria-label`);t&&n?.startsWith(`Unread. `)&&t.setAttribute(`aria-label`,n.slice(8))}d?.addEventListener(`click`,()=>{d.disabled=!0,f().then(e=>{if(e===null){d.disabled=!1;return}document.querySelectorAll(`[data-notification-id]`).forEach(p),u&&(u.textContent=n(e)),r(document,e),d.disabled=e===0})}),t(window,()=>window.location.reload());
package/static/reviews.js CHANGED
@@ -1 +1 @@
1
- import{_ as e,a as t,d as n,f as r,h as i,i as a,m as o,n as s,o as c,s as ee,t as te,v as ne}from"./chunk-CyYZeRiG.js";import{a as re,i as ie,n as ae,o as oe,r as se,s as ce,t as le}from"./chunk-CndkgJPh.js";import{C as ue,S as de,_ as fe,a as pe,b as me,c as he,d as ge,f as _e,g as ve,h as ye,i as be,l as xe,m as Se,n as Ce,o as we,r as Te,s as Ee,t as l,u,v as De,y as Oe}from"./chunk-Cj8lEKkl.js";function ke(e,t){t.forEach((t,n)=>{e.children[n]!==t&&e.insertBefore(t,e.children[n]??null)})}async function Ae(e,t,n){if(e.disabled)return;let r=e.getAttribute(`aria-pressed`)!==`true`;je(e,r),e.disabled=!0;let i=await t(r).catch(()=>!1);if(e.disabled=!1,!i)return je(e,!r);n(r)}function je(e,t){e.setAttribute(`aria-pressed`,String(t)),e.innerHTML=t?`&#9733;`:`&#9734;`,e.setAttribute(`aria-label`,`${t?`Unpin`:`Pin`} this review`)}function Me(e,t){let n=e.parentElement?.querySelector(`[data-history-list]`);n&&(n.hidden=!t,e.setAttribute(`aria-expanded`,String(t)))}function Ne(e,t,n,i){return{limits:n,expanded:t.filter(e=>e.querySelector(`[data-history-list]:not([hidden])`)).map(e=>e.dataset.id??``).filter(e=>e!==``),main:i?.scrollTop??0,focus:r(e.activeElement,e.body)}}function Pe(e,t){let n=e?.limits;if(!n||typeof n!=`object`)return t;let r={...t};for(let e of l){let t=n[e];typeof t==`number`&&Number.isInteger(t)&&t>r[e]&&(r[e]=t)}return r}function Fe(t,n,r){if(!n)return;r.reveal(Pe(n,r.limits));let a=new Set(e(n,`expanded`));for(let e of r.cards){let t=e.querySelector(`[data-history-toggle]`);t&&a.has(e.dataset.id??``)&&Me(t,!0)}let s=o(n,`main`);r.pane&&s!==null&&(r.pane.scrollTop=s),i(t,n.focus)}var d=n({ownsRestore:!0});te(`/restart`);var f=[...document.querySelectorAll(`[data-card]`)].sort((e,t)=>Number(e.dataset.rank)-Number(t.dataset.rank)),Ie=Object.fromEntries(l.map(e=>[e,document.querySelector(`[data-cards="${e}"]`)])),p=document.querySelector(`.prb-index`);function Le(e){return{id:e.dataset.id??``,queue:e.dataset.queue===void 0?void 0:Number(e.dataset.queue),status:e.dataset.status??`new`,prState:e.dataset.prState}}var m=document.querySelector(`[data-search]`),h=document.querySelector(`[data-status-filter]`),g=document.querySelector(`[data-author-filter]`),_=document.querySelector(`[data-pr-filter]`),v=document.querySelector(`[data-no-matches]`),Re=document.querySelector(`[data-count]`),y=u();function ze(e){return{stored:ue({state:e.dataset.lifecycle,at:Number(e.dataset.lifecycleAt)}),activity:{at:Number(e.dataset.activityAt??0),kind:e.dataset.activityKind??`created`}}}function Be(e){return e.dataset.pinned===`true`}function b(e){let{stored:t,activity:n}=ze(e);return xe(Be(e),t,n,E.filter)}var x=document.querySelector(`[data-bulk]`),Ve=document.querySelector(`[data-bulk-count]`),He=document.querySelector(`[data-bulk-delete]`),Ue=document.querySelector(`[data-bulk-question]`),S=document.querySelector(`[data-bulk-confirm]`),C=document.querySelector(`[data-bulk-actions]`),w=document.querySelector(`[data-bulk-error]`),T=document.querySelector(`[data-bulk-select-all]`),E=_e(window.location.hash),D=new Set,O=!1,k=document.querySelector(`[data-bulk-fetch]`),A={},j=[],M=!1;function N(){let e=E.query.trim().toLowerCase();E.author!==``&&![...g?.options??[]].some(e=>e.value===E.author)&&(E.author=``);let t=he(we(f.map(e=>({...Le(e),searchText:e.dataset.searchText??``,author:e.dataset.author,card:e})),{...E,query:e}).map(e=>e.card),b);j=t;let n=fe(t,b,y),r=new Set(l.flatMap(e=>n[e].shown));for(let e of f)e.hidden=!r.has(e);for(let e of l){let t=Ie[e];t&&ke(t,n[e].shown);let r=document.querySelector(`[data-load-more="${e}"]`);r&&(r.hidden=n[e].total<=n[e].shown.length);let i=document.querySelector(`[data-section="${e}"]`);i&&(i.hidden=n[e].total===0);let a=i?.querySelector(`[data-section-count]`);a&&(a.textContent=String(n[e].total))}if(m&&m.value!==E.query&&(m.value=E.query),g&&(g.value=E.author,E.author===``?delete g.dataset.active:g.dataset.active=``),_||(E.pr=`any`),_&&(_.value=E.pr,E.pr===`any`?delete _.dataset.active:_.dataset.active=``),h&&(h.value=E.filter,E.filter===`all`?delete h.dataset.active:h.dataset.active=``),Re){let e=t.reduce((e,t)=>e+Number(t.dataset.reviews??1),0);Re.textContent=Te(e,t.length)}v&&(v.hidden=t.length>0||f.length===0),Xe(t)}var We=300,P=null;function F(){P!==null&&window.clearTimeout(P),P=null,d.replace(Ee(E),{})}function I(e,t){if(E={...E,...e},y=u(),N(),t===`now`)return F();P!==null&&window.clearTimeout(P),P=window.setTimeout(F,We)}window.addEventListener(`pagehide`,()=>{P!==null&&F()}),document.addEventListener(`click`,e=>{P!==null&&e.target?.closest?.(`a[href]`)&&F()},!0),m?.addEventListener(`input`,()=>I({query:m.value},`settled`)),m?.addEventListener(`keydown`,e=>{e.key===`Escape`&&m.value!==``&&(e.preventDefault(),I({query:``},`now`))}),h?.addEventListener(`change`,()=>{I({filter:h.value},`now`)}),g?.addEventListener(`change`,()=>{I({author:g.value},`now`)}),_?.addEventListener(`change`,()=>{I({pr:_.value},`now`)}),document.addEventListener(`click`,e=>{let t=e.target.closest(`[data-load-more]`)?.dataset.loadMore;!t||!l.includes(t)||(y={...y,[t]:y[t]+15},N())});for(let e of[`popstate`,`hashchange`])window.addEventListener(e,()=>{E=_e(window.location.hash),y=u(),N(),qe()});document.addEventListener(`click`,e=>{let t=e.target.closest(`[data-pin]`);if(!t?.dataset.pin)return;e.preventDefault(),e.stopPropagation();let n=t.dataset.pin;Ae(t,e=>fetch(`/pin`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({id:n,pinned:e})}).then(e=>e.ok),e=>{let n=t.closest(`[data-card]`);n&&(n.dataset.pinned=String(e),q(n),N())})});async function Ge(e,t){let n;try{let r=await fetch(`/queue`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({id:e,action:t})});if(!r.ok)return;n=(await r.json()).queue}catch{return}L(n),N()}function L(e){let t=new Map(e.map((e,t)=>[e,t]));for(let e of f){let n=t.get(e.dataset.id??``);n===void 0?delete e.dataset.queue:e.dataset.queue=String(n),n!==void 0&&e.dataset.lifecycle!==`active`&&(e.dataset.lifecycle=`active`,delete e.dataset.lifecycleAt,q(e))}for(let e of document.querySelectorAll(`[data-queue-action][data-queue-id]`)){let n=t.has(e.dataset.queueId??``);e.dataset.queueAction=n?`remove`:`add`,e.textContent=Se(n)}let n=document.querySelector(`[data-queue-option]`);n&&(n.textContent=ye(e.length))}document.addEventListener(`click`,e=>{let t=e.target.closest(`[data-history-toggle]`);if(!t)return;e.preventDefault(),e.stopPropagation();let n=t.parentElement?.querySelector(`[data-history-list]`);n&&Me(t,n.hidden!==!1)});var Ke=document.querySelector(`.prb-shell > main`);function qe(){Fe(document,d.current().ui,{cards:f,pane:Ke,limits:y,reveal:e=>{y=e,N()}})}d.setCapturer(()=>Ne(document,f,y,Ke)),N(),qe();function R(e){for(let t of document.querySelectorAll(`[data-menu]`)){if(t===e)continue;let n=t.querySelector(`[data-menu-panel]`),r=t.querySelector(`[data-menu-trigger]`);n&&(n.hidden=!0),r?.setAttribute(`aria-expanded`,`false`),z(t)}}function z(e){let t=e.querySelector(`[data-menu-items]`),n=e.querySelector(`[data-menu-confirm]`);t&&(t.hidden=!1),n&&(n.hidden=!0),e.querySelector(`[data-menu-error]`)?.remove(),e.querySelector(`[data-id-field]`)?.remove()}document.addEventListener(`keydown`,e=>{e.key===`Escape`&&R()}),document.addEventListener(`click`,e=>{let t=e.target,n=t.closest(`[data-menu]`);if(!n)return void R();let r=t.closest(`[data-menu-trigger]`);if(r){e.preventDefault(),e.stopPropagation();let t=n.querySelector(`[data-menu-panel]`);if(!t)return;let i=t.hidden;R(n),z(n),t.hidden=!i,r.setAttribute(`aria-expanded`,String(i));return}let i=t.closest(`[data-copy-id]`);if(i?.dataset.copyId){e.preventDefault(),e.stopPropagation(),ce(i,i.dataset.copyId);return}let a=t.closest(`[data-fetch-review]`);if(a?.dataset.fetchReview){e.preventDefault(),e.stopPropagation(),R();let t=a.closest(`[data-card]`);t&&ct([t]);return}let o=t.closest(`[data-mark-status]`);if(o?.dataset.markId){e.preventDefault(),e.stopPropagation(),R(),tt(o.dataset.markId,o.dataset.markStatus===`complete`);return}let s=t.closest(`[data-lifecycle-set]`);if(s?.dataset.lifecycleId){e.preventDefault(),e.stopPropagation(),R(),K([s.dataset.lifecycleId],s.dataset.lifecycleSet);return}let c=t.closest(`[data-queue-action]`);if(c?.dataset.queueId){e.preventDefault(),e.stopPropagation(),R(),Ge(c.dataset.queueId,c.dataset.queueAction===`remove`?`remove`:`add`);return}if(t.closest(`[data-delete]`)){e.preventDefault(),e.stopPropagation();let t=n.querySelector(`[data-menu-items]`),r=n.querySelector(`[data-menu-confirm]`);t&&(t.hidden=!0),r&&(r.hidden=!1);return}if(t.closest(`[data-cancel-delete]`)){e.preventDefault(),e.stopPropagation(),z(n);return}if(t.closest(`[data-confirm-delete]`)){e.preventDefault(),e.stopPropagation(),Je(n);return}e.preventDefault(),e.stopPropagation()});async function Je(e){let t=e.querySelector(`[data-delete]`),n=t?.dataset.delete;if(!n)return;let r=e.querySelector(`[data-menu-confirm]`),i=e.querySelector(`[data-confirm-delete]`);i&&(i.disabled=!0,i.textContent=`Deleting`);try{let r=await fetch(`/delete`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({id:n,scope:t?.dataset.scope??`review`})});if(r.ok)return void window.location.reload();Ye(e,(await r.json().catch(()=>null))?.error??`That could not be deleted.`)}catch{Ye(e,`The workspace server did not answer. It may have stopped.`)}i&&(i.disabled=!1,i.textContent=`Delete`),r&&(r.hidden=!0);let a=e.querySelector(`[data-menu-items]`);a&&(a.hidden=!1)}function Ye(e,t){e.querySelector(`[data-menu-error]`)?.remove();let n=document.createElement(`p`);n.className=`prb-menu-error`,n.setAttribute(`data-menu-error`,``),n.textContent=t,e.querySelector(`[data-menu-panel]`)?.append(n)}function B(e){O=e,e||D.clear(),p&&(e?p.dataset.selecting=``:delete p.dataset.selecting),document.querySelector(`[data-select-mode]`)?.setAttribute(`aria-pressed`,String(e));for(let t of document.querySelectorAll(`.prb-card-link`))e?t.setAttribute(`aria-disabled`,`true`):t.removeAttribute(`aria-disabled`);V(),N()}function V(){S&&(S.hidden=!0),C&&(C.hidden=!1),w&&(w.hidden=!0,w.textContent=``)}function Xe(e){for(let e of f){let t=D.has(e.dataset.id??``),n=e.querySelector(`[data-select]`);n&&(n.checked=t),t?e.dataset.selected=``:delete e.dataset.selected}if(!x||(x.hidden=!O,!O))return;let t=new Set(e.filter(Ze).map(e=>e.dataset.id)),n=[...D].filter(e=>!t.has(e)).length;Ve&&(Ve.textContent=Oe(D.size,n)),T&&(T.textContent=De(e.length),T.disabled=e.every(e=>D.has(e.dataset.id??``))),He&&(He.textContent=be(Qe()));for(let e of x.querySelectorAll(`[data-bulk-mark], [data-bulk-lifecycle], [data-bulk-queue], [data-bulk-delete]`))e.disabled=D.size===0;k&&(k.hidden=!ae(A,Y(U())))}function Ze(e){return!e.hidden&&e.closest(`details`)?.open!==!1}for(let e of document.querySelectorAll(`details[data-section]`))e.addEventListener(`toggle`,()=>Xe(j));document.querySelector(`[data-select-mode]`)?.addEventListener(`click`,()=>{B(!O)}),T?.addEventListener(`click`,()=>{for(let e of j)e.dataset.id&&D.add(e.dataset.id);V(),N()});function H(e){D.has(e)?D.delete(e):D.add(e),V(),N()}document.addEventListener(`change`,e=>{let t=e.target.closest(`[data-select]`);t?.dataset.select&&H(t.dataset.select)}),document.addEventListener(`click`,e=>{if(!O)return;let t=e.target,n=t.closest(`[data-card]`);n?.dataset.id&&(t.closest(`[data-select], [data-pin], [data-menu], [data-history-toggle]`)||(e.preventDefault(),H(n.dataset.id)))}),document.addEventListener(`keydown`,e=>{if(!O||e.key!==`Enter`)return;let t=e.target.closest(`.prb-card-link`)?.closest(`[data-card]`);t?.dataset.id&&(e.preventDefault(),H(t.dataset.id))});function U(){return he(f.filter(e=>D.has(e.dataset.id??``)),b)}function Qe(){return U().reduce((e,t)=>e+Number(t.dataset.reviews??1),0)}function W(e){w&&(w.textContent=e,w.hidden=!1)}function G(e){for(let t of x?.querySelectorAll(`button`)??[])t.disabled=e}async function $e(e){let t=[...D];if(t.length!==0){G(!0);try{if(!(await fetch(`/status`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({ids:t,complete:e})})).ok)return G(!1),W(`That could not be saved. The workspace server refused it.`)}catch{return G(!1),W(`The workspace server did not answer. It may have stopped.`)}et(U(),e),G(!1),B(!1)}}function et(e,t){let n=t?`complete`:`in-progress`,r=t?`in-progress`:`complete`;for(let t of e){t.dataset.status=n;let e=t.querySelector(`.prb-card-status`);e&&(e.dataset.status=n,e.textContent=me(n));let i=t.querySelector(`[data-mark-status]`);i&&(i.dataset.markStatus=r,i.textContent=ge(r))}}async function tt(e,t){try{if(!(await fetch(`/status`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({ids:[e],complete:t})})).ok)return}catch{return}et(f.filter(t=>t.dataset.id===e),t),N()}async function K(e,t){let n;try{let r=await fetch(`/lifecycle`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({ids:e,state:t})});n=r.ok?await r.json().catch(()=>null):null}catch{n=null}if(!n)return!1;let r=new Set(e);for(let e of f)r.has(e.dataset.id??``)&&(e.dataset.lifecycle=t,t===`active`?delete e.dataset.lifecycleAt:e.dataset.lifecycleAt=String(n.at),q(e));return L(n.queue),N(),!0}function q(e){let{stored:t,activity:n}=ze(e),r=e.querySelector(`[data-lifecycle-chip]`);if(r){let i=Ce(Be(e),t,n);r.textContent=i??``,r.hidden=i===void 0}for(let r of e.querySelectorAll(`[data-lifecycle-set]`))r.hidden=!de(r.dataset.lifecycleSet,t,n)}async function nt(e){let t=[...D];if(t.length===0)return;G(!0);let n=await K(t,e);if(G(!1),!n)return W(`That could not be saved. The workspace server refused it or did not answer.`);B(!1)}async function rt(){let e=[...D];if(e.length===0)return;G(!0);let t=null;try{let n=await fetch(`/delete`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({ids:e})});if(t=n.ok?await n.json().catch(()=>null):null,!t)return G(!1),V(),W(`Nothing was deleted. The workspace server refused it.`)}catch{return G(!1),V(),W(`The workspace server did not answer. It may have stopped.`)}let n=t.blocked??[],r=new Set(n.map(e=>e.id));for(let e of U())r.has(e.dataset.id??``)||e.remove();f=f.filter(e=>e.isConnected),D.clear();for(let e of r)D.add(e);if(G(!1),V(),n.length===0)return B(!1);N(),W([...new Set(n.map(e=>e.error))].join(` `))}async function it(){let e=U().map(e=>e.dataset.id??``).filter(Boolean);if(e.length===0)return;G(!0);let t=null;try{let n=await fetch(`/queue`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({ids:e,action:`add`})});t=n.ok?await n.json().catch(()=>null):null}catch{return G(!1),V(),W(`The workspace server did not answer. It may have stopped.`)}if(!t?.queue)return G(!1),V(),W(`Nothing was added. The workspace server refused it.`);L(t.queue);let n=t.refused??[];D.clear();for(let e of n)D.add(e.id);if(G(!1),V(),n.length===0)return B(!1);N(),W([...new Set(n.map(e=>e.error))].join(` `))}x?.addEventListener(`click`,e=>{let t=e.target;if(t.closest(`[data-bulk-queue]`))return void it();let n=t.closest(`[data-bulk-mark]`);if(n)return void $e(n.dataset.bulkMark===`complete`);let r=t.closest(`[data-bulk-lifecycle]`);if(r)return void nt(r.dataset.bulkLifecycle);if(t.closest(`[data-bulk-delete]`)){Ue&&(Ue.textContent=pe(Qe())),C&&(C.hidden=!0),S&&(S.hidden=!1);return}if(t.closest(`[data-bulk-confirm-delete]`))return void rt();if(t.closest(`[data-bulk-cancel-delete]`))return V();if(t.closest(`[data-bulk-cancel]`))return B(!1)}),ne(window,()=>window.location.reload());var J=`prb-fetch-summary`;function Y(e){return e.map(e=>({lineage:(e.dataset.lineage??e.dataset.id??``).split(` `).filter(Boolean)}))}function at(e){return se(Y(e),A)}function ot(){for(let e of f){let t=e.querySelector(`[data-fetch-review]`);t&&(t.hidden=!ae(A,Y([e])))}}async function st(){try{let e=await fetch(`/fetch-updates`);if(!e.ok)return;A=(await e.json()).targets??{}}catch{return}ot(),N()}async function ct(e,t){let n=at(e);if(M||n.repositories===0)return;M=!0;let r=[k,...document.querySelectorAll(`[data-fetch-review]`)];for(let e of r)e&&(e.disabled=!0);t&&(t.textContent=re(n.repositories));let i=null;try{let e=await fetch(`/fetch-updates`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({ids:n.ids})});e.ok&&(i=await e.json())}catch{}M=!1;for(let e of r)e&&(e.disabled=!1);t&&(t.textContent=le),N();let o=i??{repositories:n.repositories,fetched:0,failed:[],moved:0},s={kind:o.fetched<o.repositories?`failed`:`ready`,text:ie(o)};if(o.moved>0||Z){try{window.sessionStorage.setItem(J,JSON.stringify(s))}catch{}if(!Q())return void window.location.reload();Z=!0}a(c(),s)}try{let e=window.sessionStorage.getItem(J);if(e){window.sessionStorage.removeItem(J);let t=JSON.parse(e);typeof t.kind==`string`&&typeof t.text==`string`&&a(c(),{kind:t.kind,text:t.text})}}catch{}k?.addEventListener(`click`,()=>void ct(U(),k)),st();var lt=document.body.dataset.indexRevision??``,X=document.body.dataset.live===`true`?Date.now():0,Z=!1;function Q(){return D.size>0||document.activeElement===m||M}function ut(){Z&&!Q()&&window.location.reload()}async function $(){try{let e=await fetch(`/revision`);if(e.ok){ee(document,!0);let t=await e.json();s(document,t),t.live&&X===0&&(X=Date.now()),t.live||(X=0);let n=ve(lt,t.revision??``,Q());if(n===`reload`)return void window.location.reload();n===`hold`&&(Z=!0)}}catch{ee(document,!1)}window.setTimeout(()=>void $(),oe(X===0?2**53-1:Date.now()-X))}$(),m?.addEventListener(`blur`,ut),document.addEventListener(`click`,()=>window.setTimeout(ut,0)),t();
1
+ import{A as e,C as t,D as n,F as r,G as i,H as a,J as o,K as s,L as c,M as ee,N as te,O as ne,P as re,S as l,T as ie,V as ae,Y as oe,_ as se,a as ce,b as le,g as ue,h as de,i as fe,j as pe,k as me,m as he,n as ge,o as _e,p as u,s as ve,t as ye,u as be,v as xe,w as Se,x as Ce,y as we,z as Te}from"./chunk-CxNfDBSA.js";import{a as Ee,i as De,n as Oe,o as ke,r as Ae,s as je,t as Me}from"./chunk-CndkgJPh.js";import{t as Ne}from"./chunk-BadSI8AL.js";function Pe(e,t){t.forEach((t,n)=>{e.children[n]!==t&&e.insertBefore(t,e.children[n]??null)})}async function Fe(e,t,n){if(e.disabled)return;let r=e.getAttribute(`aria-pressed`)!==`true`;Ie(e,r),e.disabled=!0;let i=await t(r).catch(()=>!1);if(e.disabled=!1,!i)return Ie(e,!r);n(r)}function Ie(e,t){e.setAttribute(`aria-pressed`,String(t)),e.innerHTML=t?`&#9733;`:`&#9734;`,e.setAttribute(`aria-label`,`${t?`Unpin`:`Pin`} this review`)}function Le(e,t){let n=e.parentElement?.querySelector(`[data-history-list]`);n&&(n.hidden=!t,e.setAttribute(`aria-expanded`,String(t)))}function Re(e,t,n,r){return{limits:n,expanded:t.filter(e=>e.querySelector(`[data-history-list]:not([hidden])`)).map(e=>e.dataset.id??``).filter(e=>e!==``),main:r?.scrollTop??0,focus:a(e.activeElement,e.body)}}function ze(e,t){let n=e?.limits;if(!n||typeof n!=`object`)return t;let r={...t};for(let e of u){let t=n[e];typeof t==`number`&&Number.isInteger(t)&&t>r[e]&&(r[e]=t)}return r}function Be(e,t,n){if(!t)return;n.reveal(ze(t,n.limits));let r=new Set(o(t,`expanded`));for(let e of n.cards){let t=e.querySelector(`[data-history-toggle]`);t&&r.has(e.dataset.id??``)&&Le(t,!0)}let a=i(t,`main`);n.pane&&a!==null&&(n.pane.scrollTop=a),s(e,t.focus)}function Ve(e,n){let r=Promise.resolve();for(let i of e){let e=i.dataset.section;if(!t(e))continue;let a=i.open;i.addEventListener(`toggle`,()=>{if(i.open===a)return;a=i.open;let t=!i.open;r=r.then(()=>n(e,t)).catch(()=>{})})}}var d=ae({ownsRestore:!0});ye(`/restart`);var f=[...document.querySelectorAll(`[data-card]`)].sort((e,t)=>Number(e.dataset.rank)-Number(t.dataset.rank)),He=Object.fromEntries(u.map(e=>[e,document.querySelector(`[data-cards="${e}"]`)])),p=document.querySelector(`.prb-index`);function Ue(e){return{id:e.dataset.id??``,queue:e.dataset.queue===void 0?void 0:Number(e.dataset.queue),status:e.dataset.status??`new`,prState:e.dataset.prState}}var m=document.querySelector(`[data-search]`),h=document.querySelector(`[data-status-filter]`),g=document.querySelector(`[data-author-filter]`),_=document.querySelector(`[data-pr-filter]`),We=document.querySelector(`[data-no-matches]`),v=document.querySelector(`[data-count]`),y=l();function Ge(e){return{stored:Te({state:e.dataset.lifecycle,at:Number(e.dataset.lifecycleAt)}),activity:re(e.dataset)??{at:0,kind:`created`}}}function Ke(e){return e.dataset.pinned===`true`}function b(e){let{stored:t,activity:n}=Ge(e);return Ce(Ke(e),t,n,E.filter)}var x=document.querySelector(`[data-bulk]`),qe=document.querySelector(`[data-bulk-count]`),Je=document.querySelector(`[data-bulk-delete]`),Ye=document.querySelector(`[data-bulk-question]`),S=document.querySelector(`[data-bulk-confirm]`),C=document.querySelector(`[data-bulk-actions]`),w=document.querySelector(`[data-bulk-error]`),T=document.querySelector(`[data-bulk-select-all]`),E=ie(window.location.hash),D=new Set,O=!1,k=document.querySelector(`[data-bulk-fetch]`),A={},j=[],M=!1;function N(){let t=E.query.trim().toLowerCase();E.author!==``&&![...g?.options??[]].some(e=>e.value===E.author)&&(E.author=``);let n=le(xe(f.map(e=>({...Ue(e),searchText:e.dataset.searchText??``,author:e.dataset.author,card:e})),{...E,query:t}).map(e=>e.card),b);j=n;let r=e(n,b,y),i=new Set(u.flatMap(e=>r[e].shown));for(let e of f)e.hidden=!i.has(e);for(let e of u){let t=He[e];t&&Pe(t,r[e].shown);let n=document.querySelector(`[data-load-more="${e}"]`);n&&(n.hidden=r[e].total<=r[e].shown.length);let i=document.querySelector(`[data-section="${e}"]`);i&&(i.hidden=r[e].total===0);let a=i?.querySelector(`[data-section-count]`);a&&(a.textContent=String(r[e].total))}if(m&&m.value!==E.query&&(m.value=E.query),g&&(g.value=E.author,E.author===``?delete g.dataset.active:g.dataset.active=``),_||(E.pr=`any`),_&&(_.value=E.pr,E.pr===`any`?delete _.dataset.active:_.dataset.active=``),h&&(h.value=E.filter,E.filter===`all`?delete h.dataset.active:h.dataset.active=``),v){let e=n.reduce((e,t)=>e+Number(t.dataset.reviews??1),0);v.textContent=de(e,n.length)}We&&(We.hidden=n.length>0||f.length===0),tt(n)}var Xe=300,P=null;function F(){P!==null&&window.clearTimeout(P),P=null,d.replace(we(E),{})}function I(e,t){if(E={...E,...e},y=l(),N(),t===`now`)return F();P!==null&&window.clearTimeout(P),P=window.setTimeout(F,Xe)}window.addEventListener(`pagehide`,()=>{P!==null&&F()}),document.addEventListener(`click`,e=>{P!==null&&e.target?.closest?.(`a[href]`)&&F()},!0),m?.addEventListener(`input`,()=>I({query:m.value},`settled`)),m?.addEventListener(`keydown`,e=>{e.key===`Escape`&&m.value!==``&&(e.preventDefault(),I({query:``},`now`))}),h?.addEventListener(`change`,()=>{I({filter:h.value},`now`)}),g?.addEventListener(`change`,()=>{I({author:g.value},`now`)}),_?.addEventListener(`change`,()=>{I({pr:_.value},`now`)}),document.addEventListener(`click`,e=>{let t=e.target.closest(`[data-load-more]`)?.dataset.loadMore;!t||!u.includes(t)||(y={...y,[t]:y[t]+15},N())});for(let e of[`popstate`,`hashchange`])window.addEventListener(e,()=>{E=ie(window.location.hash),y=l(),N(),Qe()});document.addEventListener(`click`,e=>{let t=e.target.closest(`[data-pin]`);if(!t?.dataset.pin)return;e.preventDefault(),e.stopPropagation();let n=t.dataset.pin;Fe(t,e=>fetch(`/pin`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({id:n,pinned:e})}).then(e=>e.ok),e=>{let n=t.closest(`[data-card]`);n&&(n.dataset.pinned=String(e),J(n),N())})});async function Ze(e,t){let n;try{let r=await fetch(`/queue`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({id:e,action:t})});if(!r.ok)return;n=(await r.json()).queue}catch{return}L(n),N()}function L(e){let t=new Map(e.map((e,t)=>[e,t]));for(let e of f){let n=t.get(e.dataset.id??``);n===void 0?delete e.dataset.queue:e.dataset.queue=String(n),n!==void 0&&e.dataset.lifecycle!==`active`&&(e.dataset.lifecycle=`active`,delete e.dataset.lifecycleAt,J(e))}for(let e of document.querySelectorAll(`[data-queue-action][data-queue-id]`)){let r=t.has(e.dataset.queueId??``);e.dataset.queueAction=r?`remove`:`add`,e.textContent=n(r)}let r=document.querySelector(`[data-queue-option]`);r&&(r.textContent=ne(e.length))}document.addEventListener(`click`,e=>{let t=e.target.closest(`[data-history-toggle]`);if(!t)return;e.preventDefault(),e.stopPropagation();let n=t.parentElement?.querySelector(`[data-history-list]`);n&&Le(t,n.hidden!==!1)});var R=document.querySelector(`.prb-shell > main`);function Qe(){Be(document,d.current().ui,{cards:f,pane:R,limits:y,reveal:e=>{y=e,N()}})}d.setCapturer(()=>Re(document,f,y,R)),N(),Qe();function z(e){for(let t of document.querySelectorAll(`[data-menu]`)){if(t===e)continue;let n=t.querySelector(`[data-menu-panel]`),r=t.querySelector(`[data-menu-trigger]`);n&&(n.hidden=!0),r?.setAttribute(`aria-expanded`,`false`),B(t)}}function B(e){let t=e.querySelector(`[data-menu-items]`),n=e.querySelector(`[data-menu-confirm]`);t&&(t.hidden=!1),n&&(n.hidden=!0),e.querySelector(`[data-menu-error]`)?.remove(),e.querySelector(`[data-id-field]`)?.remove()}document.addEventListener(`keydown`,e=>{e.key===`Escape`&&z()}),document.addEventListener(`click`,e=>{let t=e.target,n=t.closest(`[data-menu]`);if(!n)return void z();let r=t.closest(`[data-menu-trigger]`);if(r){e.preventDefault(),e.stopPropagation();let t=n.querySelector(`[data-menu-panel]`);if(!t)return;let i=t.hidden;z(n),B(n),t.hidden=!i,r.setAttribute(`aria-expanded`,String(i));return}let i=t.closest(`[data-copy-id]`);if(i?.dataset.copyId){e.preventDefault(),e.stopPropagation(),je(i,i.dataset.copyId);return}let a=t.closest(`[data-fetch-review]`);if(a?.dataset.fetchReview){e.preventDefault(),e.stopPropagation(),z();let t=a.closest(`[data-card]`);t&&St([t]);return}let o=t.closest(`[data-mark-status]`);if(o?.dataset.markId){e.preventDefault(),e.stopPropagation(),z(),mt(o.dataset.markId,o.dataset.markStatus===`complete`);return}let s=t.closest(`[data-lifecycle-set]`);if(s?.dataset.lifecycleId){e.preventDefault(),e.stopPropagation(),z(),ht([s.dataset.lifecycleId],s.dataset.lifecycleSet);return}let c=t.closest(`[data-queue-action]`);if(c?.dataset.queueId){e.preventDefault(),e.stopPropagation(),z(),Ze(c.dataset.queueId,c.dataset.queueAction===`remove`?`remove`:`add`);return}if(t.closest(`[data-delete]`)){e.preventDefault(),e.stopPropagation();let t=n.querySelector(`[data-menu-items]`),r=n.querySelector(`[data-menu-confirm]`);t&&(t.hidden=!0),r&&(r.hidden=!1);return}if(t.closest(`[data-cancel-delete]`)){e.preventDefault(),e.stopPropagation(),B(n);return}if(t.closest(`[data-confirm-delete]`)){e.preventDefault(),e.stopPropagation(),$e(n);return}e.preventDefault(),e.stopPropagation()});async function $e(e){let t=e.querySelector(`[data-delete]`),n=t?.dataset.delete;if(!n)return;let r=e.querySelector(`[data-menu-confirm]`),i=e.querySelector(`[data-confirm-delete]`);i&&(i.disabled=!0,i.textContent=`Deleting`);try{let r=await fetch(`/delete`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({id:n,scope:t?.dataset.scope??`review`})});if(r.ok)return void window.location.reload();et(e,(await r.json().catch(()=>null))?.error??`That could not be deleted.`)}catch{et(e,`The workspace server did not answer. It may have stopped.`)}i&&(i.disabled=!1,i.textContent=`Delete`),r&&(r.hidden=!0);let a=e.querySelector(`[data-menu-items]`);a&&(a.hidden=!1)}function et(e,t){e.querySelector(`[data-menu-error]`)?.remove();let n=document.createElement(`p`);n.className=`prb-menu-error`,n.setAttribute(`data-menu-error`,``),n.textContent=t,e.querySelector(`[data-menu-panel]`)?.append(n)}function V(e){O=e,e||D.clear(),p&&(e?p.dataset.selecting=``:delete p.dataset.selecting),document.querySelector(`[data-select-mode]`)?.setAttribute(`aria-pressed`,String(e));for(let t of document.querySelectorAll(`.prb-card-link`))e?t.setAttribute(`aria-disabled`,`true`):t.removeAttribute(`aria-disabled`);H(),N()}function H(){S&&(S.hidden=!0),C&&(C.hidden=!1),w&&(w.hidden=!0,w.textContent=``)}function tt(e){for(let e of f){let t=D.has(e.dataset.id??``),n=e.querySelector(`[data-select]`);n&&(n.checked=t),t?e.dataset.selected=``:delete e.dataset.selected}if(!x||(x.hidden=!O,!O))return;let t=new Set(e.filter(nt).map(e=>e.dataset.id)),n=[...D].filter(e=>!t.has(e)).length;qe&&(qe.textContent=ee(D.size,n)),T&&(T.textContent=pe(e.length),T.disabled=e.every(e=>D.has(e.dataset.id??``))),Je&&(Je.textContent=ue(dt()));for(let e of x.querySelectorAll(`[data-bulk-mark], [data-bulk-lifecycle], [data-bulk-queue], [data-bulk-delete]`))e.disabled=D.size===0;k&&(k.hidden=!Oe(A,X(G())))}function nt(e){return!e.hidden&&e.closest(`details`)?.open!==!1}for(let e of document.querySelectorAll(`details[data-section]`))e.addEventListener(`toggle`,()=>tt(j));Ve(document.querySelectorAll(`details[data-section]`),(e,t)=>fetch(`/sections`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({section:e,collapsed:t})})),document.querySelector(`[data-select-mode]`)?.addEventListener(`click`,()=>{V(!O)}),T?.addEventListener(`click`,()=>{for(let e of j)e.dataset.id&&D.add(e.dataset.id);H(),N()});function U(e){D.has(e)?D.delete(e):D.add(e),H(),N()}document.addEventListener(`change`,e=>{let t=e.target.closest(`[data-select]`);t?.dataset.select&&U(t.dataset.select)}),document.addEventListener(`click`,e=>{if(!O)return;let t=e.target,n=t.closest(`[data-card]`);n?.dataset.id&&(t.closest(`[data-select], [data-pin], [data-menu], [data-history-toggle]`)||(e.preventDefault(),U(n.dataset.id)))}),document.addEventListener(`keydown`,e=>{if(!O||e.key!==`Enter`)return;let t=e.target.closest(`.prb-card-link`)?.closest(`[data-card]`);t?.dataset.id&&(e.preventDefault(),U(t.dataset.id))});var W=Ne({doc:document,item:`[data-card]`,link:`.prb-card-link`,walk:()=>j.filter(nt),enterAllowed:()=>!O,background:()=>R,leadIn:e=>[...e.closest(`[data-cards]`)?.querySelectorAll(`[data-card]:not([hidden])`)??[]][0]===e?e.closest(`details[data-section]`)?.querySelector(`summary`)??null:null}),rt=8;function it(e){let t=e.querySelector(`.prb-card-link`);t&&(t.focus({preventScroll:!0}),document.activeElement!==t&&document.activeElement?.blur(),P!==null&&F(),d.leaving(),at=!0,window.location.assign(t.href))}var at=!1,ot={title:`Search reviews`,mount(e,t){let n=document.createElement(`input`);n.type=`search`,n.className=`prb-palette-input`,n.placeholder=m?.placeholder??``,n.setAttribute(`aria-label`,`Search reviews`),n.spellcheck=!1,n.value=m?.value??``;let r=document.createElement(`p`);r.className=`prb-palette-summary`,r.setAttribute(`aria-live`,`polite`);let i=document.createElement(`div`);i.className=`prb-palette-results`,i.setAttribute(`role`,`group`),i.setAttribute(`aria-label`,`Matching reviews`);let a=()=>{let e=j.slice(0,rt);i.replaceChildren(...e.map(e=>{let t=document.createElement(`button`);t.type=`button`,t.className=`prb-palette-result`,t.dataset.resultId=e.dataset.id??``;let n=document.createElement(`span`);n.className=`prb-palette-result-title`,n.textContent=e.querySelector(`.prb-card-head h2`)?.textContent??``;let r=document.createElement(`span`);return r.className=`prb-palette-result-where`,r.textContent=[e.querySelector(`.prb-card-repo`)?.textContent,e.querySelector(`.prb-card-branch`)?.textContent].filter(Boolean).join(` · `),t.append(n,r),t})),r.textContent=j.length===0?`No reviews match.`:j.length>e.length?`The first ${e.length} of ${v?.textContent??j.length}`:v?.textContent??``},o=()=>[...i.querySelectorAll(`.prb-palette-result`)],s=e=>{let n=f.find(t=>t.dataset.id===e?.dataset.resultId);n&&(t(),it(n))};n.addEventListener(`input`,()=>{m&&(m.value=n.value,m.dispatchEvent(new Event(`input`,{bubbles:!0})),a())}),i.addEventListener(`click`,e=>s(e.target.closest(`.prb-palette-result`)??void 0)),e.addEventListener(`keydown`,e=>{if(e.isComposing)return;let t=o(),r=t.indexOf(e.target);if(e.key===`Enter`&&e.target===n)return e.preventDefault(),s(t[0]);let i=e.key===`ArrowDown`?r<0?t[0]:t[r+1]:e.key===`ArrowUp`?r<=0?n:t[r-1]:null;i&&(e.preventDefault(),i.focus())}),e.append(n,r,i),a(),n.focus(),n.select()}},st={title:`Filters`,mount(e){let t=document.createElement(`p`);t.className=`prb-palette-summary`,t.setAttribute(`aria-live`,`polite`);let n=()=>{t.textContent=v?.textContent??``},r=[h,g,_].flatMap(e=>{if(!e)return[];let t=document.createElement(`label`);t.className=`prb-palette-field`;let r=document.createElement(`span`),i=(e.getAttribute(`aria-label`)??``).replace(/^Filter by /,``);r.textContent=i.charAt(0).toUpperCase()+i.slice(1);let a=document.createElement(`select`);for(let t of e.options)a.append(new Option(t.text,t.value));return a.value=e.value,a.addEventListener(`change`,()=>{e.value=a.value,e.dispatchEvent(new Event(`change`,{bubbles:!0})),n()}),t.append(r,a),[t]});e.append(...r,t),n(),r[0]?.querySelector(`select`)?.focus()}};function ct(e){let t=()=>document.querySelector(`details[data-section="${e}"]`);return{available:()=>!!(t()&&!t().hidden),state:()=>{let e=t();return e&&!e.hidden?e.open?`Expanded`:`Collapsed`:null},run:()=>{let e=t();e&&(e.open=!e.open)}}}var lt=Object.fromEntries(u.map(e=>[`reviews.section.${e}`,ct(e)])),ut=be(`reviews`,{...lt,"reviews.search":{available:()=>m!==null,panel:ot},"reviews.filters":{available:()=>h!==null,panel:st},"reviews.next":{run:()=>W.move(1)},"reviews.previous":{run:()=>W.move(-1)},"reviews.open":{available:()=>W.enterOpens(),run:()=>W.open()},"reviews.openInNewTab":{available:()=>W.enterOpens(),run:()=>W.openInNewTab()}},{onOpen:()=>z(),onSettle:()=>$()});function G(){return le(f.filter(e=>D.has(e.dataset.id??``)),b)}function dt(){return G().reduce((e,t)=>e+Number(t.dataset.reviews??1),0)}function K(e){w&&(w.textContent=e,w.hidden=!1)}function q(e){for(let t of x?.querySelectorAll(`button`)??[])t.disabled=e}async function ft(e){let t=[...D];if(t.length!==0){q(!0);try{if(!(await fetch(`/status`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({ids:t,complete:e})})).ok)return q(!1),K(`That could not be saved. The workspace server refused it.`)}catch{return q(!1),K(`The workspace server did not answer. It may have stopped.`)}pt(G(),e),q(!1),V(!1)}}function pt(e,t){let n=t?`complete`:`in-progress`,r=t?`in-progress`:`complete`;for(let t of e){t.dataset.status=n;let e=t.querySelector(`.prb-card-status`);e&&(e.dataset.status=n,e.textContent=te(n));let i=t.querySelector(`[data-mark-status]`);i&&(i.dataset.markStatus=r,i.textContent=Se(r))}}async function mt(e,t){try{if(!(await fetch(`/status`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({ids:[e],complete:t})})).ok)return}catch{return}pt(f.filter(t=>t.dataset.id===e),t),N()}async function ht(e,t){let n;try{let r=await fetch(`/lifecycle`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({ids:e,state:t})});n=r.ok?await r.json().catch(()=>null):null}catch{n=null}if(!n)return!1;let r=new Set(e);for(let e of f)r.has(e.dataset.id??``)&&(e.dataset.lifecycle=t,t===`active`?delete e.dataset.lifecycleAt:e.dataset.lifecycleAt=String(n.at),J(e));return L(n.queue),N(),!0}function J(e){let{stored:t,activity:n}=Ge(e),i=e.querySelector(`[data-lifecycle-chip]`);if(i){let r=he(Ke(e),t,n);i.textContent=r??``,i.hidden=r===void 0}for(let i of e.querySelectorAll(`[data-lifecycle-set]`)){let e=i.dataset.lifecycleSet;i.hidden=!c(e,t,n),i.textContent=r(e,t,n)}}async function gt(e){let t=[...D];if(t.length===0)return;q(!0);let n=await ht(t,e);if(q(!1),!n)return K(`That could not be saved. The workspace server refused it or did not answer.`);V(!1)}async function _t(){let e=[...D];if(e.length===0)return;q(!0);let t=null;try{let n=await fetch(`/delete`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({ids:e})});if(t=n.ok?await n.json().catch(()=>null):null,!t)return q(!1),H(),K(`Nothing was deleted. The workspace server refused it.`)}catch{return q(!1),H(),K(`The workspace server did not answer. It may have stopped.`)}let n=t.blocked??[],r=new Set(n.map(e=>e.id));for(let e of G())r.has(e.dataset.id??``)||e.remove();f=f.filter(e=>e.isConnected),D.clear();for(let e of r)D.add(e);if(q(!1),H(),n.length===0)return V(!1);N(),K([...new Set(n.map(e=>e.error))].join(` `))}async function vt(){let e=G().map(e=>e.dataset.id??``).filter(Boolean);if(e.length===0)return;q(!0);let t=null;try{let n=await fetch(`/queue`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({ids:e,action:`add`})});t=n.ok?await n.json().catch(()=>null):null}catch{return q(!1),H(),K(`The workspace server did not answer. It may have stopped.`)}if(!t?.queue)return q(!1),H(),K(`Nothing was added. The workspace server refused it.`);L(t.queue);let n=t.refused??[];D.clear();for(let e of n)D.add(e.id);if(q(!1),H(),n.length===0)return V(!1);N(),K([...new Set(n.map(e=>e.error))].join(` `))}x?.addEventListener(`click`,e=>{let t=e.target;if(t.closest(`[data-bulk-queue]`))return void vt();let n=t.closest(`[data-bulk-mark]`);if(n)return void ft(n.dataset.bulkMark===`complete`);let r=t.closest(`[data-bulk-lifecycle]`);if(r)return void gt(r.dataset.bulkLifecycle);if(t.closest(`[data-bulk-delete]`)){Ye&&(Ye.textContent=se(dt())),C&&(C.hidden=!0),S&&(S.hidden=!1);return}if(t.closest(`[data-bulk-confirm-delete]`))return void _t();if(t.closest(`[data-bulk-cancel-delete]`))return H();if(t.closest(`[data-bulk-cancel]`))return V(!1)}),oe(window,()=>window.location.reload());var Y=`prb-fetch-summary`;function X(e){return e.map(e=>({lineage:(e.dataset.lineage??e.dataset.id??``).split(` `).filter(Boolean)}))}function yt(e){return Ae(X(e),A)}function bt(){for(let e of f){let t=e.querySelector(`[data-fetch-review]`);t&&(t.hidden=!Oe(A,X([e])))}}async function xt(){try{let e=await fetch(`/fetch-updates`);if(!e.ok)return;A=(await e.json()).targets??{}}catch{return}bt(),N()}async function St(e,t){let n=yt(e);if(M||n.repositories===0)return;M=!0;let r=[k,...document.querySelectorAll(`[data-fetch-review]`)];for(let e of r)e&&(e.disabled=!0);t&&(t.textContent=Ee(n.repositories));let i=null;try{let e=await fetch(`/fetch-updates`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({ids:n.ids})});e.ok&&(i=await e.json())}catch{}M=!1;for(let e of r)e&&(e.disabled=!1);t&&(t.textContent=Me),N();let a=i??{repositories:n.repositories,fetched:0,failed:[],moved:0},o={kind:a.fetched<a.repositories?`failed`:`ready`,text:De(a)};if(a.moved>0||Q){try{window.sessionStorage.setItem(Y,JSON.stringify(o))}catch{}if(!wt())return void window.location.reload();Q=!0}fe(_e(),o)}try{let e=window.sessionStorage.getItem(Y);if(e){window.sessionStorage.removeItem(Y);let t=JSON.parse(e);typeof t.kind==`string`&&typeof t.text==`string`&&fe(_e(),{kind:t.kind,text:t.text})}}catch{}k?.addEventListener(`click`,()=>void St(G(),k)),xt();var Ct=document.body.dataset.indexRevision??``,Z=document.body.dataset.live===`true`?Date.now():0,Q=!1;function wt(){return D.size>0||document.activeElement===m||M||ut.isOpen()||at}function $(){Q&&!wt()&&window.location.reload()}async function Tt(){try{let e=await fetch(`/revision`);if(e.ok){ve(document,!0);let t=await e.json();ge(document,t),t.live&&Z===0&&(Z=Date.now()),t.live||(Z=0);let n=me(Ct,t.revision??``,wt());if(n===`reload`)return void window.location.reload();n===`hold`&&(Q=!0)}}catch{ve(document,!1)}window.setTimeout(()=>void Tt(),ke(Z===0?2**53-1:Date.now()-Z))}Tt(),m?.addEventListener(`blur`,$),document.addEventListener(`click`,()=>window.setTimeout($,0)),ce();
@@ -1 +1 @@
1
- import{a as e,c as t,d as n,t as r,v as i}from"./chunk-CyYZeRiG.js";function a(e,t){if(e===``)return null;try{let n=new URL(e);return n.origin===t&&/^\/r\/[^/]+$/.test(n.pathname)?n.href:null}catch{return null}}function o(e){let t=[...document.querySelectorAll(`[data-shutdown]`)],n=document.querySelector(`[data-shutdown-dialog]`),r=document.querySelector(`[data-shutdown-confirm]`);for(let e of t)e.addEventListener(`click`,()=>n?.showModal());document.querySelector(`[data-shutdown-cancel]`)?.addEventListener(`click`,()=>n?.close()),r?.addEventListener(`click`,()=>{r.disabled=!0,r.textContent=`Stopping…`,fetch(e,{method:`POST`}).then(e=>{if(!e.ok)throw Error(`Shutdown refused: ${e.status}`);n?.close(),s(t)}).catch(()=>{r.disabled=!1,r.textContent=`Stop server`})})}function s(e){document.body.dataset.serverStopped=`true`,t(document,`unreachable`);let n=document.createElement(`div`);n.className=`prb-stopped-notice`,n.setAttribute(`role`,`status`);let r=document.body.dataset.wayBack;n.textContent=r?`Workspace server stopped. This page is no longer being served. Run ${r} to bring it back.`:`Workspace server stopped. This page is no longer being served.`,document.body.prepend(n);for(let t of e)t.disabled=!0,t.classList.contains(`prb-strip-action`)||(t.textContent=`Server stopped`)}var c=[{id:`system`,label:`System`,help:`Follow your device setting`},{id:`light`,label:`Light`,help:`Always use light mode`},{id:`dark`,label:`Dark`,help:`Always use dark mode`}];function l(e){return c.some(t=>t.id===e)}function u(e){let t=e.querySelector(`[data-settings-theme]:checked`)?.value;return l(t)?t:void 0}function d(e,t){e.documentElement.dataset.theme=t}function f(e){for(let t of e.querySelectorAll(`[data-settings-theme]`))t.addEventListener(`change`,()=>{let t=u(e);t&&d(e,t)})}o(`/shutdown`),n(),r(`/restart`);function p(){let e=document.querySelector(`[data-settings-back]`),t=a(document.referrer,window.location.origin);if(!e||t===null)return;e.href=t,e.textContent=``;let n=document.createElement(`span`);n.setAttribute(`aria-hidden`,`true`),n.textContent=`‹`,e.append(n,` Back to the review`)}p(),f(document);var m=document.querySelector(`[data-settings-save]`),h=document.querySelector(`[data-settings-status]`),g=document.querySelector(`[data-settings-port]`),_=document.querySelector(`[data-settings-port-error]`),v=document.querySelector(`[data-settings-agent]`);function y(){let e=document.querySelector(`[data-settings-usage]:checked`);return e?e.value===`on`:void 0}function b(e,t){h&&(h.textContent=e,h.dataset.kind=t)}function x(e){_&&(_.textContent=e??``),g&&(e?(g.setAttribute(`aria-invalid`,`true`),g.focus(),g.select()):g.removeAttribute(`aria-invalid`))}async function S(){if(!m)return;let e=y(),t=u(document),n={...g?{port:g.value.trim()}:{},...v?{agent:v.value}:{},...e===void 0?{}:{usageCounts:e},...t===void 0?{}:{theme:t}};m.disabled=!0,m.textContent=`Saving`;try{let e=await(await fetch(`/settings`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(n)})).json().catch(()=>null);if(!e){b(`Nothing was saved. The workspace server did not answer.`,`error`);return}if(e.error){x(e.error),b(`Nothing was saved.`,`error`);return}x(null),g&&(g.value=String(e.port.configured)),d(document,e.theme),b(e.restartRequired?`Saved. This page is served on port ${e.port.current}; the workspace moves to ${e.port.configured} the next time it starts.`:`Saved.`,`saved`)}catch{b(`Nothing was saved. The workspace server could not be reached.`,`error`)}finally{m.disabled=!1,m.textContent=`Save changes`}}m?.addEventListener(`click`,()=>void S()),e(),i(window,()=>window.location.reload());
1
+ import{V as e,Y as t,a as n,c as r,t as i,u as a}from"./chunk-CxNfDBSA.js";function o(e,t){if(e===``)return null;try{let n=new URL(e);return n.origin===t&&/^\/r\/[^/]+$/.test(n.pathname)?n.href:null}catch{return null}}function s(e){let t=[...document.querySelectorAll(`[data-shutdown]`)],n=document.querySelector(`[data-shutdown-dialog]`),r=document.querySelector(`[data-shutdown-confirm]`);for(let e of t)e.addEventListener(`click`,()=>n?.showModal());document.querySelector(`[data-shutdown-cancel]`)?.addEventListener(`click`,()=>n?.close()),r?.addEventListener(`click`,()=>{r.disabled=!0,r.textContent=`Stopping…`,fetch(e,{method:`POST`}).then(e=>{if(!e.ok)throw Error(`Shutdown refused: ${e.status}`);n?.close(),c(t)}).catch(()=>{r.disabled=!1,r.textContent=`Stop server`})})}function c(e){document.body.dataset.serverStopped=`true`,r(document,`unreachable`);let t=document.createElement(`div`);t.className=`prb-stopped-notice`,t.setAttribute(`role`,`status`);let n=document.body.dataset.wayBack;t.textContent=n?`Workspace server stopped. This page is no longer being served. Run ${n} to bring it back.`:`Workspace server stopped. This page is no longer being served.`,document.body.prepend(t);for(let t of e)t.disabled=!0,t.classList.contains(`prb-strip-action`)||(t.textContent=`Server stopped`)}var l=[{id:`system`,label:`System`,help:`Follow your device setting`},{id:`light`,label:`Light`,help:`Always use light mode`},{id:`dark`,label:`Dark`,help:`Always use dark mode`}];function u(e){return l.some(t=>t.id===e)}function d(e){let t=e.querySelector(`[data-settings-theme]:checked`)?.value;return u(t)?t:void 0}function f(e,t){e.documentElement.dataset.theme=t}function p(e){for(let t of e.querySelectorAll(`[data-settings-theme]`))t.addEventListener(`change`,()=>{let t=d(e);t&&f(e,t)})}s(`/shutdown`),e(),a(`global`,{}),i(`/restart`);function m(){let e=document.querySelector(`[data-settings-back]`),t=o(document.referrer,window.location.origin);if(!e||t===null)return;e.href=t,e.textContent=``;let n=document.createElement(`span`);n.setAttribute(`aria-hidden`,`true`),n.textContent=`‹`,e.append(n,` Back to the review`)}m(),p(document);var h=document.querySelector(`[data-settings-save]`),g=document.querySelector(`[data-settings-status]`),_=document.querySelector(`[data-settings-port]`),v=document.querySelector(`[data-settings-port-error]`),y=document.querySelector(`[data-settings-agent]`);function b(){let e=document.querySelector(`[data-settings-usage]:checked`);return e?e.value===`on`:void 0}function x(e,t){g&&(g.textContent=e,g.dataset.kind=t)}function S(e){v&&(v.textContent=e??``),_&&(e?(_.setAttribute(`aria-invalid`,`true`),_.focus(),_.select()):_.removeAttribute(`aria-invalid`))}async function C(){if(!h)return;let e=b(),t=d(document),n={..._?{port:_.value.trim()}:{},...y?{agent:y.value}:{},...e===void 0?{}:{usageCounts:e},...t===void 0?{}:{theme:t}};h.disabled=!0,h.textContent=`Saving`;try{let e=await(await fetch(`/settings`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(n)})).json().catch(()=>null);if(!e){x(`Nothing was saved. The workspace server did not answer.`,`error`);return}if(e.error){S(e.error),x(`Nothing was saved.`,`error`);return}S(null),_&&(_.value=String(e.port.configured)),f(document,e.theme),x(e.restartRequired?`Saved. This page is served on port ${e.port.current}; the workspace moves to ${e.port.configured} the next time it starts.`:`Saved.`,`saved`)}catch{x(`Nothing was saved. The workspace server could not be reached.`,`error`)}finally{h.disabled=!1,h.textContent=`Save changes`}}h?.addEventListener(`click`,()=>void C()),n(),t(window,()=>window.location.reload());