prreviewbuddy 0.52.2 → 0.53.1

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,43 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.53.1
4
+
5
+ **The running KISS review has its normal layout back.** While a KISS review ran, its progress
6
+ message sat in a rounded grey pill with the text pressed against its edges. It borrowed the styling
7
+ of the new recommendation status labels, which shared its name.
8
+
9
+ ## 0.53.0
10
+
11
+ **KISS recommendations are decisions now.** Each recommendation carries its status and two choices
12
+ worded for whose code it is. Reviewing your own code, you choose **Plan to simplify** or **Keep as
13
+ implemented**. Reviewing someone else's, you choose **Raise with author** or **Leave it**. Decided
14
+ recommendations move into a **Decided** list below the open ones, in the order the analysis ranked
15
+ them. Press the chosen button again to take a decision back. Decisions are kept across reloads, and
16
+ the KISS rail counts what is still undecided. If a decision can't be saved, the card goes back as it
17
+ was and offers **Try again**.
18
+
19
+ - **Copy recommendations** (reviewing someone else's code): copies the recommendations you chose to
20
+ raise as Markdown ready to paste, with each one's title, why it matters, the simpler approach, where
21
+ to start and the draft comment. It is disabled until you choose one, while a decision is still
22
+ being saved, and whenever the branch has moved since the run. If a rerun fails, the earlier review
23
+ stays on the page and is checked against the branch by its own commit, so it is marked stale when
24
+ the branch has moved past it.
25
+ - Each card also has **Copy**, **Ask Buddy**, **Open file** and, where the run wrote one, **Copy
26
+ draft comment**.
27
+ - **Whose code is this?** is now part of running KISS, not part of the result. A finished review
28
+ shows its perspective in the header, beside **Run again**, which opens the choice with the last
29
+ answer already selected. The stale-branch notice offers the same **Run again**, and **Not now**
30
+ now folds that notice to one line instead of removing it.
31
+ - **Complexity worth keeping** is collapsed on the KISS summary. New runs give each item a one-line
32
+ reason beside its title.
33
+ - Fixed: a review finishing in the background could undo something you changed on the page while it
34
+ ran, such as a dismissed notice or an answered question.
35
+
36
+ ## 0.52.3
37
+
38
+ **Selected cards keep their rounded corners.** In select mode, a ticked card's tint now fills the
39
+ card's own rounded shape instead of a square behind it.
40
+
3
41
  ## 0.52.2
4
42
 
5
43
  **Continue reviewing is gone from the Reviews page.** The banner opened whatever was first in your
@@ -3245,6 +3245,30 @@ function failSession(session, error, kind, rejectedAnswer) {
3245
3245
  };
3246
3246
  }
3247
3247
  //#endregion
3248
+ //#region ../../packages/review-harness/src/domain/kiss/identity.ts
3249
+ function distinctIds(items) {
3250
+ const taken = new Set(items.map((item) => item.id));
3251
+ const kept = /* @__PURE__ */ new Set();
3252
+ return items.map((item) => {
3253
+ if (!kept.has(item.id)) {
3254
+ kept.add(item.id);
3255
+ return item;
3256
+ }
3257
+ let n = 2;
3258
+ while (taken.has(`${item.id}~${n}`)) n += 1;
3259
+ const id = `${item.id}~${n}`;
3260
+ taken.add(id);
3261
+ return {
3262
+ ...item,
3263
+ id
3264
+ };
3265
+ });
3266
+ }
3267
+ /** A run's recommendations with the ids decisions are stored against. Read through this, always. */
3268
+ function recommendationsOf(result) {
3269
+ return distinctIds(result?.recommendations ?? []);
3270
+ }
3271
+ //#endregion
3248
3272
  //#region ../../packages/review-harness/src/domain/content/github/diff_parser.ts
3249
3273
  var CONTEXT_LINES = 2;
3250
3274
  /**
@@ -4326,6 +4350,19 @@ var WORKSPACES_DIR = join(STORE_ROOT, "workspaces");
4326
4350
  * in the minutes it took. `handleState` is the only writer and writes nothing else.
4327
4351
  */
4328
4352
  var REVIEWER_SESSION_FIELDS = ["answeredQuestionIds", "dismissedIssues"];
4353
+ /**
4354
+ * A session a long run is about to write, with the reviewer's own fields taken from disk instead.
4355
+ *
4356
+ * The run built `session` from a copy it loaded before awaiting something, and the reviewer may have
4357
+ * answered or dismissed something in that window. Absent on disk means absent here too.
4358
+ */
4359
+ function keepReviewerFields(fresh, session) {
4360
+ const kept = { ...session };
4361
+ const current = fresh.session;
4362
+ for (const field of REVIEWER_SESSION_FIELDS) if (field in fresh.session) kept[field] = current[field];
4363
+ else delete kept[field];
4364
+ return kept;
4365
+ }
4329
4366
  function workspacePath(id) {
4330
4367
  return join(WORKSPACES_DIR, `${id}.json`);
4331
4368
  }
