prreviewbuddy 0.45.0 → 0.48.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 CHANGED
@@ -1,5 +1,96 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.48.0
4
+
5
+ **Active, Waiting and Done.** A review can now be marked **Waiting**, for when you have done your
6
+ pass and expect another round, or **Done**, for when you are finished with it. The reviews list keeps
7
+ your active reviews at the top, with **Waiting** below them and **Done** below that, folded away. Use
8
+ the **⋯** menu on a card, or select several and use the bar at the bottom. **Move to active** puts a
9
+ review back. This is separate from **Reviewed**, which still records that you have been through it.
10
+
11
+ **Waiting reviews come back when something changes.** If a Waiting review gets new commits, or its
12
+ pull request is merged, closed or reopened, it shows up in the main list again marked **Changed while
13
+ waiting**. Marking it Waiting again puts it back. A Done review never comes back by itself; if it
14
+ changes, it is marked **Changed since done** where it is. Marking a review Waiting starts watching
15
+ it straight away, so a push made soon after still brings it back. Adding a Waiting or Done review to
16
+ your review queue moves it back to Active.
17
+
18
+ **The list no longer reorders when you open a review.** Reviews are ordered by what last happened to
19
+ the change: when it was analysed, when new commits arrived, or when the pull request was merged,
20
+ closed or reopened. The time on each card now says which of those it was, for example "Updated
21
+ 2 hours ago" or "Merged 1 day ago". Saved reviews still come first.
22
+
23
+ **Load more instead of pages.** Each section shows fifteen reviews and a **Load more** button for the
24
+ rest. Search and the filters still cover every review, in all three sections.
25
+
26
+ **Done reviews are kept longer.** Like saved reviews, Done reviews are kept for ninety days rather
27
+ than thirty, counting from the last time you opened or marked them.
28
+
29
+ **Light mode.** The workspace now has a light theme as well as the dark one. The rail, the top bars,
30
+ Buddy AI, the reviews list, Notifications and Settings are drawn in pale greys around a white
31
+ review, so the review stays the brightest thing on the screen. Purple is kept for what you have
32
+ chosen and for the main action, as a pale tint rather than a solid block.
33
+
34
+ **Follows your device, or stays put.** Settings has a new **Appearance** section with **System**,
35
+ **Light** and **Dark**. System is the default, and it changes with your device at once, without
36
+ reloading the page, when your Mac switches between light and dark. Choosing a theme shows it on the
37
+ Settings page straight away; **Save changes** keeps it. If you have not chosen, the workspace follows
38
+ your device, so on a Mac set to light it now opens in light mode.
39
+
40
+ **Readable in both.** Every piece of text in the light theme, including timestamps, counts and other
41
+ small details, meets the WCAG 4.5:1 contrast level against whatever it sits on.
42
+
43
+ **Fixed: buttons in a review that went blank on hover.** In the dark theme, pointing at **Open in**
44
+ your editor, **Show more of this file**, **View files**, **Regenerate** or a diagram's zoom buttons
45
+ turned the label white on the white review, so it disappeared. They now keep their dark label.
46
+
47
+ **A clearer message when OpenAI refuses Codex while it is signed in.** If Codex says it is signed in
48
+ but OpenAI answers "Incorrect API key", the review no longer suggests signing in again, and no longer
49
+ suggests looking for an API key of your own: the key in that error is Codex's own. It now suggests
50
+ `codex doctor` to see what Codex is using, and `codex features list` to find an experimental Codex
51
+ feature to turn off, which is what fixed it when we saw it.
52
+
53
+ ## 0.46.0
54
+
55
+ **The change map: see what a change is about, and how its parts affect each other.** The Diagrams
56
+ page now opens on a **Change map**, drawn from the review's own themes. It reads from the goal of
57
+ the change, through what it does and the state it shares, to the rules it must keep, the risks, and
58
+ what the person using it gets. Every arrow says what it means, such as *adds another writer* or
59
+ *protects every change*, rather than just joining two boxes. Each idea says why it matters, names the
60
+ code to search for, and links to its theme in the review path. The ideas that matter most have a
61
+ heavier frame and are marked **Core idea**. Click an idea to highlight what it connects to, or open
62
+ **Read as a list** to read every relationship as a sentence.
63
+
64
+ **Simple or Technical.** A switch on the map changes its wording between everyday language and the
65
+ precise terms, without changing what is connected to what, and without asking Buddy AI again. Your
66
+ choice is remembered. If you have already asked Buddy AI to **Explain in simple terms**, the map's
67
+ Simple wording keeps the same analogy.
68
+
69
+ **Change map and Implementation, side by side.** The Diagrams page has two tabs. **Change map**
70
+ explains the change. **Implementation** is the diagram of how the code does it, which works as it
71
+ did before. A small check on each tab shows whether it has already been generated. Diagrams is now
72
+ always in the review's sidebar, and the Overview has a **Diagrams** button beside **Explain in simple
73
+ terms**.
74
+
75
+ **Nothing is generated until you ask.** Opening Diagrams, or either tab, never starts Buddy AI. Only a
76
+ button that says **Generate** or **Regenerate** does, and while one is running you see its progress
77
+ and **Stop**. Reviews made before this version open on a short description of the map and a
78
+ **Generate change map** button.
79
+
80
+ **A change map always matches the review beside it.** Running the analysis again, or updating the
81
+ review to newer commits, removes the map, because it was built from the analysis that was replaced.
82
+ Generate a new one to map the review as it is now. Implementation diagrams are kept as before and say
83
+ when they were drawn from an earlier commit.
84
+
85
+ **Every page of a review can be expanded.** The expand button now also appears on the Overview,
86
+ Diagrams, PR context, both KISS review pages and the progress page shown while a review is running,
87
+ as well as Buddy AI, Issues, Questions, Files and the review path. Diagrams and Files get much more
88
+ of the window, and an expanded change map shows its stages side by side; the others stay at a
89
+ comfortable reading width.
90
+
91
+ **Folding Your prompts now hides them.** Clicking **Your prompts** turned its arrow and saved your
92
+ choice, but the prompts stayed on screen. They now fold away as intended.
93
+
3
94
  ## 0.45.0
