opencode-magi 0.0.0-dev-20260722060754 → 0.0.0-dev-20260722111427

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.
@@ -52,6 +52,14 @@ export const MergeQueueStatusDocument = gql `
52
52
  mergeQueueEntry {
53
53
  id
54
54
  }
55
+ timelineItems(last: 1, itemTypes: REMOVED_FROM_MERGE_QUEUE_EVENT) {
56
+ nodes {
57
+ ... on RemovedFromMergeQueueEvent {
58
+ createdAt
59
+ reason
60
+ }
61
+ }
62
+ }
55
63
  }
56
64
  }
57
65
  }
@@ -232,9 +232,10 @@ export async function automate() {
232
232
  if (action === "merge" && this.config.review.merge.queue) {
233
233
  const octokit = await this.magi.createOctokit(this.config, this.context.abort, account);
234
234
  const graphql = this.magi.createGraphql(octokit);
235
+ const enqueuedAt = new Date().toISOString();
235
236
  await graphql.enqueuePullRequest({ id: this.state.pr.metadata.node_id });
236
237
  await this.updateEvent(`Waiting for merge queue.`);
237
- const result = await waitMergeQueue.call(this);
238
+ const result = await waitMergeQueue.call(this, enqueuedAt);
238
239
  if (result === "CONFLICT")
239
240
  return result;
240
241
  }
@@ -358,8 +359,10 @@ function getCheckTime(check) {
358
359
  return Number.isNaN(time) ? prev : Math.max(prev, time);
359
360
  }, 0);
360
361
  }
361
- async function waitMergeQueue(leftMergeQueue = false) {
362
+ async function waitMergeQueue(enqueuedAt, leftMergeQueue = false, retries = 0) {
362
363
  this.context.abort.throwIfAborted();
364
+ if (!this.state.pr?.metadata)
365
+ throw new MagiError("blocked", "PR metadata not found.");
363
366
  const { repository } = await this.graphql.mergeQueueStatus({
364
367
  owner: this.config.github.owner,
365
368
  pr: this.number,
@@ -367,20 +370,33 @@ async function waitMergeQueue(leftMergeQueue = false) {
367
370
  });
368
371
  if (!repository?.pullRequest)
369
372
  throw new MagiError("blocked", "Could not fetch merge queue status.");
370
- const { isInMergeQueue, mergeQueueEntry, state } = repository.pullRequest;
373
+ const { isInMergeQueue, mergeQueueEntry, state, timelineItems } = repository.pullRequest;
371
374
  if (state === "MERGED")
372
375
  return "MERGED";
373
376
  const nextLeftMergeQueue = state === "OPEN" && !isInMergeQueue && !mergeQueueEntry;
374
377
  if (leftMergeQueue && nextLeftMergeQueue) {
375
378
  if (await isConflict.call(this)) {
376
379
  await this.updateState({ pr: { automation: "CONFLICT" } });
377
- await this.updateEvent(`Merge automation found conflicts.`);
380
+ await this.updateEvent("Merge automation found conflicts.");
378
381
  return "CONFLICT";
379
382
  }
383
+ const removedFromQueue = timelineItems.nodes?.at(-1);
384
+ if (removedFromQueue?.reason === "failed_checks" &&
385
+ Date.parse(removedFromQueue.createdAt) >= Date.parse(enqueuedAt)) {
386
+ if (retries >= this.config.review.checks.retryFailedJobs)
387
+ throw new MagiError("blocked", `PR left the merge queue after failed checks exceeded ${retries} retries.`);
388
+ const attempt = retries + 1;
389
+ const nextEnqueuedAt = new Date().toISOString();
390
+ await this.updateEvent(`Attempt ${attempt} failed to merge from the merge queue. Retrying...`);
391
+ await this.graphql.enqueuePullRequest({
392
+ id: this.state.pr.metadata.node_id,
393
+ });
394
+ return await waitMergeQueue.call(this, nextEnqueuedAt, false, attempt);
395
+ }
380
396
  throw new MagiError("blocked", `PR left the merge queue before merging.`);
381
397
  }
382
398
  await wait(30_000, this.context.abort);
383
- return await waitMergeQueue.call(this, nextLeftMergeQueue);
399
+ return await waitMergeQueue.call(this, enqueuedAt, nextLeftMergeQueue, retries);
384
400
  }
385
401
  async function isConflict() {
386
402
  if (!this.state.worktree)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-magi",
3
- "version": "0.0.0-dev-20260722060754",
3
+ "version": "0.0.0-dev-20260722111427",
4
4
  "description": "Multi-agent PR review and merge orchestration plugin for OpenCode.",
5
5
  "license": "MIT",
6
6
  "author": "Hirotomo Yamada <hirotomo.yamada@avap.co.jp>",