@@ -4945,6 +4982,17 @@ function previousKissResult(workspace) {
4945
4982
  for (let index = before.length - 1; index >= 0; index -= 1) if (before[index].result) return before[index];
4946
4983
  return null;
4947
4984
  }
4985
+ /**
4986
+ * The run whose answer the page presents: the latest when it produced one, otherwise the last that
4987
+ * did. The store's form of `presentedKissRun` in the view, for callers holding a workspace rather
4988
+ * than a view model. Freshness must be measured from this run's commit: measured from a failed
4989
+ * rerun's instead, an answer about older commits would read as current, and could be handed off.
4990
+ */
4991
+ function presentedKissRunOf(workspace) {
4992
+ const latest = latestKissRun(workspace);
4993
+ if (latest?.result) return latest;
4994
+ return previousKissResult(workspace);
4995
+ }
4948
4996
  /** Appends a run and points the page at it. The caller saves: this is one half of a larger write. */
4949
4997
  function startKissRun(workspace, start) {
4950
4998
  const run = {
@@ -5004,6 +5052,38 @@ function failKissRun(workspace, runId, error, kind, rejectedAnswer) {
5004
5052
  return run;
5005
5053
  }
5006
5054
  /**
5055
+ * Whether this review holds the recommendation a decision names. Asked before writing, so a refused
5056
+ * decision leaves the file untouched, and again inside the write, where the answer is final.
5057
+ */
5058
+ function kissDecisionRefusal(workspace, input) {
5059
+ const run = (workspace.kissRuns ?? []).find((candidate) => candidate.id === input.runId);
5060
+ if (!run?.result) return "unknown-run";
5061
+ return recommendationsOf(run.result).some((recommendation) => recommendation.id === input.recommendationId) ? null : "unknown-recommendation";
5062
+ }
5063
+ /**
5064
+ * Record one decision, replacing whatever was decided about that recommendation before.
5065
+ *
5066
+ * One entry per request rather than the page's whole list, so two cards decided in quick
5067
+ * succession cannot overwrite each other: each request changes only the entry it names.
5068
+ */
5069
+ function decideKissRecommendation(workspace, input, now = Date.now()) {
5070
+ const refusal = kissDecisionRefusal(workspace, input);
5071
+ if (refusal) return refusal;
5072
+ const others = (workspace.kissDecisions ?? []).filter((entry) => !(entry.runId === input.runId && entry.recommendationId === input.recommendationId));
5073
+ workspace.kissDecisions = input.decision === "undecided" ? others : [...others, {
5074
+ runId: input.runId,
5075
+ recommendationId: input.recommendationId,
5076
+ decision: input.decision,
5077
+ decidedAt: now
5078
+ }];
5079
+ return null;
5080
+ }
5081
+ /** The decisions made against one run. Empty for a run nobody has decided anything about. */
5082
+ function kissDecisionsOf(workspace, runId) {
5083
+ if (!runId) return [];
5084
+ return (workspace.kissDecisions ?? []).filter((entry) => entry.runId === runId);
5085
+ }
5086
+ /**
5007
5087
  * Record that a workspace was opened.
5008
5088
  *
5009
5089
  * Best-effort and deliberately silent: a review that cannot record having been looked at is still
@@ -9505,6 +9585,7 @@ var KISS_OUTPUT_INSTRUCTIONS = `Respond with a single JSON object, no markdown a
9505
9585
  "justifiedComplexity": [{
9506
9586
  "id": string,
9507
9587
  "title": string,
9588
+ "reason": string,
9508
9589
  "rationale": string,
9509
9590
  "locations": [{ "path": string, "line": number, "primary": boolean }]
9510
9591
  }],
@@ -9530,6 +9611,9 @@ Field guidance:
9530
9611
  - "draftComment": REVIEWER FRAMING ONLY, and only where a comment is worth making. Omit it otherwise. A short, constructive pull request comment in the reviewer's voice.
9531
9612
  - "locations": required, at least one. Where this complexity lives. Prefer the changed files responsible for it, named exactly as they appear in the diff. If an unchanged repository file is where the complexity actually sits and no changed file represents it, cite that file too, but never describe an unchanged file as part of this change. "line" is optional. Set "primary": true on exactly one location — the one place a reader should open first, which should be a changed file wherever one represents the concern — and false on the rest.
9532
9613
  - "justifiedComplexity": complexity in this change that is doing a real job. Empty list when there is nothing worth the note.
9614
+ - "title": what is kept, as the decision: "Keep atomic replacement", "Keep the schema 1 fallback".
9615
+ - "reason": required. Why it stays, in one sentence of at most 15 words: "Prevents concurrent writers from corrupting persisted state." Shown without expanding anything, so it must carry the point on its own. Do not restate the title.
9616
+ - "rationale": the full supporting explanation, in detail. Point at the code.
9533
9617
  - "aggregateEstimate": optional, one phrase, across the whole change. Omit it unless it is defensible.`;
9534
9618
  function buildKissPrompt(pr, options) {
9535
9619
  const { stats, raw } = pr;
@@ -9828,10 +9912,10 @@ function parseKissAnswer(raw) {
9828
9912
  const { kept, withheld } = normalizeRecommendations(obj.recommendations);
9829
9913
  return {
9830
9914
  result: {
9831
- schemaVersion: 2,
9915
+ schemaVersion: 3,
9832
9916
  assessment,
9833
9917
  summary,
9834
- recommendations: kept,
9918
+ recommendations: distinctIds(kept),
9835
9919
  justifiedComplexity: normalizeJustified(obj.justifiedComplexity),
9836
9920
  ...optional("aggregateEstimate", asString(obj.aggregateEstimate))
9837
9921
  },
@@ -9896,6 +9980,7 @@ function normalizeJustified(value) {
9896
9980
  return value.filter((item) => typeof item === "object" && item !== null).map((item, index) => ({
9897
9981
  id: asString(item.id) || `keep-${index + 1}`,
9898
9982
  title: asString(item.title),
9983
+ ...optional("reason", unlessPlaceholder(asString(item.reason))),
9899
9984
  rationale: asString(item.rationale),
9900
9985
  locations: normalizeLocations(item.locations)
9901
9986
  })).filter((entry) => entry.title !== "" || entry.rationale !== "");
@@ -10849,16 +10934,17 @@ async function startJob(input) {
10849
10934
  } : {}
10850
10935
  });
10851
10936
  saveJob(job);
10852
- if (review.type === "kiss") startKissRun(workspace, {
10853
- jobId: job.id,
10854
- audience: review.audience,
10855
- reviewedSha: target.sha,
10856
- promptVersion: "2",
10857
- agentId: agent.id,
10858
- ...input.requestedModel ? { requestedModel: input.requestedModel } : {}
10937
+ mutateWorkspace(workspace.id, (fresh) => {
10938
+ if (review.type === "kiss") startKissRun(fresh, {
10939
+ jobId: job.id,
10940
+ audience: review.audience,
10941
+ reviewedSha: target.sha,
10942
+ promptVersion: "3",
10943
+ agentId: agent.id,
10944
+ ...input.requestedModel ? { requestedModel: input.requestedModel } : {}
10945
+ });
10946
+ else fresh.jobId = job.id;
10859
10947
  });
10860
- else workspace.jobId = job.id;
10861
- saveWorkspace(workspace);
10862
10948
  });
10863
10949
  return workspace.id;
10864
10950
  }
@@ -10881,37 +10967,41 @@ async function reanalyseReview(workspaceId, agentId, onStarted, requestedModel)
10881
10967
  if (!sha) throw new Error("This review does not record which commit it describes, so it cannot be analysed again.");
10882
10968
  const agent = agentId ? agentById(agentId) : agentById(agentIdOf(workspace.session));
10883
10969
  const started = await withReviewLock(workspaceId, () => {
10884
- if (workspace.session.result) workspace.previousResult = {
10885
- result: workspace.session.result,
10886
- commitSha: sha,
10887
- replacedAt: Date.now(),
10888
- agentId: agentIdOf(workspace.session),
10889
- ...workspace.session.requestedModel ? { requestedModel: workspace.session.requestedModel } : {}
10890
- };
10891
- const target = {
10892
- originRepoPath: workspace.repoPath,
10893
- branch: workspace.changeSet.headRef,
10894
- sha,
10895
- ...baseOf(workspace.changeSet)
10896
- };
10897
- const model = resolveModel({
10898
- ...requestedModel ? { flag: requestedModel } : {},
10899
- review: { session: workspace.session }
10900
- });
10901
- const job = createJob({
10902
- workspaceId: workspace.id,
10903
- target,
10904
- env: agent.captureEnv(),
10905
- purpose: "review",
10906
- reanalysis: true,
10907
- ...model ? { requestedModel: model } : {}
10970
+ const created = {};
10971
+ mutateWorkspace(workspaceId, (workspace) => {
10972
+ if (workspace.session.result) workspace.previousResult = {
10973
+ result: workspace.session.result,
10974
+ commitSha: sha,
10975
+ replacedAt: Date.now(),
10976
+ agentId: agentIdOf(workspace.session),
10977
+ ...workspace.session.requestedModel ? { requestedModel: workspace.session.requestedModel } : {}
10978
+ };
10979
+ const target = {
10980
+ originRepoPath: workspace.repoPath,
10981
+ branch: workspace.changeSet.headRef,
10982
+ sha,
10983
+ ...baseOf(workspace.changeSet)
10984
+ };
10985
+ const model = resolveModel({
10986
+ ...requestedModel ? { flag: requestedModel } : {},
10987
+ review: { session: workspace.session }
10988
+ });
10989
+ const job = createJob({
10990
+ workspaceId: workspace.id,
10991
+ target,
10992
+ env: agent.captureEnv(),
10993
+ purpose: "review",
10994
+ reanalysis: true,
10995
+ ...model ? { requestedModel: model } : {}
10996
+ });
10997
+ saveJob(job);
10998
+ workspace.jobId = job.id;
10999
+ workspace.session = beginReviewSession(sha, agent, void 0, model ?? void 0);
11000
+ dropDerivedFromAnalysis(workspace);
11001
+ created.job = job;
10908
11002
  });
10909
- saveJob(job);
10910
- workspace.jobId = job.id;
10911
- workspace.session = beginReviewSession(sha, agent, void 0, model ?? void 0);
10912
- dropDerivedFromAnalysis(workspace);
10913
- saveWorkspace(workspace);
10914
- return job;
11003
+ if (!created.job) throw new Error("No such review.");
11004
+ return created.job;
10915
11005
  });
10916
11006
  if (isBusy(started)) throw new ReviewBeingDeletedError();
10917
11007
  onStarted?.(started.id);
@@ -11038,27 +11128,27 @@ async function drive(jobId, workspaceId, runners, driver, signal) {
11038
11128
  ...job.target.pullRequest ? { requestNumber: job.target.pullRequest.number } : {},
11039
11129
  ...expectedFor(job.target)
11040
11130
  });
11041
- const stored = loadWorkspace(workspaceId);
11042
11131
  const isLinkedWorktree = await linkedWorktree(job.target.originRepoPath);
11043
11132
  const checkoutName = basename(job.target.originRepoPath);
11044
- saveWorkspace({
11133
+ const target = job.target;
11134
+ mutateWorkspace(workspaceId, (stored) => ({
11045
11135
  ...stored,
11046
11136
  changeSet: {
11047
11137
  ...context.changeSet,
11048
- repoPath: job.target.originRepoPath,
11049
- headRef: job.target.branch,
11050
- ...job.target.ref ? { headResolvedRef: job.target.ref } : {},
11051
- ...commitIdentity(job.target, stored.changeSet),
11138
+ repoPath: target.originRepoPath,
11139
+ headRef: target.branch,
11140
+ ...target.ref ? { headResolvedRef: target.ref } : {},
11141
+ ...commitIdentity(target, stored.changeSet),
11052
11142
  checkoutName,
11053
11143
  isLinkedWorktree,
11054
11144
  data: {
11055
11145
  ...context.changeSet.data,
11056
11146
  pullRequest: {
11057
11147
  ...context.changeSet.data.pullRequest,
11058
- number: job.target.pullRequest?.number ?? context.changeSet.data.pullRequest.number,
11148
+ number: target.pullRequest?.number ?? context.changeSet.data.pullRequest.number,
11059
11149
  head: {
11060
11150
  ...context.changeSet.data.pullRequest.head,
11061
- ref: job.target.branch
11151
+ ref: target.branch
11062
11152
  },
11063
11153
  repo: checkoutName
11064
11154
  }
@@ -11066,7 +11156,7 @@ async function drive(jobId, workspaceId, runners, driver, signal) {
11066
11156
  },
11067
11157
  diff: context.diff,
11068
11158
  reviewedPaths: context.changeSet.data.files.map((file) => file.name)
11069
- });
11159
+ }));
11070
11160
  job = {
11071
11161
  ...job,
11072
11162
  contextId: context.contextId
@@ -11099,10 +11189,12 @@ async function drive(jobId, workspaceId, runners, driver, signal) {
11099
11189
  detail: message(error)
11100
11190
  };
11101
11191
  }
11102
- if (outcome.kind === "attached") saveWorkspace({
11103
- ...stored,
11104
- prContext: outcome.context
11105
- });
11192
+ if (outcome.kind === "attached") {
11193
+ const context = outcome.context;
11194
+ mutateWorkspace(workspaceId, (fresh) => {
11195
+ fresh.prContext = context;
11196
+ });
11197
+ }
11106
11198
  }
11107
11199
  job = {
11108
11200
  ...job,
@@ -11338,15 +11430,17 @@ async function runAnalysisFor(job, workspaceId, runners, signal, onObservedModel
11338
11430
  */
11339
11431
  async function applyKiss(job, workspaceId, payload, observedModel) {
11340
11432
  const stored = loadWorkspace(workspaceId);
11341
- const run = runOfJob(stored, job.id);
11433
+ runOfJob(stored, job.id);
11342
11434
  const validated = await validateKiss(payload, stored.reviewedPaths, (paths) => existingPaths(job.worktreePath, paths));
11343
- completeKissRun(stored, run.id, {
11344
- result: validated.result,
11345
- audit: validated.audit,
11346
- ...job.env.agentId ? { agentId: job.env.agentId } : {},
11347
- ...await runProvenanceOf(job, observedModel)
11435
+ const provenance = await runProvenanceOf(job, observedModel);
11436
+ mutateWorkspace(workspaceId, (fresh) => {
11437
+ completeKissRun(fresh, runOfJob(fresh, job.id).id, {
11438
+ result: validated.result,
11439
+ audit: validated.audit,
11440
+ ...job.env.agentId ? { agentId: job.env.agentId } : {},
11441
+ ...provenance
11442
+ });
11348
11443
  });
11349
- saveWorkspace(stored);
11350
11444
  }
11351
11445
  /**
11352
11446
  * Record the failure on the run, if there is still a run in flight to record it on.
@@ -11358,12 +11452,11 @@ async function applyKiss(job, workspaceId, payload, observedModel) {
11358
11452
  * declines instead of turning a delivered answer into a failure.
11359
11453
  */
11360
11454
  function failCurrentKissRun(workspaceId, job, reason, kind, rejectedAnswer) {
11361
- const stored = loadWorkspace(workspaceId);
11362
- if (!stored) return;
11363
- const run = (stored.kissRuns ?? []).find((candidate) => candidate.jobId === job.id);
11364
- if (!run || run.status === "completed" || run.status === "failed") return;
11365
- failKissRun(stored, run.id, reason, kind, rejectedAnswer);
11366
- saveWorkspace(stored);
11455
+ mutateWorkspace(workspaceId, (stored) => {
11456
+ const run = (stored.kissRuns ?? []).find((candidate) => candidate.jobId === job.id);
11457
+ if (!run || run.status === "completed" || run.status === "failed") return;
11458
+ failKissRun(stored, run.id, reason, kind, rejectedAnswer);
11459
+ });
11367
11460
  }
11368
11461
  async function applyGuide(job, workspaceId, payload, observedModel) {
11369
11462
  const stored = loadWorkspace(workspaceId);
@@ -11372,18 +11465,22 @@ async function applyGuide(job, workspaceId, payload, observedModel) {
11372
11465
  try {
11373
11466
  applied = await applyGuideToContext(context, payload);
11374
11467
  } catch (error) {
11375
- if (error instanceof GuideRejected) saveWorkspace({
11376
- ...stored,
11377
- session: failSession(stored.session, error.message, "agent_output_invalid", error.answer)
11378
- });
11468
+ if (error instanceof GuideRejected) {
11469
+ const failed = failSession(stored.session, error.message, "agent_output_invalid", error.answer);
11470
+ mutateWorkspace(workspaceId, (fresh) => ({
11471
+ ...fresh,
11472
+ session: keepReviewerFields(fresh, failed)
11473
+ }));
11474
+ }
11379
11475
  throw error;
11380
11476
  }
11381
- saveWorkspace({
11382
- ...stored,
11383
- session: completeReviewSession(stored.session, applied.result, context, { run: await runProvenanceOf(job, observedModel) }),
11477
+ const session = completeReviewSession(stored.session, applied.result, context, { run: await runProvenanceOf(job, observedModel) });
11478
+ mutateWorkspace(workspaceId, (fresh) => ({
11479
+ ...fresh,
11480
+ session: keepReviewerFields(fresh, session),
11384
11481
  audit: applied.audit,
11385
11482
  referencedFiles: applied.referencedFiles
11386
- });
11483
+ }));
11387
11484
  }
11388
11485
  /**
11389
11486
  * How the run that just finished was made, as the session should record it.
@@ -11458,7 +11555,7 @@ async function recordKissRun(input) {
11458
11555
  jobId: job.id,
11459
11556
  audience: input.audience,
11460
11557
  reviewedSha: sha,
11461
- promptVersion: "2",
11558
+ promptVersion: "3",
11462
11559
  agentId: agent.id,
11463
11560
  ...input.requestedModel ? { requestedModel: input.requestedModel } : {}
11464
11561
  });
@@ -12557,11 +12654,7 @@ function mergeUpdateInto(fresh, updated) {
12557
12654
  const source = updated;
12558
12655
  for (const field of UPDATE_OWNED_FIELDS) if (field in updated) target[field] = source[field];
12559
12656
  else delete target[field];
12560
- const session = { ...updated.session };
12561
- const current = fresh.session;
12562
- for (const field of REVIEWER_SESSION_FIELDS) if (field in fresh.session) session[field] = current[field];
12563
- else delete session[field];
12564
- merged.session = session;
12657
+ merged.session = keepReviewerFields(fresh, updated.session);
12565
12658
  dropStaleChangeMap(merged);
12566
12659
  return merged;
12567
12660
  }
@@ -12991,4 +13084,4 @@ function lineageIds(id) {
12991
13084
  return [.../* @__PURE__ */ new Set([id, ...lineage.map((review) => review.id)])];
12992
13085
  }
12993
13086
  //#endregion
12994
- export { compactQueue as $, loadWorkspace as $t, createPrState as A, reviewerDispositions as An, followedBranch as At, toneOf as B, resolveModel as Bn, phasesFor as Bt, readEvents as C, queueStamp as Cn, claimRequestUrl as Ct, announceJob as D, isQuestionOutstanding as Dn, fillFileUrlTemplate as Dt, telemetryUploadConsent as E, isIssueOutstanding as En, remoteHost as Et, markAllRead as F, resolveTarget as Fn, isTerminal as Ft, extractJsonText as G, STORE_ROOT as Gn, isClaimed as Gt, withUsageRecorded as H, readAgentPreference as Hn, purposeOf as Ht, markRead as I, displayRef as In, loadJob as It, readMarker as J, agentById as Jn, indexKeptIds as Jt, ReviewBeingDeletedError as K, AGENT_IDS as Kn, followedRefName as Kt, pruneNotifications as L, isCommitReview as Ln, saveJob as Lt, eventName as M, describeAuthorship as Mn, allJobs as Mt, headline as N, WITHHELD_REASON as Nn, endedAt as Nt, branchOf as O, issuesOutstanding as On, checkCodeFreshness as Ot, listNotifications as P, kissOutcome as Pn, fail as Pt, activateQueued as Q, AgentUnavailableError as Qn, lineagePosition as Qt, readNotification as R, git as Rn, PHASES as Rt, startJob as S, queueRemove as Sn, writePortPreference as St, recordTelemetryUploadConsent as T, doneVerb as Tn, forgeFor as Tt, EXPLAIN_SIMPLY_PROMPT as U, writeAgentPreference as Un, clearClaim as Ut, unreadCount as V, clearAgentPreference as Vn, progressSteps as Vt, asString as W, CONFIG_PATH as Wn, driverGone as Wt, modelHelpLines as X, detectAgents as Xn, latestKissRun as Xt, removeWorktree as Y, agentFor as Yn, indexReviewGroups as Yt, relativeTime as Z, AgentCancelledError as Zn, lineageKeyFor as Zt, agentEnvOf as _, offersLifecycle as _n, MAX_WORKSPACE_PORT as _t, wasBlocked as a, reviewedCommit as an, ensureServer as at, reanalyseReview as b, queueAdd as bn, resolveWorkspacePort as bt, RefreshUnavailableError as c, touchWorkspace as cn, serverEntryExists as ct, refreshPrContext as d, LIFECYCLES as dn, workspaceUrl as dt, matchingWorkspaceIds as en, queueForReview as et, isUnchanged as f, activityLabel as fn, writeServerRecord as ft, runningJobs as g, lifecyclePill as gn, DEFAULT_WORKSPACE_PORT as gt, liveUpdateFor as h, lifecycleChip as hn, feedbackUrl as ht, liveJobsFor as i, recentWorkspaces as in, clearServerRecord as it, createPrUpdate as j, processDiscussion as jn, reviewedShaOf as jt, subjectOf as k, questionsOutstanding as kn, checkReview as kt, mergeUpdateInto as l, workspaceRevision as ln, spawnServer as lt, UpdateAlreadyRunningError as m, lifecycleAction as mn, PACKAGE_NAME as mt, deleteReview as n, positionInLineage as nn, readIndexToken as nt, discardJob as o, reviewedRepositories as on, readServerRecord as ot, askCheckout as p, isLifecycle as pn, BUILD_VERSION as pt, MANAGED_ROOT as q, DEFAULT_AGENT_ID as qn, groupByLineage as qt, lineageIds as r, previousKissResult as rn, bootstrapUrl as rt, FETCH_TIMEOUT_MS as s, summarise as sn, reviewsUrl as st, deleteLineage as t, mutateWorkspace as tn, settleQueue as tt, updateReview as u, workspaceStamps as un, stopServer as ut, recordKissRun as v, parseLifecycle as vn, MIN_WORKSPACE_PORT as vt, record as w, readQueue as wn, forgeResolver as wt, runJob as x, queueAddMany as xn, statedWorkspacePort as xt, startKissJob as y, sectionOf as yn, parseWorkspacePort as yt, removeNotification as z, resolveAgent as zn, isLiveJob as zt };
13087
+ export { compactQueue as $, agentById as $n, latestKissRun as $t, createPrState as A, isIssueOutstanding as An, followedBranch as At, toneOf as B, resolveTarget as Bn, phasesFor as Bt, readEvents as C, sectionOf as Cn, claimRequestUrl as Ct, announceJob as D, queueStamp as Dn, fillFileUrlTemplate as Dt, telemetryUploadConsent as E, queueRemove as En, remoteHost as Et, markAllRead as F, processDiscussion as Fn, isTerminal as Ft, extractJsonText as G, resolveModel as Gn, isClaimed as Gt, withUsageRecorded as H, isCommitReview as Hn, purposeOf as Ht, markRead as I, recommendationsOf as In, loadJob as It, readMarker as J, writeAgentPreference as Jn, groupByLineage as Jt, ReviewBeingDeletedError as K, clearAgentPreference as Kn, decideKissRecommendation as Kt, pruneNotifications as L, describeAuthorship as Ln, saveJob as Lt, eventName as M, issuesOutstanding as Mn, allJobs as Mt, headline as N, questionsOutstanding as Nn, endedAt as Nt, branchOf as O, readQueue as On, checkCodeFreshness as Ot, listNotifications as P, reviewerDispositions as Pn, fail as Pt, activateQueued as Q, DEFAULT_AGENT_ID as Qn, kissDecisionsOf as Qt, readNotification as R, WITHHELD_REASON as Rn, PHASES as Rt, startJob as S, parseLifecycle as Sn, writePortPreference as St, recordTelemetryUploadConsent as T, queueAddMany as Tn, forgeFor as Tt, EXPLAIN_SIMPLY_PROMPT as U, git as Un, clearClaim as Ut, unreadCount as V, displayRef as Vn, progressSteps as Vt, asString as W, resolveAgent as Wn, driverGone as Wt, modelHelpLines as X, STORE_ROOT as Xn, indexReviewGroups as Xt, removeWorktree as Y, CONFIG_PATH as Yn, indexKeptIds as Yt, relativeTime as Z, AGENT_IDS as Zn, kissDecisionRefusal as Zt, agentEnvOf as _, isLifecycle as _n, MAX_WORKSPACE_PORT as _t, wasBlocked as a, positionInLineage as an, ensureServer as at, reanalyseReview as b, lifecyclePill as bn, resolveWorkspacePort as bt, RefreshUnavailableError as c, recentWorkspaces as cn, serverEntryExists as ct, refreshPrContext as d, summarise as dn, workspaceUrl as dt, lineageKeyFor as en, agentFor as er, queueForReview as et, isUnchanged as f, touchWorkspace as fn, writeServerRecord as ft, runningJobs as g, activityLabel as gn, DEFAULT_WORKSPACE_PORT as gt, liveUpdateFor as h, LIFECYCLES as hn, feedbackUrl as ht, liveJobsFor as i, mutateWorkspace as in, clearServerRecord as it, createPrUpdate as j, isQuestionOutstanding as jn, reviewedShaOf as jt, subjectOf as k, doneVerb as kn, checkReview as kt, mergeUpdateInto as l, reviewedCommit as ln, spawnServer as lt, UpdateAlreadyRunningError as m, workspaceStamps as mn, PACKAGE_NAME as mt, deleteReview as n, loadWorkspace as nn, AgentCancelledError as nr, readIndexToken as nt, discardJob as o, presentedKissRunOf as on, readServerRecord as ot, askCheckout as p, workspaceRevision as pn, BUILD_VERSION as pt, MANAGED_ROOT as q, readAgentPreference as qn, followedRefName as qt, lineageIds as r, matchingWorkspaceIds as rn, AgentUnavailableError as rr, bootstrapUrl as rt, FETCH_TIMEOUT_MS as s, previousKissResult as sn, reviewsUrl as st, deleteLineage as t, lineagePosition as tn, detectAgents as tr, settleQueue as tt, updateReview as u, reviewedRepositories as un, stopServer as ut, recordKissRun as v, lifecycleAction as vn, MIN_WORKSPACE_PORT as vt, record as w, queueAdd as wn, forgeResolver as wt, runJob as x, offersLifecycle as xn, statedWorkspacePort as xt, startKissJob as y, lifecycleChip as yn, parseWorkspacePort as yt, removeNotification as z, kissOutcome as zn, isLiveJob as zt };
package/dist/main.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { $t as loadWorkspace, Bn as resolveModel, E as telemetryUploadConsent, Fn as resolveTarget, Ft as isTerminal, Gn as STORE_ROOT, Gt as isClaimed, Hn as readAgentPreference, Ht as purposeOf, In as displayRef, It as loadJob, J as readMarker, Jn as agentById, Kn as AGENT_IDS, Kt as followedRefName, Mt as allJobs, Nn as WITHHELD_REASON, Pn as kissOutcome, Rn as git, Rt as PHASES, S as startJob, St as writePortPreference, T as recordTelemetryUploadConsent, Un as writeAgentPreference, Ut as clearClaim, Vt as progressSteps, Wn as CONFIG_PATH, Wt as driverGone, X as modelHelpLines, Xn as detectAgents, Y as removeWorktree, Z as relativeTime, Zt as lineageKeyFor, _t as MAX_WORKSPACE_PORT, a as wasBlocked, at as ensureServer, b as reanalyseReview, dt as workspaceUrl, en as matchingWorkspaceIds, et as queueForReview, g as runningJobs, gt as DEFAULT_WORKSPACE_PORT, h as liveUpdateFor, i as liveJobsFor, in as recentWorkspaces, kt as checkReview, l as mergeUpdateInto, m as UpdateAlreadyRunningError, mt as PACKAGE_NAME, n as deleteReview$1, nn as positionInLineage, nt as readIndexToken, on as reviewedRepositories, pt as BUILD_VERSION, q as MANAGED_ROOT, qn as DEFAULT_AGENT_ID, qt as groupByLineage, rt as bootstrapUrl, sn as summarise, st as reviewsUrl, tn as mutateWorkspace, u as updateReview, ut as stopServer, v as recordKissRun, vt as MIN_WORKSPACE_PORT, w as record$1, wt as forgeResolver, x as runJob, xt as statedWorkspacePort, yt as parseWorkspacePort, zn as resolveAgent } from "./delete_review-BiV1aBpx.js";
2
+ import { $n as agentById, Bn as resolveTarget, E as telemetryUploadConsent, Ft as isTerminal, Gn as resolveModel, Gt as isClaimed, Ht as purposeOf, It as loadJob, J as readMarker, Jn as writeAgentPreference, Jt as groupByLineage, Mt as allJobs, Qn as DEFAULT_AGENT_ID, Rn as WITHHELD_REASON, Rt as PHASES, S as startJob, St as writePortPreference, T as recordTelemetryUploadConsent, Un as git, Ut as clearClaim, Vn as displayRef, Vt as progressSteps, Wn as resolveAgent, Wt as driverGone, X as modelHelpLines, Xn as STORE_ROOT, Y as removeWorktree, Yn as CONFIG_PATH, Z as relativeTime, Zn as AGENT_IDS, _t as MAX_WORKSPACE_PORT, a as wasBlocked, an as positionInLineage, at as ensureServer, b as reanalyseReview, cn as recentWorkspaces, dn as summarise, dt as workspaceUrl, en as lineageKeyFor, et as queueForReview, g as runningJobs, gt as DEFAULT_WORKSPACE_PORT, h as liveUpdateFor, i as liveJobsFor, in as mutateWorkspace, kt as checkReview, l as mergeUpdateInto, m as UpdateAlreadyRunningError, mt as PACKAGE_NAME, n as deleteReview$1, nn as loadWorkspace, nt as readIndexToken, pt as BUILD_VERSION, q as MANAGED_ROOT, qn as readAgentPreference, qt as followedRefName, rn as matchingWorkspaceIds, rt as bootstrapUrl, st as reviewsUrl, tr as detectAgents, u as updateReview, un as reviewedRepositories, ut as stopServer, v as recordKissRun, vt as MIN_WORKSPACE_PORT, w as record$1, wt as forgeResolver, x as runJob, xt as statedWorkspacePort, yt as parseWorkspacePort, zn as kissOutcome } from "./delete_review-DMJXD3bf.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";