prreviewbuddy 0.63.0 → 0.64.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +56 -0
- package/dist/{delete_review-CeJo9t7h.js → delete_review-l4p_p6oh.js} +102 -24
- package/dist/main.js +1 -1
- package/dist/server.js +314 -131
- package/package.json +1 -1
- package/static/chunk-CXf6hwXL.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 +189 -22
- package/static/workspace.js +84 -78
- package/static/chunk-CxNfDBSA.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,61 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.64.2
|
|
4
|
+
|
|
5
|
+
**Review state says whether you have reviewed a change, in those words.** On the Reviews page the
|
|
6
|
+
filter reads `Review state: All / Queue / Not reviewed / Reviewed`, and a card you have opened but
|
|
7
|
+
not marked says `Not reviewed` where it said `In progress`. The menus and the bulk bar say
|
|
8
|
+
`Mark not reviewed` for the way back. This is a separate question from where a review sits in
|
|
9
|
+
Active, Waiting and Done, so `Not reviewed` and `Done` together is a card you have put away
|
|
10
|
+
without marking it reviewed, not a contradiction.
|
|
11
|
+
|
|
12
|
+
`New` still marks a review you have never opened. The `Not reviewed` filter includes those as well,
|
|
13
|
+
because a review nobody has opened has not been reviewed either. Mark not reviewed from a review's
|
|
14
|
+
own page now always lands on `Not reviewed`, never back on `New`, as it already did from the list.
|
|
15
|
+
Links to the old filter keep working.
|
|
16
|
+
|
|
17
|
+
## 0.64.1
|
|
18
|
+
|
|
19
|
+
**The author filter names people.** On the Reviews page it reads `Author: Everyone`, like Status
|
|
20
|
+
and PR beside it, and lists each person by their GitHub name with their login beside it:
|
|
21
|
+
`Amy Li · @amy`. Someone with no public name on GitHub is listed by login alone. The list is in
|
|
22
|
+
alphabetical order of what you read, and if someone changes their name on GitHub the filter shows
|
|
23
|
+
the name from their newest review. Author and PR both carry the GitHub mark, because both are
|
|
24
|
+
answered from GitHub. Status is yours, so it has none.
|
|
25
|
+
|
|
26
|
+
## 0.64.0
|
|
27
|
+
|
|
28
|
+
**Choose the findings you want to raise, and copy them as one message.** Issues and Questions each
|
|
29
|
+
have a Prepare feedback button now. Press it and every card gets a checkbox; tick the ones you want
|
|
30
|
+
to take to the author. Your choices stay as you move between Issues and Questions, and a bar at the
|
|
31
|
+
foot of the review keeps count: `5 chosen · 2 issues · 3 questions`. Each count takes you back to
|
|
32
|
+
its list. The rail shows `2 chosen` under each. Clear empties your choice, and Done leaves it
|
|
33
|
+
altogether.
|
|
34
|
+
|
|
35
|
+
Prepare feedback in that bar opens your choices, large enough to read, issues first, then
|
|
36
|
+
questions, each in the order the review lists them. Preview shows the message as the author will
|
|
37
|
+
read it; Markdown shows the text behind it, to edit. They are one draft: an edit is in the preview
|
|
38
|
+
as soon as you switch back, and Copy Markdown copies what you edited. Each item starts as exactly
|
|
39
|
+
what that card's own Copy gives you: the finding, why it matters, and where it points. Severity and
|
|
40
|
+
status are left out, because they are how PR Review Buddy sorts findings for you, not part of what
|
|
41
|
+
you tell the author. Dismissing or answering a finding you chose leaves your draft exactly as you
|
|
42
|
+
left it. Change what you chose, even to take a tick back, and the draft is made again from the new
|
|
43
|
+
choice. Nothing is rewritten by AI.
|
|
44
|
+
|
|
45
|
+
A choice belongs to the review you made it on. Another review starts with none, and reloading the
|
|
46
|
+
page starts over. Dismiss and Mark answered work as before, while choosing or not.
|
|
47
|
+
|
|
48
|
+
Lists are drawn as GitHub draws them, in the feedback preview and in Buddy AI's answers. A list
|
|
49
|
+
with blank lines between its items is one list, numbered on from its first number. A paragraph
|
|
50
|
+
indented under an item stays in that item, and a list indented under an item is drawn inside it,
|
|
51
|
+
one level deep, with its own paragraphs. What counts is how far a line is indented under its item,
|
|
52
|
+
so a list indented the same throughout is still one list. Before, each item after a blank line was
|
|
53
|
+
numbered 1, and a nested list was drawn as more items of the outer one, so a finding with numbered
|
|
54
|
+
steps of its own previewed them as further findings.
|
|
55
|
+
|
|
56
|
+
KISS's Copy draft comment and Copy recommendations now say Copied in their own words after a
|
|
57
|
+
click, and then go back to their names. Before, the first click left them as a bare icon.
|
|
58
|
+
|
|
3
59
|
## 0.63.0
|
|
4
60
|
|
|
5
61
|
**Telemetry now records first use.** With telemetry on, PR Review Buddy sends one more event,
|
|
@@ -4278,7 +4278,7 @@ function normalise(ids) {
|
|
|
4278
4278
|
* What happens next with a change, as the reviewer says it: still in play, parked until something
|
|
4279
4279
|
* moves, or finished with.
|
|
4280
4280
|
*
|
|
4281
|
-
* A separate axis from New /
|
|
4281
|
+
* A separate axis from New / Not reviewed / Reviewed, which says what the reviewer has *done*. A
|
|
4282
4282
|
* change can be reviewed and waiting for another push, or reviewed and done, and one field cannot
|
|
4283
4283
|
* hold both answers.
|
|
4284
4284
|
*
|
|
@@ -4988,7 +4988,8 @@ function summarise(workspace) {
|
|
|
4988
4988
|
prNumber: workspace.changeSet.data.pullRequest?.number || workspace.prContext?.pullRequest.number,
|
|
4989
4989
|
commitSha: workspace.session.metadata?.commitSha || (workspace.changeSet.targetType === "commit" ? workspace.changeSet.data.pullRequest.head.sha : "") || void 0,
|
|
4990
4990
|
author: describeAuthorship(workspace.changeSet, workspace.prContext?.pullRequest)?.label,
|
|
4991
|
-
authorHandle: workspace.prContext?.pullRequest.author?.handle || void 0
|
|
4991
|
+
authorHandle: workspace.prContext?.pullRequest.author?.handle || void 0,
|
|
4992
|
+
authorName: workspace.prContext?.pullRequest.author?.name || void 0
|
|
4992
4993
|
};
|
|
4993
4994
|
}
|
|
4994
4995
|
/**
|
|
@@ -10260,16 +10261,57 @@ function diagramFigure(code, label) {
|
|
|
10260
10261
|
const id = `prb-md-mermaid-source-${++diagramCount}`;
|
|
10261
10262
|
return `<figure class="prb-md-mermaid" data-md-mermaid data-state="source"><div class="prb-md-mermaid-canvas" data-md-mermaid-canvas role="img" aria-label="${escapeHtml(label)}" hidden></div><p class="prb-md-mermaid-error" data-md-mermaid-error hidden>This diagram couldn\u2019t be displayed.</p><button type="button" class="prb-md-mermaid-toggle" data-md-mermaid-toggle aria-expanded="true" aria-controls="${id}" hidden>Hide source</button>` + codeBlock(code, "Copy source", "Copy source", ` id="${id}" data-md-mermaid-source`) + `</figure>`;
|
|
10262
10263
|
}
|
|
10264
|
+
/**
|
|
10265
|
+
* The column after `whitespace`, written from column `from`. A tab moves to the next multiple of
|
|
10266
|
+
* four, as CommonMark's tab stops do, so "-\t" and "- " both put text at column 2 and 4 alike.
|
|
10267
|
+
*/
|
|
10268
|
+
function columnAfter(whitespace, from = 0) {
|
|
10269
|
+
let column = from;
|
|
10270
|
+
for (const char of whitespace) column = char === " " ? column + 4 - column % 4 : column + 1;
|
|
10271
|
+
return column;
|
|
10272
|
+
}
|
|
10273
|
+
/** How far a line is indented, in columns. */
|
|
10274
|
+
function indentOf(raw) {
|
|
10275
|
+
return columnAfter(raw.match(/^[ \t]*/)[0]);
|
|
10276
|
+
}
|
|
10277
|
+
/**
|
|
10278
|
+
* A list marker line: its kind, an ordered one's number, its text, and its content column, where a
|
|
10279
|
+
* line has to start to belong inside the item. Spaces or tabs may follow the marker, counted to tab
|
|
10280
|
+
* stops. Five or more columns of them make the text an indented code line in CommonMark, so content
|
|
10281
|
+
* then sits one column after the marker.
|
|
10282
|
+
*/
|
|
10283
|
+
function markerOf(raw) {
|
|
10284
|
+
const match = raw.match(/^([ \t]*)(?:([-*+])|(\d{1,9})[.)])([ \t]+)(\S.*)$/);
|
|
10285
|
+
if (!match) return null;
|
|
10286
|
+
const [, lead, bullet, number, gap, text] = match;
|
|
10287
|
+
const afterMarker = columnAfter(lead) + (bullet ? 1 : number.length + 1);
|
|
10288
|
+
const afterGap = columnAfter(gap, afterMarker);
|
|
10289
|
+
return {
|
|
10290
|
+
tag: bullet ? "ul" : "ol",
|
|
10291
|
+
start: bullet ? 1 : Number(number),
|
|
10292
|
+
text: text.trim(),
|
|
10293
|
+
content: afterGap - afterMarker > 4 ? afterMarker + 1 : afterGap
|
|
10294
|
+
};
|
|
10295
|
+
}
|
|
10263
10296
|
function renderBlocks(text, lifted) {
|
|
10264
10297
|
const out = [];
|
|
10265
10298
|
let paragraph = [];
|
|
10266
10299
|
let quote = [];
|
|
10267
10300
|
let list = null;
|
|
10301
|
+
const startAttr = (l) => l.tag === "ol" && l.start !== 1 ? ` start="${l.start}"` : "";
|
|
10268
10302
|
let html = null;
|
|
10269
10303
|
const flush = () => {
|
|
10270
10304
|
if (paragraph.length) out.push(`<p>${renderInline(paragraph.join(" "), lifted)}</p>`);
|
|
10271
10305
|
if (quote.length) out.push(`<blockquote>${renderInline(quote.join(" "), lifted)}</blockquote>`);
|
|
10272
|
-
if (list)
|
|
10306
|
+
if (list) {
|
|
10307
|
+
const paragraphs = (texts) => texts.length === 1 ? renderInline(texts[0], lifted) : texts.map((text) => `<p>${renderInline(text, lifted)}</p>`).join("");
|
|
10308
|
+
const nested = (l) => `<${l.tag}${startAttr(l)}>${l.items.map((item) => `<li>${paragraphs(item.paras)}</li>`).join("")}</${l.tag}>`;
|
|
10309
|
+
const item = ({ blocks }) => {
|
|
10310
|
+
const inline = blocks.filter((block) => typeof block === "string").length === 1;
|
|
10311
|
+
return blocks.map((block) => typeof block !== "string" ? nested(block) : inline ? renderInline(block, lifted) : `<p>${renderInline(block, lifted)}</p>`).join("");
|
|
10312
|
+
};
|
|
10313
|
+
out.push(`<${list.tag}${startAttr(list)}>${list.items.map((entry) => `<li>${item(entry)}</li>`).join("")}</${list.tag}>`);
|
|
10314
|
+
}
|
|
10273
10315
|
paragraph = [];
|
|
10274
10316
|
quote = [];
|
|
10275
10317
|
list = null;
|
|
@@ -10285,9 +10327,45 @@ function renderBlocks(text, lifted) {
|
|
|
10285
10327
|
html = null;
|
|
10286
10328
|
}
|
|
10287
10329
|
if (!line) {
|
|
10288
|
-
|
|
10330
|
+
if (list && !paragraph.length && !quote.length) list.gap = true;
|
|
10331
|
+
else flush();
|
|
10289
10332
|
continue;
|
|
10290
10333
|
}
|
|
10334
|
+
if (list?.items.length) {
|
|
10335
|
+
const item = list.items[list.items.length - 1];
|
|
10336
|
+
const tail = item.blocks[item.blocks.length - 1];
|
|
10337
|
+
const inner = typeof tail === "string" ? null : tail;
|
|
10338
|
+
const innerItem = inner?.items[inner.items.length - 1] ?? null;
|
|
10339
|
+
const indent = indentOf(raw);
|
|
10340
|
+
const marker = markerOf(raw);
|
|
10341
|
+
const gap = list.gap;
|
|
10342
|
+
list.gap = false;
|
|
10343
|
+
if (marker && indent >= item.content) {
|
|
10344
|
+
const joins = inner && innerItem && (indent >= innerItem.content || inner.tag === marker.tag);
|
|
10345
|
+
const entry = {
|
|
10346
|
+
paras: [marker.text],
|
|
10347
|
+
content: marker.content
|
|
10348
|
+
};
|
|
10349
|
+
if (joins) inner.items.push(entry);
|
|
10350
|
+
else item.blocks.push({
|
|
10351
|
+
tag: marker.tag,
|
|
10352
|
+
start: marker.start,
|
|
10353
|
+
items: [entry]
|
|
10354
|
+
});
|
|
10355
|
+
continue;
|
|
10356
|
+
}
|
|
10357
|
+
if (!marker && gap) {
|
|
10358
|
+
if (innerItem && indent >= innerItem.content) {
|
|
10359
|
+
innerItem.paras.push(line);
|
|
10360
|
+
continue;
|
|
10361
|
+
}
|
|
10362
|
+
if (indent >= item.content) {
|
|
10363
|
+
item.blocks.push(line);
|
|
10364
|
+
continue;
|
|
10365
|
+
}
|
|
10366
|
+
flush();
|
|
10367
|
+
} else if (marker && gap && marker.tag !== list.tag) flush();
|
|
10368
|
+
}
|
|
10291
10369
|
if (lifted && startsHtmlBlock(line, lifted)) {
|
|
10292
10370
|
flush();
|
|
10293
10371
|
html = [escapeHtml(line)];
|
|
@@ -10310,28 +10388,22 @@ function renderBlocks(text, lifted) {
|
|
|
10310
10388
|
out.push(`<h${level}>${renderInline(heading[2], lifted)}</h${level}>`);
|
|
10311
10389
|
continue;
|
|
10312
10390
|
}
|
|
10313
|
-
const
|
|
10314
|
-
if (
|
|
10315
|
-
|
|
10391
|
+
const marker = markerOf(raw);
|
|
10392
|
+
if (marker) {
|
|
10393
|
+
let open = list;
|
|
10394
|
+
if (open?.tag !== marker.tag) {
|
|
10316
10395
|
flush();
|
|
10317
|
-
list = {
|
|
10318
|
-
tag:
|
|
10319
|
-
|
|
10396
|
+
open = list = {
|
|
10397
|
+
tag: marker.tag,
|
|
10398
|
+
start: marker.start,
|
|
10399
|
+
items: [],
|
|
10400
|
+
gap: false
|
|
10320
10401
|
};
|
|
10321
10402
|
}
|
|
10322
|
-
|
|
10323
|
-
|
|
10324
|
-
|
|
10325
|
-
|
|
10326
|
-
if (ordered) {
|
|
10327
|
-
if (list?.tag !== "ol") {
|
|
10328
|
-
flush();
|
|
10329
|
-
list = {
|
|
10330
|
-
tag: "ol",
|
|
10331
|
-
items: []
|
|
10332
|
-
};
|
|
10333
|
-
}
|
|
10334
|
-
list.items.push(ordered[1]);
|
|
10403
|
+
open.items.push({
|
|
10404
|
+
blocks: [marker.text],
|
|
10405
|
+
content: marker.content
|
|
10406
|
+
});
|
|
10335
10407
|
continue;
|
|
10336
10408
|
}
|
|
10337
10409
|
const quoted = line.match(/^>\s?(.*)$/);
|
|
@@ -10341,7 +10413,13 @@ function renderBlocks(text, lifted) {
|
|
|
10341
10413
|
continue;
|
|
10342
10414
|
}
|
|
10343
10415
|
if (list && list.items.length) {
|
|
10344
|
-
list.items[list.items.length - 1]
|
|
10416
|
+
const { blocks } = list.items[list.items.length - 1];
|
|
10417
|
+
const last = blocks[blocks.length - 1];
|
|
10418
|
+
if (typeof last === "string") blocks[blocks.length - 1] = `${last} ${line}`;
|
|
10419
|
+
else {
|
|
10420
|
+
const paras = last.items[last.items.length - 1].paras;
|
|
10421
|
+
paras[paras.length - 1] += ` ${line}`;
|
|
10422
|
+
}
|
|
10345
10423
|
continue;
|
|
10346
10424
|
}
|
|
10347
10425
|
if (quote.length) {
|
package/dist/main.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { $n as loadWorkspace, $r as detectAgents, $t as bootstrapUrl, A as reanalyseReview, B as telemetryUploadEnabled, Bn as clearClaim, En as checkReview, F as record$1, Fn as PHASES, Gn as groupByLineage, Gr as readAgentPreference, Hn as isClaimed, Hr as resolveAgent, I as stamp, Ir as WITHHELD_REASON, Jr as STORE_ROOT, Kr as writeAgentPreference, Kt as modelHelpLines, L as deliver, Lr as kissOutcome, M as startJob, Mn as isTerminal, N as append, Nn as loadJob, Qt as readIndexToken, R as recordTelemetryUploadConsent, Rn as progressSteps, Rr as resolveTarget, Ur as resolveModel, Ut as readMarker, Vn as driverGone, Vr as git, Wn as followedRefName, Wt as removeWorktree, Xr as DEFAULT_AGENT_ID, Xt as queueForReview, Yr as AGENT_IDS, Zn as lineageKeyFor, Zr as agentById, _ as liveUpdateFor, a as wasBlocked, ar as recentWorkspaces, b as recordKissRun, cn as workspaceUrl, cr as summarise, d as mergeUpdateInto, dn as PACKAGE_NAME, er as matchingWorkspaceIds, f as updateReview, g as UpdateAlreadyRunningError, gn as parseWorkspacePort, hn as MIN_WORKSPACE_PORT, i as liveJobsFor, j as runJob, kn as allJobs, mn as MAX_WORKSPACE_PORT, n as deleteReview$1, nr as positionInLineage, pn as DEFAULT_WORKSPACE_PORT, qr as CONFIG_PATH, qt as relativeTime, rn as reviewsUrl, sn as stopServer, sr as reviewedRepositories, tn as ensureServer, tr as mutateWorkspace, un as BUILD_VERSION, v as runningJobs, vn as statedWorkspacePort, xn as forgeResolver, yn as writePortPreference, z as telemetryUploadConsent, zn as purposeOf, zr as displayRef, zt as MANAGED_ROOT } from "./delete_review-
|
|
2
|
+
import { $n as loadWorkspace, $r as detectAgents, $t as bootstrapUrl, A as reanalyseReview, B as telemetryUploadEnabled, Bn as clearClaim, En as checkReview, F as record$1, Fn as PHASES, Gn as groupByLineage, Gr as readAgentPreference, Hn as isClaimed, Hr as resolveAgent, I as stamp, Ir as WITHHELD_REASON, Jr as STORE_ROOT, Kr as writeAgentPreference, Kt as modelHelpLines, L as deliver, Lr as kissOutcome, M as startJob, Mn as isTerminal, N as append, Nn as loadJob, Qt as readIndexToken, R as recordTelemetryUploadConsent, Rn as progressSteps, Rr as resolveTarget, Ur as resolveModel, Ut as readMarker, Vn as driverGone, Vr as git, Wn as followedRefName, Wt as removeWorktree, Xr as DEFAULT_AGENT_ID, Xt as queueForReview, Yr as AGENT_IDS, Zn as lineageKeyFor, Zr as agentById, _ as liveUpdateFor, a as wasBlocked, ar as recentWorkspaces, b as recordKissRun, cn as workspaceUrl, cr as summarise, d as mergeUpdateInto, dn as PACKAGE_NAME, er as matchingWorkspaceIds, f as updateReview, g as UpdateAlreadyRunningError, gn as parseWorkspacePort, hn as MIN_WORKSPACE_PORT, i as liveJobsFor, j as runJob, kn as allJobs, mn as MAX_WORKSPACE_PORT, n as deleteReview$1, nr as positionInLineage, pn as DEFAULT_WORKSPACE_PORT, qr as CONFIG_PATH, qt as relativeTime, rn as reviewsUrl, sn as stopServer, sr as reviewedRepositories, tn as ensureServer, tr as mutateWorkspace, un as BUILD_VERSION, v as runningJobs, vn as statedWorkspacePort, xn as forgeResolver, yn as writePortPreference, z as telemetryUploadConsent, zn as purposeOf, zr as displayRef, zt as MANAGED_ROOT } from "./delete_review-l4p_p6oh.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";
|