prreviewbuddy 0.59.50 → 0.62.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/CHANGELOG.md +86 -0
- package/dist/{delete_review-TsYWWNVr.js → delete_review-LzUgEUzN.js} +29 -4
- package/dist/main.js +1 -1
- package/dist/server.js +139 -22
- package/package.json +1 -1
- package/static/chunk-BadSI8AL.js +1 -0
- package/static/chunk-CxNfDBSA.js +1 -0
- package/static/help.js +1 -1
- package/static/notifications.js +1 -1
- package/static/reviews.js +1 -1
- package/static/settings.js +1 -1
- package/static/shell.css +184 -0
- package/static/workspace.js +79 -79
- package/static/chunk-Cj8lEKkl.js +0 -1
- package/static/chunk-CyYZeRiG.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,91 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.62.0
|
|
4
|
+
|
|
5
|
+
**Buddy AI has its own keys.** On a review, ⌘K B opens a Buddy AI menu. B O opens Buddy AI with
|
|
6
|
+
the cursor in its question, which is what ⌘K S B used to do; Sections now lists the review's own
|
|
7
|
+
content only.
|
|
8
|
+
|
|
9
|
+
**Choose a prompt without leaving the keyboard.** ⌘K B P lists your prompts, the ones under Your
|
|
10
|
+
prompts in Buddy AI, in the same order. Type to narrow them by name or wording. The first ten shown
|
|
11
|
+
are numbered, and pressing a number picks that prompt; the numbers follow what you have typed, so
|
|
12
|
+
the best match is always 1. The arrows, or J and K once you are in the list, reach the rest, and
|
|
13
|
+
Enter picks. The prompt goes into your question exactly as clicking it does, with Buddy AI open
|
|
14
|
+
and ready for you to carry on. Escape goes back to the Buddy AI menu.
|
|
15
|
+
|
|
16
|
+
## 0.61.1
|
|
17
|
+
|
|
18
|
+
**J and K show the ends of the list.** Walking the Reviews list stopped with the first or last
|
|
19
|
+
review flush against the edge of the window, leaving the count, Select and the section's name above
|
|
20
|
+
it, or Load more below it, scrolled out of sight. Reaching the first review now scrolls the list
|
|
21
|
+
right back to its top, reaching the last scrolls it to its bottom, arriving at the first review of a
|
|
22
|
+
section brings that section's heading with it, and every other review stops a little short of the
|
|
23
|
+
edge. The same goes for notifications.
|
|
24
|
+
|
|
25
|
+
**The highlight on a notification has its corners.** On the first or last notification shown, the
|
|
26
|
+
list's rounded corners cut the highlight off; it is now rounded to match.
|
|
27
|
+
|
|
28
|
+
## 0.61.0
|
|
29
|
+
|
|
30
|
+
**Search and Filters inside the command palette.** On the Reviews list, ⌘K S now turns the palette
|
|
31
|
+
into a search: type, and the matching reviews appear under the field as you go; Enter or a click
|
|
32
|
+
opens one. ⌘K F shows the list's filters there, each with its current choice. Both are the toolbar's
|
|
33
|
+
own search and filters, so whatever you choose in one shows in the other, and the toolbar is still
|
|
34
|
+
there for the mouse. Escape takes you back to the palette's commands, and a second Escape closes it.
|
|
35
|
+
|
|
36
|
+
**J and K on Notifications.** Move through the notifications with J and K, open one with Enter or
|
|
37
|
+
in a new tab with Shift+Enter, and come back to it with Back, as on the Reviews list.
|
|
38
|
+
|
|
39
|
+
**The Reviews list's ring now sits on the card's own edge**, with no gap between them.
|
|
40
|
+
|
|
41
|
+
## 0.60.0
|
|
42
|
+
|
|
43
|
+
**Keyboard commands across the workspace.** Press **⌘K** on a Mac, or **Ctrl+K** elsewhere, to open
|
|
44
|
+
the command palette. It lists what you can do on the page you are on, and after a key that leads
|
|
45
|
+
somewhere (on a review **S** for Sections, **M** for Mark and **A** for Actions, on the Reviews
|
|
46
|
+
list **L** for its sections), it shows the keys that can follow. It stays open until you choose
|
|
47
|
+
something, press Escape or click away. A key it does not know just closes it.
|
|
48
|
+
|
|
49
|
+
- **Anywhere:** ⌘K R goes to Reviews, ⌘K N to Notifications, and ⌘K ? opens the full table of
|
|
50
|
+
keyboard shortcuts.
|
|
51
|
+
- **On a review:** ⌘K S then K, I, G, Q, F or B goes to KISS, Issues, Diagrams, Questions, Files or
|
|
52
|
+
Buddy AI. With a section expanded, the one you go to arrives expanded. **\\** expands or collapses
|
|
53
|
+
the section you are on, and Escape still leaves focus mode. ⌘K M then R, W or D marks the review
|
|
54
|
+
reviewed, waiting or done. ⌘K A then C checks for updates, U updates the review (wherever the
|
|
55
|
+
Update review button is offered), Q adds it to the review queue or takes it out, and D opens the
|
|
56
|
+
delete confirmation, with Cancel ready, and deletes nothing by itself.
|
|
57
|
+
- **On the Reviews list:** J and K move through the reviews on screen, drawing a ring around the
|
|
58
|
+
one Enter opens; Shift+Enter opens it in a new tab. The ring stays put while the mouse moves, is
|
|
59
|
+
separate from the ticks of Select, and comes back to the review you opened when you go Back. ⌘K S
|
|
60
|
+
puts you in search, ⌘K F on the filters, and ⌘K L then P, A, W or D folds or opens Pinned,
|
|
61
|
+
Active, Waiting or Done, with the palette saying which are open.
|
|
62
|
+
|
|
63
|
+
A command that cannot apply right now, such as Mark waiting on an older review of a branch, is shown
|
|
64
|
+
dimmed and does nothing, as is anything that would change where the review stands while another
|
|
65
|
+
such change is still on its way to the server. Single keys never act while you are typing in a
|
|
66
|
+
field. The **…** menu on a review shows each action's shortcut beside it, and Help has the same
|
|
67
|
+
table under Keyboard.
|
|
68
|
+
|
|
69
|
+
## 0.59.52
|
|
70
|
+
|
|
71
|
+
**The Reviews page remembers which sections you fold.** Pinned, Active, Waiting and Done each keep
|
|
72
|
+
the state you left them in through a refresh, the page's own live updates and a restart of the
|
|
73
|
+
workspace. A review arriving in a section you folded does not open it, though the count beside its
|
|
74
|
+
name still changes. Until you fold or open a section yourself it starts as before, with Done folded
|
|
75
|
+
and the rest open. The choice is stored on your machine, alongside the theme and the Buddy AI width.
|
|
76
|
+
|
|
77
|
+
## 0.59.51
|
|
78
|
+
|
|
79
|
+
**A merge no longer marks a Done review as changed.** A review you had marked Done showed
|
|
80
|
+
**Changed since done** as soon as its pull request merged or closed, even with no new commits, which
|
|
81
|
+
read as a contradiction beside **Review up to date**. It now shows that only when new commits land
|
|
82
|
+
after you marked it Done, including commits pushed just before a merge. A pull request reopened after
|
|
83
|
+
Done shows **Reopened since done**.
|
|
84
|
+
|
|
85
|
+
**Keep done settles a changed review.** On a Done review showing either of those, the menu now says
|
|
86
|
+
**Keep done** where it used to offer **Mark done** again. It clears the note and leaves the review in
|
|
87
|
+
Done. Waiting reviews are unchanged: any new activity, a merge included, still brings them back.
|
|
88
|
+
|
|
3
89
|
## 0.59.50
|
|
4
90
|
|
|
5
91
|
**A click on the Architecture background clears the selection.** Clicking empty space in the
|
|
@@ -4343,6 +4343,11 @@ var ACTIVITY_LABELS = {
|
|
|
4343
4343
|
closed: "Closed",
|
|
4344
4344
|
reopened: "Reopened"
|
|
4345
4345
|
};
|
|
4346
|
+
/** An activity as the `data-activity-*` attributes carry it, so the pages can recompute the chip. */
|
|
4347
|
+
function activityAttributes(activity) {
|
|
4348
|
+
const moved = activity.movedAt === void 0 ? "" : ` data-activity-moved-at="${activity.movedAt}"`;
|
|
4349
|
+
return ` data-activity-at="${activity.at}" data-activity-kind="${activity.kind}"${moved}`;
|
|
4350
|
+
}
|
|
4346
4351
|
function activityLabel(kind) {
|
|
4347
4352
|
return ACTIVITY_LABELS[kind];
|
|
4348
4353
|
}
|
|
@@ -4361,10 +4366,21 @@ function sectionOf(lifecycle, activity) {
|
|
|
4361
4366
|
if (lifecycle.state === "waiting" && changedSince(lifecycle, activity)) return "active";
|
|
4362
4367
|
return lifecycle.state;
|
|
4363
4368
|
}
|
|
4364
|
-
/**
|
|
4369
|
+
/**
|
|
4370
|
+
* The chip that says why a card is where it is, or absent when its section already says it.
|
|
4371
|
+
*
|
|
4372
|
+
* Waiting is answered by any movement, a merge included: that is often what it was waiting for.
|
|
4373
|
+
* Done is answered only by what could change the verdict. A push after Done means the code is no
|
|
4374
|
+
* longer the code that was reviewed, even when the request merged afterwards. A reopen can make it
|
|
4375
|
+
* relevant again. A merge or close on its own is the request finishing after the review did, which
|
|
4376
|
+
* confirms Done rather than unsettling it.
|
|
4377
|
+
*/
|
|
4365
4378
|
function lifecycleChip(lifecycle, activity) {
|
|
4366
|
-
if (!lifecycle || !
|
|
4367
|
-
|
|
4379
|
+
if (!lifecycle || !activity) return void 0;
|
|
4380
|
+
if (lifecycle.state === "waiting") return changedSince(lifecycle, activity) ? "Changed while waiting" : void 0;
|
|
4381
|
+
if (activity.kind === "reopened" && activity.at > lifecycle.at) return "Reopened since done";
|
|
4382
|
+
const movedAt = activity.movedAt ?? (activity.kind === "updated" ? activity.at : void 0);
|
|
4383
|
+
return movedAt !== void 0 && movedAt > lifecycle.at ? "Changed since done" : void 0;
|
|
4368
4384
|
}
|
|
4369
4385
|
function changedSince(lifecycle, activity) {
|
|
4370
4386
|
return activity !== void 0 && activity.kind !== "created" && activity.at > lifecycle.at;
|
|
@@ -4381,6 +4397,15 @@ function offersLifecycle(target, lifecycle, activity) {
|
|
|
4381
4397
|
if (lifecycleChip(lifecycle, activity) !== void 0) return true;
|
|
4382
4398
|
return target !== (lifecycle?.state ?? "active");
|
|
4383
4399
|
}
|
|
4400
|
+
/**
|
|
4401
|
+
* A lifecycle item's words. The settle item on a changed Done review is "Keep done": "Mark done" on
|
|
4402
|
+
* something already Done reads as a no-op. Waiting keeps "Mark waiting", because a changed Waiting
|
|
4403
|
+
* review is drawn in Active, where parking it again is what the words already say.
|
|
4404
|
+
*/
|
|
4405
|
+
function lifecycleItemLabel(target, lifecycle, activity) {
|
|
4406
|
+
if (target === "done" && lifecycle?.state === "done" && lifecycleChip(lifecycle, activity) !== void 0) return "Keep done";
|
|
4407
|
+
return lifecycleAction(target);
|
|
4408
|
+
}
|
|
4384
4409
|
//#endregion
|
|
4385
4410
|
//#region ../../packages/review-harness/src/workspace/store.ts
|
|
4386
4411
|
var WORKSPACES_DIR = join(STORE_ROOT, "workspaces");
|
|
@@ -16127,4 +16152,4 @@ function lineageIds(id) {
|
|
|
16127
16152
|
return [.../* @__PURE__ */ new Set([id, ...lineage.map((review) => review.id)])];
|
|
16128
16153
|
}
|
|
16129
16154
|
//#endregion
|
|
16130
|
-
export { REPOSITORY_SCOPE as $, presentedKissRunOf as $n, reviewsUrl as $t, reanalyseReview as A, saveJob as An,
|
|
16155
|
+
export { REPOSITORY_SCOPE as $, presentedKissRunOf as $n, reviewsUrl as $t, reanalyseReview as A, saveJob as An, recommendationsOf as Ar, renderInlineText as At, RUNTIME_WORDS as B, followedRefName as Bn, clearAgentPreference as Br, removeWorktree as Bt, track as C, followedBranch as Cn, doneVerb as Cr, authorPreview as Ct, endRun as D, fail as Dn, questionsOutstanding as Dr, CODE_BLOCK_CLASS as Dt, completeRun as E, endedAt as En, issuesOutstanding as Er, renderMarkdown as Et, recordTelemetryUploadConsent as F, purposeOf as Fn, displayRef as Fr, MANAGED_ROOT as Ft, partFiles as G, kissDecisionsOf as Gn, AGENT_IDS as Gr, compactQueue as Gt, ARCHITECTURE_DIR as H, indexKeptIds as Hn, writeAgentPreference as Hr, modelHelpLines as Ht, telemetryUploadConsent as I, clearClaim as In, isCommitReview as Ir, createWorktree as It, storeArchitecture as J, lineagePosition as Jn, agentFor as Jr, readIndexToken as Jt, readArchitecture as K, latestKissRun as Kn, DEFAULT_AGENT_ID as Kr, queueForReview as Kt, waitingHistory as L, driverGone as Ln, git as Lr, holdWorktree as Lt, startJob as M, isLiveJob as Mn, WITHHELD_REASON as Mr, extractJsonText as Mt, readEvents as N, phasesFor as Nn, kissOutcome as Nr, objectWithAnyOf as Nt, reportRun as O, isTerminal as On, reviewerDispositions as Or, CODE_COPY_CLASS as Ot, record as P, progressSteps as Pn, resolveTarget as Pr, ReviewBeingDeletedError as Pt, QUOTE_LIMITS as Q, positionInLineage as Qn, readServerRecord as Qt, mapRuntimes as R, isClaimed as Rn, resolveAgent as Rr, isWorktreeHeld as Rt, isDriving as S, checkReview as Sn, readQueue as Sr, UNESTABLISHED_MOTIVATION as St, beginRun as T, allJobs as Tn, isQuestionOutstanding as Tr, GITHUB_MARKDOWN as Tt, checkArchitecture as U, indexReviewGroups as Un, CONFIG_PATH as Ur, relativeTime as Ut, describeRuntimes as V, groupByLineage as Vn, readAgentPreference as Vr, requestJobStop as Vt, loadArchitecture as W, kissDecisionRefusal as Wn, STORE_ROOT as Wr, activateQueued as Wt, trackedFiles as X, matchingWorkspaceIds as Xn, AgentCancelledError as Xr, clearServerRecordOwnedBy as Xt, storedScopes as Y, loadWorkspace as Yn, detectAgents as Yr, bootstrapUrl as Yt, ownersOf as Z, mutateWorkspace as Zn, AgentUnavailableError as Zr, ensureServer as Zt, liveUpdateFor as _, forgeResolver as _n, sectionOf as _r, removeNotification as _t, wasBlocked as a, writeServerRecord as an, touchWorkspace as ar, subjectOf as at, recordKissRun as b, fillFileUrlTemplate as bn, queueRemove as br, withUsageRecorded as bt, RefreshUnavailableError as c, feedbackUrl as cn, LIFECYCLES as cr, createPrUpdate as ct, mergeUpdateInto as d, MIN_WORKSPACE_PORT as dn, isLifecycle as dr, listNotifications as dt, serverEntryExists as en, previousKissResult as er, ancestorsOf as et, updateReview as f, parseWorkspacePort as fn, lifecycleChip as fr, markAllRead as ft, UpdateAlreadyRunningError as g, claimRequestUrl as gn, parseLifecycle as gr, readNotification as gt, askCheckout as h, writePortPreference as hn, offersLifecycle as hr, pruneNotifications as ht, liveJobsFor as i, workspaceUrl as in, summarise as ir, branchOf as it, runJob as j, PHASES as jn, describeAuthorship as jr, asString as jt, stopRun as k, loadJob as kn, processDiscussion as kr, escapeHtml as kt, cancelUpdate as l, DEFAULT_WORKSPACE_PORT as ln, activityAttributes as lr, eventName as lt, isUnchanged as m, statedWorkspacePort as mn, lifecyclePill as mr, markReadForReview as mt, deleteReview as n, stopChild as nn, reviewedCommit as nr, writeJsonAtomically as nt, discardJob as o, BUILD_VERSION as on, workspaceRevision as or, createArchitectureNotification as ot, refreshPrContext as p, resolveWorkspacePort as pn, lifecycleItemLabel as pr, markRead as pt, repositoryKey as q, lineageKeyFor as qn, agentById as qr, settleQueue as qt, lineageIds as r, stopServer as rn, reviewedRepositories as rr, announceJob as rt, FETCH_TIMEOUT_MS as s, PACKAGE_NAME as sn, workspaceStamps as sr, createPrState as st, deleteLineage as t, spawnServer as tn, recentWorkspaces as tr, isArchitectureId as tt, cancellableHere as u, MAX_WORKSPACE_PORT as un, activityLabel as ur, headline as ut, runningJobs as v, forgeFor as vn, queueAdd as vr, toneOf as vt, RUN_KINDS as w, reviewedShaOf as wn, isIssueOutstanding as wr, hasAuthorContent as wt, startKissJob as x, checkCodeFreshness as xn, queueStamp as xr, EXPLAIN_SIMPLY_PROMPT as xt, agentEnvOf as y, remoteHost as yn, queueAddMany as yr, unreadCount as yt, recordRuntimeBestEffort as z, decideKissRecommendation as zn, resolveModel as zr, readMarker as zt };
|
package/dist/main.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { $t as reviewsUrl, A as reanalyseReview, Bn as followedRefName,
|
|
2
|
+
import { $t as reviewsUrl, A as reanalyseReview, Bn as followedRefName, Bt as removeWorktree, F as recordTelemetryUploadConsent, Fn as purposeOf, Fr as displayRef, Ft as MANAGED_ROOT, Gr as AGENT_IDS, Hr as writeAgentPreference, Ht as modelHelpLines, I as telemetryUploadConsent, In as clearClaim, Jt as readIndexToken, Kr as DEFAULT_AGENT_ID, Kt as queueForReview, Ln as driverGone, Lr as git, M as startJob, Mr as WITHHELD_REASON, Nr as kissOutcome, On as isTerminal, P as record$1, Pn as progressSteps, Pr as resolveTarget, Qn as positionInLineage, Rn as isClaimed, Rr as resolveAgent, Sn as checkReview, Tn as allJobs, Ur as CONFIG_PATH, Ut as relativeTime, Vn as groupByLineage, Vr as readAgentPreference, Wr as STORE_ROOT, Xn as matchingWorkspaceIds, Yn as loadWorkspace, Yr as detectAgents, Yt as bootstrapUrl, Zn as mutateWorkspace, Zt as ensureServer, _ as liveUpdateFor, _n as forgeResolver, a as wasBlocked, b as recordKissRun, d as mergeUpdateInto, dn as MIN_WORKSPACE_PORT, f as updateReview, fn as parseWorkspacePort, g as UpdateAlreadyRunningError, hn as writePortPreference, i as liveJobsFor, in as workspaceUrl, ir as summarise, j as runJob, jn as PHASES, kn as loadJob, ln as DEFAULT_WORKSPACE_PORT, mn as statedWorkspacePort, n as deleteReview$1, on as BUILD_VERSION, qn as lineageKeyFor, qr as agentById, rn as stopServer, rr as reviewedRepositories, sn as PACKAGE_NAME, tr as recentWorkspaces, un as MAX_WORKSPACE_PORT, v as runningJobs, zr as resolveModel, zt as readMarker } from "./delete_review-LzUgEUzN.js";
|
|
3
3
|
import { basename, dirname, join, resolve } from "node:path";
|
|
4
4
|
import { spawn } from "node:child_process";
|
|
5
5
|
import { existsSync, mkdirSync, readdirSync, realpathSync, rmSync, statSync, writeFileSync } from "node:fs";
|
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
|
|
1
|
+
import { $ as REPOSITORY_SCOPE, $n as presentedKissRunOf, A as reanalyseReview, An as saveJob, Ar as recommendationsOf, At as renderInlineText, B as RUNTIME_WORDS, Bn as followedRefName, Br as clearAgentPreference, Bt as removeWorktree, C as track, Cn as followedBranch, Cr as doneVerb, Ct as authorPreview, D as endRun, Dn as fail, Dr as questionsOutstanding, Dt as CODE_BLOCK_CLASS, E as completeRun, En as endedAt, Er as issuesOutstanding, Et as renderMarkdown, F as recordTelemetryUploadConsent, Fn as purposeOf, Ft as MANAGED_ROOT, G as partFiles, Gn as kissDecisionsOf, Gr as AGENT_IDS, Gt as compactQueue, H as ARCHITECTURE_DIR, Hn as indexKeptIds, Hr as writeAgentPreference, I as telemetryUploadConsent, Ir as isCommitReview, It as createWorktree, J as storeArchitecture, Jn as lineagePosition, Jr as agentFor, Jt as readIndexToken, K as readArchitecture, Kn as latestKissRun, L as waitingHistory, Lr as git, Lt as holdWorktree, Mn as isLiveJob, Mr as WITHHELD_REASON, Mt as extractJsonText, N as readEvents, Nn as phasesFor, Nr as kissOutcome, Nt as objectWithAnyOf, O as reportRun, On as isTerminal, Or as reviewerDispositions, 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, Rt as isWorktreeHeld, S as isDriving, Sn as checkReview, Sr as readQueue, St as UNESTABLISHED_MOTIVATION, T as beginRun, Tn as allJobs, Tr as isQuestionOutstanding, Tt as GITHUB_MARKDOWN, U as checkArchitecture, Un as indexReviewGroups, Ut as relativeTime$1, V as describeRuntimes, Vn as groupByLineage, Vr as readAgentPreference, Vt as requestJobStop, W as loadArchitecture, Wn as kissDecisionRefusal, Wr as STORE_ROOT, Wt as activateQueued, X as trackedFiles, Xr as AgentCancelledError, Xt as clearServerRecordOwnedBy, Y as storedScopes, Yn as loadWorkspace, Z as ownersOf, Zn as mutateWorkspace, Zr as AgentUnavailableError, _ as liveUpdateFor, _r as sectionOf, _t as removeNotification, a as wasBlocked, an as writeServerRecord, ar as touchWorkspace, at as subjectOf, bn as fillFileUrlTemplate, br as queueRemove, 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 isLifecycle, 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 parseLifecycle, gt as readNotification, h as askCheckout, hn as writePortPreference, hr as offersLifecycle, ht as pruneNotifications, i as liveJobsFor, it as branchOf, j as runJob, jr as describeAuthorship, jt as asString, k as stopRun, kn as loadJob, kr as processDiscussion, kt as escapeHtml$1, l as cancelUpdate, ln as DEFAULT_WORKSPACE_PORT, lr as activityAttributes, lt as eventName, m as isUnchanged, mn as statedWorkspacePort, mr as lifecyclePill, 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 lifecycleItemLabel, pt as markRead, q as repositoryKey, 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 activityLabel, ut as headline, vn as forgeFor, vr as queueAdd, vt as toneOf, w as RUN_KINDS, wn as reviewedShaOf, wr as isIssueOutstanding, wt as hasAuthorContent, x as startKissJob, xn as checkCodeFreshness, xr as queueStamp, xt as EXPLAIN_SIMPLY_PROMPT, y as agentEnvOf, yn as remoteHost, yr as queueAddMany, yt as unreadCount$1, z as recordRuntimeBestEffort, zn as decideKissRecommendation, zr as resolveModel, zt as readMarker } from "./delete_review-LzUgEUzN.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(" · ")}</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(
|
|
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${[
|
|
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">⋯</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)
|
|
8435
|
-
|
|
8436
|
-
|
|
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.
|
|
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
|
|
8813
|
-
return `<details class="prb-index-section" data-section="${section}"${
|
|
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}"` : ""}
|
|
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 ? "★" : "☆"}</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(
|
|
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)}">⋯</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.
|
|
3
|
+
"version": "0.62.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{
|
|
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());
|
package/static/notifications.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
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());
|