4
95
 
5
96
  **Expand a pane to fill the review page.** Buddy AI, Issues, Questions, Files and the review path
@@ -1129,6 +1129,19 @@ var CodexUnavailableError = class extends AgentUnavailableError {};
1129
1129
  */
1130
1130
  var AUTHENTICATION = /not (?:logged|signed) in|unauthori[sz]ed|401|authenticat|credential|sign[- ]?in|log ?in/i;
1131
1131
  /**
1132
+ * OpenAI refusing a request Codex believes is signed in, which is not nobody being signed in.
1133
+ *
1134
+ * Seen with Codex reporting "Logged in using ChatGPT" and no API key anywhere in the reviewer's
1135
+ * environment: the key named in the error is Codex's own, not one of theirs. Signing in again did
1136
+ * not clear it; turning off an experimental Codex feature did. So the advice is Codex's own
1137
+ * diagnosis and its feature switches, never a login loop and never a hunt for an API key. Still an
1138
+ * authentication failure, so no Retry is offered.
1139
+ */
1140
+ var REJECTED_KEY = /incorrect api key|invalid[_ ]api[_ ]key/i;
1141
+ function isAuthentication(detail) {
1142
+ return AUTHENTICATION.test(detail) || REJECTED_KEY.test(detail);
1143
+ }
1144
+ /**
1132
1145
  * Which kind of failure the agent's own sentence describes.
1133
1146
  *
1134
1147
  * Only the one distinction that changes what a person is offered: a run that failed because nobody
@@ -1137,7 +1150,7 @@ var AUTHENTICATION = /not (?:logged|signed) in|unauthori[sz]ed|401|authenticat|c
1137
1150
  * label for them.
1138
1151
  */
1139
1152
  function kindOf(detail) {
1140
- return AUTHENTICATION.test(detail) ? "agent_authentication_failed" : "agent_execution_failed";
1153
+ return isAuthentication(detail) ? "agent_authentication_failed" : "agent_execution_failed";
1141
1154
  }
