mergestorm 0.3.52 → 0.3.53

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/README.md CHANGED
@@ -45,12 +45,12 @@ On a TTY, bare `mergestorm` (or `mergestorm shell`) opens a branded REPL: a comp
45
45
 
46
46
  ```
47
47
  ╭──────────────────────────────────────────────────────────────────────────────╮
48
- │ ▀▀▀▀▀▀▀▀▀▀▘ mergestorm v0.3.52 │
48
+ │ ▀▀▀▀▀▀▀▀▀▀▘ mergestorm v0.3.53 │
49
49
  │ ▀▀▀▀▀▀▀▀▀ ● msk_live_… · maelstrom │
50
50
  │ ▀▀▀▀▀▀ [████████░░░░░░░░░░░░░░░░░░░░░░] 25% used │
51
51
  │ ▝▀▀▀▀▀ local reviews + stacked PRs · mergestorm.ai │
52
52
  │ ▝▀▀▘ review a diff · usage for tabs · /help for all commands │
53
- │ ▀ New in v0.3.52: Sign-in errors name the agent login │
53
+ │ ▀ New in v0.3.53: Busy queue no longer reads as stuck │
54
54
  ╰──────────────────────────────────────────────────────────────────────────────╯
55
55
  mergestorm
56
56
  ╭──────────────────────────────────────────────────────────────────────────────╮
@@ -199,6 +199,7 @@ export type MergeQueueWait = {
199
199
  waitReason: string | null;
200
200
  aheadStackId: string | null;
201
201
  aheadOther: boolean;
202
+ idleSince?: string | null;
202
203
  };
203
204
  export declare function mergeQueueWait(queue: readonly MergeQueueEntryDto[], nowMs: number): MergeQueueWait | null;
204
205
  export declare function conflictLiveParent(stack: StackDto, layer: StackLayerDto): string | null;
@@ -102,7 +102,7 @@ const CYCLONE_HANDOFF_WORDS = {
102
102
  ci_red_on_base: "the same check also fails on the base branch",
103
103
  ci_rerun_exhausted: "Cyclone already had Surge re-run this check once at this head",
104
104
  ci_rerun_unavailable: "the failure looked flaky and Surge could not re-run it",
105
- ci_unverified: "Cyclone could not confirm a fix locally, so it pushed nothing",
105
+ ci_unverified: "Cyclone's static checks did not cover its fix, so it pushed nothing",
106
106
  ci_unreadable: "Cyclone could not read the failing checks",
107
107
  ci_needs_actions_read: "Cyclone's GitHub App cannot read the Actions logs on this repo",
108
108
  ci_unresolved: "Cyclone's CI fix failed",
@@ -520,11 +520,22 @@ export function mergeQueueWait(queue, nowMs) {
520
520
  const queuedFor = minutesOf(queuedMs);
521
521
  const ahead = entry.aheadInRepo;
522
522
  if (!ahead) {
523
+ const progressAt = entry.repoQueue?.progressAt ?? null;
524
+ const progressMs = progressAt ? waitedMs(progressAt, nowMs) : null;
525
+ const idleMs = queuedMs != null && progressMs != null ? Math.min(queuedMs, progressMs) : queuedMs;
526
+ const queuedAhead = entry.repoQueue?.queuedAhead ?? 0;
527
+ const turn = queuedAhead > 0
528
+ ? `behind ${queuedAhead} older queued ${queuedAhead === 1 ? "entry" : "entries"}`
529
+ : "not picked up yet";
530
+ const moved = progressMs != null && queuedMs != null && progressMs < queuedMs
531
+ ? `; the queue last moved ${minutesOf(progressMs)}m ago`
532
+ : "";
523
533
  return {
524
- text: `Queued ${queuedFor}m in the merge queue, not picked up yet${reason ? ` (last note: ${reason})` : ""}`,
525
- stalled: queuedMs != null && queuedMs >= MERGE_QUEUE_STALL_ATTENTION_MS,
534
+ text: `Queued ${queuedFor}m in the merge queue, ${turn}${moved}${reason ? ` (last note: ${reason})` : ""}`,
535
+ stalled: idleMs != null && idleMs >= MERGE_QUEUE_STALL_ATTENTION_MS,
526
536
  notPickedUp: true,
527
537
  since: entry.enqueuedAt, waitReason: reason, aheadStackId: null, aheadOther: false,
538
+ idleSince: moved ? progressAt : null,
528
539
  };
529
540
  }
530
541
  const aheadMs = ahead.claimedAt ? waitedMs(ahead.claimedAt, nowMs) : null;
@@ -554,7 +565,7 @@ function queueStalledSteps(stack, layer, wait) {
554
565
  return `#${layer.prNumber} is waiting in the merge queue behind another entry in ${stack.owner}/${stack.repo} that has made no progress since ${wait.since ?? "it was claimed"}. Nothing on ${layer.branch} needs a change. ${ahead} If it stays stuck, tell the human: the queue for this repo is held by that entry.`;
