prreviewbuddy 0.25.8 → 0.25.13
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/main.js +58 -7
- package/dist/{relative_time-D760FOL9.js → relative_time-vn8Ex9E8.js} +395 -80
- package/dist/server.js +312 -42
- package/package.json +1 -1
- package/static/chunk-B80S6zbH.js +4 -4
- package/static/chunk-CIsM3PMS.js +1 -0
- package/static/{chunk-B9H2wUlQ.js → chunk-gBDI1-Cy.js} +1 -1
- package/static/reviews.js +1 -1
- package/static/settings.js +1 -1
- package/static/shell.css +48 -0
- package/static/workspace.js +44 -44
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,91 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.25.13
|
|
4
|
+
|
|
5
|
+
**Two updates of the same review no longer run over each other.** Pressing **Update review** on the
|
|
6
|
+
page while `prreviewbuddy review --update` was working on the same review started a second update
|
|
7
|
+
alongside the first. Whichever finished last replaced the other's result without a word, after
|
|
8
|
+
both had spent minutes of agent time.
|
|
9
|
+
|
|
10
|
+
A second update is now refused while one is running, from wherever it was asked for. On the page,
|
|
11
|
+
the review reloads onto the running update's steps. In the terminal, the command says the review
|
|
12
|
+
is already being updated, gives the link where you can follow it, and exits without changing
|
|
13
|
+
anything. An analysis, a KISS review or a question to the assistant does not block an update.
|
|
14
|
+
|
|
15
|
+
## 0.25.12
|
|
16
|
+
|
|
17
|
+
**An update shows what it is doing, in the terminal and on the review.** `prreviewbuddy review
|
|
18
|
+
--update` printed nothing until the reassessment was over, usually minutes after you typed it, and
|
|
19
|
+
the review page showed nothing either. Only the reviews list noticed, and it called the whole update
|
|
20
|
+
"Preparing isolated checkout".
|
|
21
|
+
|
|
22
|
+
The command now prints the link straight away and then draws the same step list a new review does:
|
|
23
|
+
fetching the latest commits, re-reading the pull request conversation, preparing a checkout of the
|
|
24
|
+
new commits, and reassessing the review, with the agent's own notes under the step that is running.
|
|
25
|
+
Open the link while it works and those steps tick over above the review, which stays readable
|
|
26
|
+
underneath until the update lands. The page refreshes onto the result when it finishes, and the
|
|
27
|
+
reviews list names each step in the same words.
|
|
28
|
+
|
|
29
|
+
An update that finds no new commits stops after the fetch and says so, without ticking steps it
|
|
30
|
+
never ran. **Update review** on the page now shows the same live steps, where it used to show
|
|
31
|
+
captions guessed from a timer.
|
|
32
|
+
|
|
33
|
+
`--reanalyse` kept the terminal silent in the same way, for a whole analysis, and now draws its
|
|
34
|
+
progress too.
|
|
35
|
+
|
|
36
|
+
## 0.25.11
|
|
37
|
+
|
|
38
|
+
**A review with nothing committed to read now says why, straight away.** Running
|
|
39
|
+
`prreviewbuddy review` on `main` with a dozen edited files said "No changes found to review",
|
|
40
|
+
which looked like a bug to anyone who could see the edits. It now says there are no *committed*
|
|
41
|
+
changes, counts the uncommitted ones (new files included), and explains that PR Review Buddy
|
|
42
|
+
reviews a fixed snapshot of your code, so work that is not committed yet is not included. Then
|
|
43
|
+
it tells you what to do: commit on a branch, or just commit if you are already on one.
|
|
44
|
+
|
|
45
|
+
The refusal also comes at once. It used to arrive after an isolated checkout had been prepared,
|
|
46
|
+
reported as a paused review that would refuse again every time you tried to carry it on. Nothing
|
|
47
|
+
is created now. A branch that has since been merged still opens the review it already has.
|
|
48
|
+
|
|
49
|
+
## 0.25.10
|
|
50
|
+
|
|
51
|
+
**The reviews list now shows what is happening, and keeps showing it.** A review being analysed
|
|
52
|
+
right now, one whose analysis failed, and one that was never analysed all looked the same on the
|
|
53
|
+
list: every card said "No standard review yet". Start a review, go back to the list, and you
|
|
54
|
+
watched nothing happen for three minutes.
|
|
55
|
+
|
|
56
|
+
A card now says which step an analysis has reached, in the same words the terminal prints, and says
|
|
57
|
+
when one has stopped. It updates on its own, so a review that finishes while you are looking at the
|
|
58
|
+
list fills in its summary, risk and counts without you touching anything. A review started in
|
|
59
|
+
another terminal appears by itself too.
|
|
60
|
+
|
|
61
|
+
Where a review already has results, they stay put while a new analysis runs over them: a KISS run
|
|
62
|
+
no longer hides the issues you were reading.
|
|
63
|
+
|
|
64
|
+
The list checks in about once a second while something is being made and once every fifteen when
|
|
65
|
+
nothing is, and it waits rather than refreshing under you if you have rows ticked or are partway
|
|
66
|
+
through typing a search.
|
|
67
|
+
|
|
68
|
+
## 0.25.9
|
|
69
|
+
|
|
70
|
+
**Marking a review reviewed shows up straight away on the reviews list.** It used to keep saying
|
|
71
|
+
what it had said before, and catch up some minutes later on its own. Nothing was actually stale:
|
|
72
|
+
the mark is written to disk before the button finishes repainting, and the list is rebuilt from
|
|
73
|
+
those files on every request. The browser simply stopped asking. No page this server sends had
|
|
74
|
+
ever carried a caching rule, so a browser was free to reuse the copy it already had, and pressing
|
|
75
|
+
Back does not reload a page at all: it restores a frozen one from memory, JavaScript variables and
|
|
76
|
+
all, without a single request.
|
|
77
|
+
|
|
78
|
+
Both doors are shut now, and shut in one place rather than per page. Every response describing a
|
|
79
|
+
review, HTML and JSON alike, says it must not be stored, and that is a property of the two helpers
|
|
80
|
+
that write responses rather than something each route remembers. Every page now reloads itself
|
|
81
|
+
when the browser restores it from history, because a restored page may be stale in any of its
|
|
82
|
+
parts and not only the one that prompted this.
|
|
83
|
+
|
|
84
|
+
Assets went the other way, which is the arrangement they should always have had. The bundles whose
|
|
85
|
+
filenames carry a content hash, which are most of what a page downloads, may now be kept
|
|
86
|
+
indefinitely: a new build asks for different names. The handful named plainly still check in every
|
|
87
|
+
time, because those names survive an upgrade.
|
|
88
|
+
|
|
3
89
|
## 0.25.8
|
|
4
90
|
|
|
5
91
|
**A review that fails says so, instead of reporting itself as ready.** An analysis that failed
|
package/dist/main.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
2
|
+
import { A as liveUpdateFor, B as recordTelemetryUploadConsent, Bt as displayRef, C as writePortPreference, Ct as recentWorkspaces, Dt as summarise, Et as saveWorkspace, F as reanalyseReview, Gt as writeAgentPreference, H as BUILD_VERSION, Ht as agentIdOf, I as runJob, Jt as AGENT_IDS, Kt as CONFIG_PATH, L as startJob, N as recordKissRun, Q as removeWorktree, Qt as detectAgents, S as statedWorkspacePort, T as updateReview, Tt as reviewedRepositories, U as PACKAGE_NAME, V as telemetryUploadConsent, Vt as git, Wt as readAgentPreference, X as MANAGED_ROOT, Xt as agentById, Yt as DEFAULT_AGENT_ID, Z as readMarker, _ as DEFAULT_WORKSPACE_PORT, a as liveJobsFor, at as loadJob, b as parseWorkspacePort, bt as positionInLineage, c as readIndexToken, d as ensureServer, dt as clearClaim, et as checkFreshness, ft as isClaimed, gt as lineageKeyFor, h as workspaceUrl, it as isTerminal, j as runningJobs, k as UpdateAlreadyRunningError, l as bootstrapUrl, lt as progressSteps, m as stopServer, mt as groupByLineage, o as wasBlocked, p as reviewsUrl, pt as followedRefName, q as forgeResolver, qt as STORE_ROOT, r as deleteReview$1, st as PHASES, t as relativeTime, tt as allJobs, ut as purposeOf, v as MAX_WORKSPACE_PORT, vt as loadWorkspace, y as MIN_WORKSPACE_PORT, yt as matchingWorkspaceIds, z as record, zt as resolveTarget } from "./relative_time-vn8Ex9E8.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";
|
|
@@ -1267,6 +1267,19 @@ function agentUnusedByResume(agentId) {
|
|
|
1267
1267
|
* link. Not rephrased here: an update that stopped early has a specific reason and the reviewer
|
|
1268
1268
|
* gets the same reason whichever surface asked for it.
|
|
1269
1269
|
*/
|
|
1270
|
+
/**
|
|
1271
|
+
* Said before the update starts, so the command answers at once and the link is there to open while
|
|
1272
|
+
* it works. The same label the creation path uses, because it is the same offer.
|
|
1273
|
+
*
|
|
1274
|
+
* Not "continues if this terminal closes", which the creation path can say and this cannot: the
|
|
1275
|
+
* update runs in this process, so closing the terminal stops it.
|
|
1276
|
+
*/
|
|
1277
|
+
function startedUpdate(url, acted) {
|
|
1278
|
+
return `${subjectLine(acted)}\nOpen workspace now ${url}`;
|
|
1279
|
+
}
|
|
1280
|
+
function updateAlreadyRunning(url, acted) {
|
|
1281
|
+
return `${subjectLine(acted)}\nThis review is already being updated. Follow it here ${url}`;
|
|
1282
|
+
}
|
|
1270
1283
|
function updateFinished(outcome, url, acted) {
|
|
1271
1284
|
return `${subjectLine(acted)}\n${outcome.message}\n${url}`;
|
|
1272
1285
|
}
|
|
@@ -1572,10 +1585,10 @@ var GREEN = "\x1B[32m";
|
|
|
1572
1585
|
var RED = "\x1B[31m";
|
|
1573
1586
|
var RESET = "\x1B[0m";
|
|
1574
1587
|
/** The header above the phases: what is being reviewed, and the facts about how. */
|
|
1575
|
-
function header(target, colour) {
|
|
1588
|
+
function header(target, colour, purpose = "review") {
|
|
1576
1589
|
const meta = `${target.sha.slice(0, 7)} · isolated checkout · ${target.originRepoPath}`;
|
|
1577
1590
|
return [
|
|
1578
|
-
|
|
1591
|
+
`${purpose === "update" ? "Updating" : "Reviewing"} ${target.branch}`,
|
|
1579
1592
|
colour ? `${DIM}${meta}${RESET}` : meta,
|
|
1580
1593
|
""
|
|
1581
1594
|
];
|
|
@@ -1638,7 +1651,7 @@ function followJob(jobId, target, options = {}) {
|
|
|
1638
1651
|
const paint = () => {
|
|
1639
1652
|
const job = read(jobId);
|
|
1640
1653
|
if (!job) return;
|
|
1641
|
-
const lines = [...header(target, colour), ...phaseLines(job, colour)];
|
|
1654
|
+
const lines = [...header(job.target ?? target, colour, purposeOf(job)), ...phaseLines(job, colour)];
|
|
1642
1655
|
const block = lines.join("\n");
|
|
1643
1656
|
if (block === last) return;
|
|
1644
1657
|
if (inPlace && drawn > 0) stream.write(`\u001b[${drawn}A\u001b[0J`);
|
|
@@ -1851,13 +1864,38 @@ async function operate(command, workspace) {
|
|
|
1851
1864
|
if (command.operation === "reanalyse") {
|
|
1852
1865
|
const agent = await chooseFor(command, workspace);
|
|
1853
1866
|
if (!agent) return 1;
|
|
1854
|
-
|
|
1867
|
+
let stopReanalysis;
|
|
1868
|
+
try {
|
|
1869
|
+
await reanalyseReview(workspace.id, agent.id, (jobId) => {
|
|
1870
|
+
stopReanalysis = follow(jobId);
|
|
1871
|
+
});
|
|
1872
|
+
} finally {
|
|
1873
|
+
stopReanalysis?.();
|
|
1874
|
+
}
|
|
1855
1875
|
const port = await ensureServer();
|
|
1856
1876
|
out(reanalysed(agent.displayName, linkTo(port, workspace.id, workspace.token), actedOn(workspace)));
|
|
1857
1877
|
return 0;
|
|
1858
1878
|
}
|
|
1859
1879
|
if (command.agentId) err(agentUnusedByUpdate(command.agentId));
|
|
1860
|
-
const
|
|
1880
|
+
const url = linkTo(await ensureServer(), workspace.id, workspace.token);
|
|
1881
|
+
if (liveUpdateFor(workspace.id)) {
|
|
1882
|
+
out(updateAlreadyRunning(url, actedOn(workspace)));
|
|
1883
|
+
return 1;
|
|
1884
|
+
}
|
|
1885
|
+
out(startedUpdate(url, actedOn(workspace)));
|
|
1886
|
+
let stopUpdate;
|
|
1887
|
+
let outcome;
|
|
1888
|
+
try {
|
|
1889
|
+
outcome = await updateReview(workspace, { onStarted: (jobId) => {
|
|
1890
|
+
stopUpdate = follow(jobId);
|
|
1891
|
+
} });
|
|
1892
|
+
} catch (error) {
|
|
1893
|
+
if (!(error instanceof UpdateAlreadyRunningError)) throw error;
|
|
1894
|
+
out(updateAlreadyRunning(url, actedOn(workspace)));
|
|
1895
|
+
return 1;
|
|
1896
|
+
} finally {
|
|
1897
|
+
stopUpdate?.();
|
|
1898
|
+
}
|
|
1861
1899
|
workspace.lastUpdate = outcome;
|
|
1862
1900
|
saveWorkspace(workspace);
|
|
1863
1901
|
record({
|
|
@@ -1872,10 +1910,23 @@ async function operate(command, workspace) {
|
|
|
1872
1910
|
newIssues: outcome.counts?.newIssues ?? 0,
|
|
1873
1911
|
questionsAnswered: outcome.counts?.questionsAnswered ?? 0
|
|
1874
1912
|
});
|
|
1875
|
-
out(updateFinished(outcome,
|
|
1913
|
+
out(updateFinished(outcome, url, actedOn(workspace)));
|
|
1876
1914
|
return 0;
|
|
1877
1915
|
}
|
|
1878
1916
|
/**
|
|
1917
|
+
* Draw a job's progress block, from what the job itself records about its target.
|
|
1918
|
+
*
|
|
1919
|
+
* From the record rather than the caller, for the reason `drive` gives: the job knows what it is
|
|
1920
|
+
* working on, and a second copy assembled here could disagree with it.
|
|
1921
|
+
*/
|
|
1922
|
+
function follow(jobId) {
|
|
1923
|
+
return followJob(jobId, loadJob(jobId)?.target ?? {
|
|
1924
|
+
branch: "",
|
|
1925
|
+
sha: "",
|
|
1926
|
+
originRepoPath: ""
|
|
1927
|
+
});
|
|
1928
|
+
}
|
|
1929
|
+
/**
|
|
1879
1930
|
* What to call the review an operation acted on.
|
|
1880
1931
|
*
|
|
1881
1932
|
* Read off the record rather than off the command, because the two are not the same question. The
|