1142
1155
  var codexAgent = {
1143
1156
  id: CODEX_AGENT_ID,
@@ -1147,8 +1160,10 @@ var codexAgent = {
1147
1160
  captureEnv: captureEnv$1,
1148
1161
  /** Which tool, which profile, and the one command that changes it. See `agent.ts` for the budget. */
1149
1162
  explainFailure(detail, env = {}) {
1150
- if (!AUTHENTICATION.test(detail)) return null;
1151
- return `Codex could not sign in. This review was started using ${env.CODEX_HOME ? `the Codex profile at \`${env.CODEX_HOME}\`` : "your default Codex profile"}, so run \`codex login\` against that one.`;
1163
+ if (!isAuthentication(detail)) return null;
1164
+ const profile = env.CODEX_HOME ? `the Codex profile at \`${env.CODEX_HOME}\`` : "your default Codex profile";
1165
+ if (REJECTED_KEY.test(detail)) return `OpenAI refused a request from ${profile} even though Codex reports being signed in, which usually points to Codex's own setup rather than your sign-in. Run \`codex doctor\` to see what it is using, and check \`codex features list\` for an experimental feature to turn off with \`codex features disable <name>\`.`;
1166
+ return `Codex could not sign in. This review was started using ${profile}, so run \`codex login\` against that one.`;
1152
1167
  },
1153
1168
  /**
1154
1169
  * Whether the command is here and runs. Deliberately not whether it is signed in.
@@ -4112,6 +4127,95 @@ function normalise(ids) {
4112
4127
  return seen;
4113
4128
  }
4114
4129
  //#endregion
4130
+ //#region ../../packages/review-harness/src/workspace/lifecycle.ts
4131
+ /**
4132
+ * What happens next with a change, as the reviewer says it: still in play, parked until something
4133
+ * moves, or finished with.
4134
+ *
4135
+ * A separate axis from New / In progress / Reviewed, which says what the reviewer has *done*. A
4136
+ * change can be reviewed and waiting for another push, or reviewed and done, and one field cannot
4137
+ * hold both answers.
4138
+ *
4139
+ * One registry that the stored type, the card, the menus, the bulk bar and the route all derive
4140
+ * from. Pure on purpose: the reviews page's script imports it to move a card between sections after
4141
+ * a mark, without asking the server for the page again.
4142
+ */
4143
+ var LIFECYCLES = [
4144
+ {
4145
+ id: "active",
4146
+ action: "Move to active"
4147
+ },
4148
+ {
4149
+ id: "waiting",
4150
+ action: "Mark waiting"
4151
+ },
4152
+ {
4153
+ id: "done",
4154
+ action: "Mark done"
4155
+ }
4156
+ ];
4157
+ function isLifecycle(value) {
4158
+ return LIFECYCLES.some((lifecycle) => lifecycle.id === value);
4159
+ }
4160
+ /** A stored value read defensively: anything this code did not write reads as Active. */
4161
+ function parseLifecycle(raw) {
4162
+ if (typeof raw !== "object" || raw === null) return void 0;
4163
+ const { state, at } = raw;
4164
+ if (state !== "waiting" && state !== "done" || typeof at !== "number" || !Number.isFinite(at)) return void 0;
4165
+ return {
4166
+ state,
4167
+ at
4168
+ };
4169
+ }
4170
+ function lifecycleAction(lifecycle) {
4171
+ return LIFECYCLES.find((entry) => entry.id === lifecycle).action;
4172
+ }
4173
+ var ACTIVITY_LABELS = {
4174
+ created: "Created",
4175
+ updated: "Updated",
4176
+ merged: "Merged",
4177
+ closed: "Closed",
4178
+ reopened: "Reopened"
4179
+ };
4180
+ function activityLabel(kind) {
4181
+ return ACTIVITY_LABELS[kind];
4182
+ }
4183
+ /**
4184
+ * Which section a card is drawn in.
4185
+ *
4186
+ * Waiting means "bring this back when something changes", so a Waiting review whose change moved
4187
+ * after it was parked is drawn in Active. Derived, and nothing is written: the stored state stays
4188
+ * Waiting until the reviewer says otherwise, and marking it Waiting again moves the baseline.
4189
+ *
4190
+ * Done means "leave me alone", so it never comes back by itself. `created` can never resurface
4191
+ * anything either, because a new analysis is a new record, and a new record is Active.
4192
+ */
4193
+ function sectionOf(lifecycle, activity) {
4194
+ if (!lifecycle) return "active";
4195
+ if (lifecycle.state === "waiting" && changedSince(lifecycle, activity)) return "active";
4196
+ return lifecycle.state;
4197
+ }
4198
+ /** The chip that says why a card is where it is, or absent when its section already says it. */
4199
+ function lifecycleChip(lifecycle, activity) {
4200
+ if (!lifecycle || !changedSince(lifecycle, activity)) return void 0;
4201
+ return lifecycle.state === "waiting" ? "Changed while waiting" : "Changed since done";
4202
+ }
4203
+ function changedSince(lifecycle, activity) {
4204
+ return activity !== void 0 && activity.kind !== "created" && activity.at > lifecycle.at;
4205
+ }
4206
+ /**
4207
+ * Which lifecycle items a card's menu offers.
4208
+ *
4209
+ * Every state but the one the card is already in, which would be an item that does nothing. A card
4210
+ * carrying a chip is the exception and offers all three: re-marking it is how the reviewer says
4211
+ * they have seen the change, so "Mark waiting" on a Waiting review that changed is the settle
4212
+ * action, not a no-op.
4213
+ */
4214
+ function offersLifecycle(target, lifecycle, activity) {
4215
+ if (lifecycleChip(lifecycle, activity) !== void 0) return true;
4216
+ return target !== (lifecycle?.state ?? "active");
4217
+ }
4218
+ //#endregion
4115
4219
  //#region ../../packages/review-harness/src/workspace/store.ts
4116
4220
  var WORKSPACES_DIR = join(STORE_ROOT, "workspaces");
4117
4221
  /**
@@ -4481,8 +4585,20 @@ function followedRefName(branch, followedRef) {
4481
4585
  * can return is the two added together. Neither constant says that on its own, which is why it is
4482
4586
  * said here.
4483
4587
  */
4484
- function indexReviewGroups(limit, keptLimit, keptIds) {
4485
- return selectIndexGroups(groupByLineage(recentWorkspaces(Number.MAX_SAFE_INTEGER)), limit, keptLimit, keptIds);
4588
+ function indexReviewGroups(limit, keptLimit, keptIds, rank, groups = groupByLineage(recentWorkspaces(Number.MAX_SAFE_INTEGER))) {
4589
+ return selectIndexGroups(groups, limit, keptLimit, keptIds, rank);
4590
+ }
4591
+ /**
4592
+ * What the reviewer explicitly kept, which is what stops the recency window hiding it: the queue,
4593
+ * Saved, and anything marked Waiting or Done.
4594
+ *
4595
+ * Done is the reviewer's archive, and an archive the recency window can empty is not one. Waiting
4596
+ * is work they expect back, and a push to it must have a card to come back on.
4597
+ */
4598
+ function indexKeptIds(reviews, queue) {
4599
+ const kept = new Set(queue);
4600
+ for (const review of reviews) if (review.pinned || review.lifecycle !== void 0) kept.add(review.id);
4601
+ return kept;
4486
4602
  }
4487
4603
  /**
4488
4604
  * The choosing, with the disk left out, in the same spirit as `groupByLineage` next door.
@@ -4494,12 +4610,18 @@ function indexReviewGroups(limit, keptLimit, keptIds) {
4494
4610
  *
4495
4611
  * The kept side is capped for the same reason the recent side is: `queue.json` is a file on a disk
4496
4612
  * somebody can edit, and an uncapped read of it is an index with five thousand cards on it.
4613
+ *
4614
+ * **Windowed by `rank`, which is what the list is ordered by.** The index passes what last happened
4615
+ * to each change, so a branch analysed two months ago and pushed to this morning is inside the
4616
+ * window rather than cut before its activity is ever looked at. Absent, it is when the newest
4617
+ * review was made, which is what every other caller has always meant by recent.
4497
4618
  */
4498
- function selectIndexGroups(groups, limit, keptLimit, keptIds) {
4619
+ function selectIndexGroups(groups, limit, keptLimit, keptIds, rank = (group) => group.latest.createdAt) {
4499
4620
  const kept = [];
4500
4621
  const rest = [];
4501
4622
  for (const group of groups) (group.history.some((review) => keptIds.has(review.id)) ? kept : rest).push(group);
4502
- return [...rest.slice(0, limit), ...kept.slice(0, keptLimit)].sort((a, b) => b.latest.createdAt - a.latest.createdAt);
4623
+ const byRank = (a, b) => rank(b) - rank(a);
4624
+ return [...rest.sort(byRank).slice(0, limit), ...kept.sort(byRank).slice(0, keptLimit)].sort(byRank);
4503
4625
  }
4504
4626
  /**
4505
4627
  * The grouping itself, with the disk left out.
@@ -4626,6 +4748,7 @@ function summarise(workspace) {
4626
4748
  lastViewedAt: workspace.lastViewedAt,
4627
4749
  completedAt: workspace.completedAt,
4628
4750
  pinned: workspace.pinned === true,
4751
+ lifecycle: parseLifecycle(workspace.lifecycle),
4629
4752
  paths: files.slice(0, MAX_INDEXED_PATHS).map((file) => file.name),
4630
4753
  prNumber: workspace.changeSet.data.pullRequest?.number || workspace.prContext?.pullRequest.number,
4631
4754
  commitSha: workspace.session.metadata?.commitSha || (workspace.changeSet.targetType === "commit" ? workspace.changeSet.data.pullRequest.head.sha : "") || void 0,
@@ -4644,6 +4767,28 @@ function reviewedCommit(workspace) {
4644
4767
  return workspace.session.metadata?.commitSha || workspace.changeSet.data.pullRequest.head.sha || null;
4645
4768
  }
4646
4769
  /**
4770
+ * Forget what was built from the analysis, because the analysis is being replaced.
4771
+ *
4772
+ * Only the change map. It is made from the review's own themes, so one kept beside a different set
4773
+ * of themes would contradict the guide it sits next to. Diagrams describe code and carry their
4774
+ * commit, so they stay and say they are dated; see `diagrams`.
4775
+ */
4776
+ function dropDerivedFromAnalysis(workspace) {
4777
+ delete workspace.changeMap;
4778
+ }
4779
+ /**
4780
+ * The same, for a review that has just moved to a different commit.
4781
+ *
4782
+ * Said by commit rather than by "an update happened", so an update that found nothing new keeps
4783
+ * the map, and a map drawn from the old analysis while the update was running goes with the rest.
4784
+ */
4785
+ function dropStaleChangeMap(workspace) {
4786
+ const drawnFrom = workspace.changeMap?.commitSha;
4787
+ if (!drawnFrom) return;
4788
+ const reviewed = reviewedCommit(workspace);
4789
+ if (reviewed && drawnFrom !== reviewed) dropDerivedFromAnalysis(workspace);
4790
+ }
4791
+ /**
4647
4792
  * The KISS run the page presents, or null when nobody has run one.
4648
4793
  *
4649
4794
  * Reads the recorded pointer rather than the end of the list, so a failed rerun does not become
@@ -4781,7 +4926,8 @@ function isKept(entry, queued) {
4781
4926
  const id = workspaceIdFrom(entry);
4782
4927
  if (id === null) return false;
4783
4928
  if (queued.has(id)) return true;
4784
- return loadWorkspace(id)?.pinned === true;
4929
+ const workspace = loadWorkspace(id);
4930
+ return workspace?.pinned === true || parseLifecycle(workspace?.lifecycle)?.state === "done";
4785
4931
  }
4786
4932
  /** The review an entry belongs to, whether it is the record or the usage sidecar beside it. */
4787
4933
  function workspaceIdFrom(entry) {
@@ -10547,6 +10693,7 @@ async function reanalyseReview(workspaceId, agentId, onStarted, requestedModel)
10547
10693
  saveJob(job);
10548
10694
  workspace.jobId = job.id;
10549
10695
  workspace.session = beginReviewSession(sha, agent, void 0, model ?? void 0);
10696
+ dropDerivedFromAnalysis(workspace);
10550
10697
  saveWorkspace(workspace);
10551
10698
  return job;
10552
10699
  });
@@ -12199,6 +12346,7 @@ function mergeUpdateInto(fresh, updated) {
12199
12346
  for (const field of REVIEWER_SESSION_FIELDS) if (field in fresh.session) session[field] = current[field];
12200
12347
  else delete session[field];
12201
12348
  merged.session = session;
12349
+ dropStaleChangeMap(merged);
12202
12350
  return merged;
12203
12351
  }
12204
12352
  /**
@@ -12627,4 +12775,4 @@ function lineageIds(id) {
12627
12775
  return [.../* @__PURE__ */ new Set([id, ...lineage.map((review) => review.id)])];
12628
12776
  }