555
566
  }
556
567
  if (wait.notPickedUp) {
557
- return `#${layer.prNumber} has been queued in the merge queue for ${stack.owner}/${stack.repo} since ${wait.since ?? "it was enqueued"} and nothing is working on it or on an entry ahead of it${wait.waitReason ? `; its last note is: ${wait.waitReason}` : ""}. Nothing on ${layer.branch} needs a change: do not patch or push for this. If the note says the base branch keeps moving, the queue is waiting for a quiet moment on it and continues by itself once pushes to that branch pause. Otherwise tell the human: the merge queue is not picking this entry up; they can take the stack out of the queue and enqueue it again (mg queue rm ${stack.id}, then mg queue add ${stack.id}). Do not retarget the PR base.`;
568
+ return `#${layer.prNumber} has been queued in the merge queue for ${stack.owner}/${stack.repo} since ${wait.since ?? "it was enqueued"} and nothing is working on it or on an entry ahead of it${wait.idleSince ? `: the queue last claimed or finished an entry at ${wait.idleSince}` : ""}${wait.waitReason ? `; its last note is: ${wait.waitReason}` : ""}. Nothing on ${layer.branch} needs a change: do not patch or push for this. If the note says the base branch keeps moving, the queue is waiting for a quiet moment on it and continues by itself once pushes to that branch pause. Otherwise tell the human: the merge queue is not picking this entry up; they can take the stack out of the queue and enqueue it again (mg queue rm ${stack.id}, then mg queue add ${stack.id}). Do not retarget the PR base.`;
558
569
  }
559
570
  return `The merge queue has held #${layer.prNumber} at ${layer.headSha ?? "its head"} since ${wait.since ?? "it was claimed"} without landing or bouncing it${wait.waitReason ? `; its last note is: ${wait.waitReason}` : ", and it recorded no reason"}. If the note names a failing check or a conflict on ${layer.branch}, fix that with an ordinary push. If it waits on CI, list the head's checks (gh run list --branch ${layer.branch}) and re-run the one that never finished (gh run rerun <run-id>). If nothing moves after that, tell the human: they can take the stack out of the queue and enqueue it again (mg queue rm ${stack.id}, then mg queue add ${stack.id}). Do not retarget the PR base.`;
560
571
  }
@@ -457,6 +457,10 @@ export type MergeQueueAheadDto = {
457
457
  claimedAt: string | null;
458
458
  waitReason: string | null;
459
459
  };
460
+ export type MergeQueueRepoQueueDto = {
461
+ queuedAhead: number;
462
+ progressAt: string | null;
463
+ };
460
464
  export type MergeQueueEntryDto = {
461
465
  id: string;
462
466
  stackId: string;
@@ -482,4 +486,5 @@ export type MergeQueueEntryDto = {
482
486
  finishedAt: string | null;
483
487
  claimedAt?: string | null;
484
488
  aheadInRepo?: MergeQueueAheadDto | null;
489
+ repoQueue?: MergeQueueRepoQueueDto | null;
485
490
  };
package/dist/ui/banner.js CHANGED
@@ -194,6 +194,9 @@ const WHATS_NEW = {
194
194
  "0.3.52": [
195
195
  "Sign-in errors name the agent login",
196
196
  ],
197
+ "0.3.53": [
198
+ "Busy queue no longer reads as stuck",
199
+ ],
197
200
  };
198
201
  function densityFromVariant(variant) {
199
202
  if (variant === "mini" || variant === "nano")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mergestorm",
3
- "version": "0.3.52",
3
+ "version": "0.3.53",
4
4
  "description": "Mergestorm CLI (mg) — local reviews & stacked PRs. MIT; build from source: https://github.com/marginsystems/mergestorm-cli",
5
5
  "license": "MIT",
6
6
  "type": "module",