12629
12777
  //#endregion
12630
- export { bootstrapUrl as $, recentWorkspaces as $t, createPrState as A, STORE_ROOT as An, fail as At, toneOf as B, driverGone as Bt, readEvents as C, git as Cn, fillFileUrlTemplate as Ct, announceJob as D, readAgentPreference as Dn, reviewedShaOf as Dt, telemetryUploadConsent as E, clearAgentPreference as En, followedBranch as Et, markAllRead as F, detectAgents as Fn, isLiveJob as Ft, MANAGED_ROOT as G, latestKissRun as Gt, withUsageRecorded as H, followedRefName as Ht, markRead as I, AgentCancelledError as In, phasesFor as It, modelHelpLines as J, loadWorkspace as Jt, readMarker as K, lineageKeyFor as Kt, pruneNotifications as L, AgentUnavailableError as Ln, progressSteps as Lt, eventName as M, DEFAULT_AGENT_ID as Mn, loadJob as Mt, headline as N, agentById as Nn, saveJob as Nt, branchOf as O, writeAgentPreference as On, allJobs as Ot, listNotifications as P, agentFor as Pn, PHASES as Pt, readIndexToken as Q, previousKissResult as Qt, readNotification as R, purposeOf as Rt, startJob as S, isCommitReview as Sn, remoteHost as St, recordTelemetryUploadConsent as T, resolveModel as Tn, checkReview as Tt, EXPLAIN_SIMPLY_PROMPT as U, groupByLineage as Ut, unreadCount as V, isClaimed as Vt, ReviewBeingDeletedError as W, indexReviewGroups as Wt, compactQueue as X, mutateWorkspace as Xt, relativeTime as Y, matchingWorkspaceIds as Yt, queueForReview as Z, positionInLineage as Zt, agentEnvOf as _, reviewerDispositions as _n, statedWorkspacePort as _t, wasBlocked as a, workspaceStamps as an, spawnServer as at, reanalyseReview as b, resolveTarget as bn, forgeResolver as bt, RefreshUnavailableError as c, queueAddMany as cn, writeServerRecord as ct, refreshPrContext as d, readQueue as dn, feedbackUrl as dt, reviewedCommit as en, clearServerRecord as et, isUnchanged as f, doneVerb as fn, DEFAULT_WORKSPACE_PORT as ft, runningJobs as g, questionsOutstanding as gn, resolveWorkspacePort as gt, liveUpdateFor as h, issuesOutstanding as hn, parseWorkspacePort as ht, liveJobsFor as i, workspaceRevision as in, serverEntryExists as it, createPrUpdate as j, AGENT_IDS as jn, isTerminal as jt, subjectOf as k, CONFIG_PATH as kn, endedAt as kt, mergeUpdateInto as l, queueRemove as ln, BUILD_VERSION as lt, UpdateAlreadyRunningError as m, isQuestionOutstanding as mn, MIN_WORKSPACE_PORT as mt, deleteReview as n, summarise as nn, readServerRecord as nt, discardJob as o, dequeueOnComplete as on, stopServer as ot, askCheckout as p, isIssueOutstanding as pn, MAX_WORKSPACE_PORT as pt, removeWorktree as q, lineagePosition as qt, lineageIds as r, touchWorkspace as rn, reviewsUrl as rt, FETCH_TIMEOUT_MS as s, queueAdd as sn, workspaceUrl as st, deleteLineage as t, reviewedRepositories as tn, ensureServer as tt, updateReview as u, queueStamp as un, PACKAGE_NAME as ut, recordKissRun as v, processDiscussion as vn, writePortPreference as vt, record as w, resolveAgent as wn, checkCodeFreshness as wt, runJob as x, displayRef as xn, forgeFor as xt, startKissJob as y, describeAuthorship as yn, claimRequestUrl as yt, removeNotification as z, clearClaim as zt };
12778
+ export { queueForReview as $, mutateWorkspace as $t, createPrState as A, describeAuthorship as An, allJobs as At, toneOf as B, CONFIG_PATH as Bn, purposeOf as Bt, readEvents as C, doneVerb as Cn, forgeFor as Ct, announceJob as D, questionsOutstanding as Dn, checkReview as Dt, telemetryUploadConsent as E, issuesOutstanding as En, checkCodeFreshness as Et, markAllRead as F, resolveAgent as Fn, saveJob as Ft, extractJsonText as G, agentFor as Gn, groupByLineage as Gt, withUsageRecorded as H, AGENT_IDS as Hn, driverGone as Ht, markRead as I, resolveModel as In, PHASES as It, readMarker as J, AgentUnavailableError as Jn, latestKissRun as Jt, ReviewBeingDeletedError as K, detectAgents as Kn, indexKeptIds as Kt, pruneNotifications as L, clearAgentPreference as Ln, isLiveJob as Lt, eventName as M, displayRef as Mn, fail as Mt, headline as N, isCommitReview as Nn, isTerminal as Nt, branchOf as O, reviewerDispositions as On, followedBranch as Ot, listNotifications as P, git as Pn, loadJob as Pt, compactQueue as Q, matchingWorkspaceIds as Qt, readNotification as R, readAgentPreference as Rn, phasesFor as Rt, startJob as S, readQueue as Sn, forgeResolver as St, recordTelemetryUploadConsent as T, isQuestionOutstanding as Tn, fillFileUrlTemplate as Tt, EXPLAIN_SIMPLY_PROMPT as U, DEFAULT_AGENT_ID as Un, isClaimed as Ut, unreadCount as V, STORE_ROOT as Vn, clearClaim as Vt, asString as W, agentById as Wn, followedRefName as Wt, modelHelpLines as X, lineagePosition as Xt, removeWorktree as Y, lineageKeyFor as Yt, relativeTime as Z, loadWorkspace as Zt, agentEnvOf as _, dequeueOnComplete as _n, parseWorkspacePort as _t, wasBlocked as a, summarise as an, reviewsUrl as at, reanalyseReview as b, queueRemove as bn, writePortPreference as bt, RefreshUnavailableError as c, workspaceStamps as cn, stopServer as ct, refreshPrContext as d, isLifecycle as dn, BUILD_VERSION as dt, positionInLineage as en, readIndexToken as et, isUnchanged as f, lifecycleAction as fn, PACKAGE_NAME as ft, runningJobs as g, sectionOf as gn, MIN_WORKSPACE_PORT as gt, liveUpdateFor as h, parseLifecycle as hn, MAX_WORKSPACE_PORT as ht, liveJobsFor as i, reviewedRepositories as in, readServerRecord as it, createPrUpdate as j, resolveTarget as jn, endedAt as jt, subjectOf as k, processDiscussion as kn, reviewedShaOf as kt, mergeUpdateInto as l, LIFECYCLES as ln, workspaceUrl as lt, UpdateAlreadyRunningError as m, offersLifecycle as mn, DEFAULT_WORKSPACE_PORT as mt, deleteReview as n, recentWorkspaces as nn, clearServerRecord as nt, discardJob as o, touchWorkspace as on, serverEntryExists as ot, askCheckout as p, lifecycleChip as pn, feedbackUrl as pt, MANAGED_ROOT as q, AgentCancelledError as qn, indexReviewGroups as qt, lineageIds as r, reviewedCommit as rn, ensureServer as rt, FETCH_TIMEOUT_MS as s, workspaceRevision as sn, spawnServer as st, deleteLineage as t, previousKissResult as tn, bootstrapUrl as tt, updateReview as u, activityLabel as un, writeServerRecord as ut, recordKissRun as v, queueAdd as vn, resolveWorkspacePort as vt, record as w, isIssueOutstanding as wn, remoteHost as wt, runJob as x, queueStamp as xn, claimRequestUrl as xt, startKissJob as y, queueAddMany as yn, statedWorkspacePort as yt, removeNotification as z, writeAgentPreference as zn, progressSteps as zt };
package/dist/main.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { $ as bootstrapUrl, $t as recentWorkspaces, An as STORE_ROOT, Bt as driverGone, Cn as git, Dn as readAgentPreference, E as telemetryUploadConsent, Fn as detectAgents, G as MANAGED_ROOT, Ht as followedRefName, J as modelHelpLines, Jt as loadWorkspace, K as readMarker, Kt as lineageKeyFor, Lt as progressSteps, Mn as DEFAULT_AGENT_ID, Mt as loadJob, Nn as agentById, On as writeAgentPreference, Ot as allJobs, Pt as PHASES, Q as readIndexToken, Rt as purposeOf, S as startJob, T as recordTelemetryUploadConsent, Tn as resolveModel, Tt as checkReview, Ut as groupByLineage, Vt as isClaimed, Xt as mutateWorkspace, Y as relativeTime, Yt as matchingWorkspaceIds, Z as queueForReview, Zt as positionInLineage, _t as statedWorkspacePort, a as wasBlocked, b as reanalyseReview, bn as resolveTarget, bt as forgeResolver, ft as DEFAULT_WORKSPACE_PORT, g as runningJobs, h as liveUpdateFor, ht as parseWorkspacePort, i as liveJobsFor, jn as AGENT_IDS, jt as isTerminal, kn as CONFIG_PATH, l as mergeUpdateInto, lt as BUILD_VERSION, m as UpdateAlreadyRunningError, mt as MIN_WORKSPACE_PORT, n as deleteReview$1, nn as summarise, ot as stopServer, pt as MAX_WORKSPACE_PORT, q as removeWorktree, rt as reviewsUrl, st as workspaceUrl, tn as reviewedRepositories, tt as ensureServer, u as updateReview, ut as PACKAGE_NAME, v as recordKissRun, vt as writePortPreference, w as record$1, wn as resolveAgent, x as runJob, xn as displayRef, zt as clearClaim } from "./delete_review-BWMmO81Q.js";
2
+ import { $ as queueForReview, $t as mutateWorkspace, At as allJobs, Bn as CONFIG_PATH, Bt as purposeOf, Dt as checkReview, E as telemetryUploadConsent, Fn as resolveAgent, Gt as groupByLineage, Hn as AGENT_IDS, Ht as driverGone, In as resolveModel, It as PHASES, J as readMarker, Kn as detectAgents, Mn as displayRef, Nt as isTerminal, Pn as git, Pt as loadJob, Qt as matchingWorkspaceIds, Rn as readAgentPreference, S as startJob, St as forgeResolver, T as recordTelemetryUploadConsent, Un as DEFAULT_AGENT_ID, Ut as isClaimed, Vn as STORE_ROOT, Vt as clearClaim, Wn as agentById, Wt as followedRefName, X as modelHelpLines, Y as removeWorktree, Yt as lineageKeyFor, Z as relativeTime, Zt as loadWorkspace, _t as parseWorkspacePort, a as wasBlocked, an as summarise, at as reviewsUrl, b as reanalyseReview, bt as writePortPreference, ct as stopServer, dt as BUILD_VERSION, en as positionInLineage, et as readIndexToken, ft as PACKAGE_NAME, g as runningJobs, gt as MIN_WORKSPACE_PORT, h as liveUpdateFor, ht as MAX_WORKSPACE_PORT, i as liveJobsFor, in as reviewedRepositories, jn as resolveTarget, l as mergeUpdateInto, lt as workspaceUrl, m as UpdateAlreadyRunningError, mt as DEFAULT_WORKSPACE_PORT, n as deleteReview$1, nn as recentWorkspaces, q as MANAGED_ROOT, rt as ensureServer, tt as bootstrapUrl, u as updateReview, v as recordKissRun, w as record$1, x as runJob, yt as statedWorkspacePort, zn as writeAgentPreference, zt as progressSteps } from "./delete_review-D52wkt66.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";