opencode-magi 0.0.0-dev-20260522221334 → 0.0.0-dev-20260522222915

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.
@@ -650,6 +650,17 @@ export async function waitForMergeQueue(exec, repository, pr, intervalMs = 30_00
650
650
  await new Promise((resolve) => setTimeout(resolve, intervalMs));
651
651
  }
652
652
  }
653
+ export async function waitForAutoMerge(exec, repository, pr, intervalMs = 30_000) {
654
+ for (;;) {
655
+ const status = await fetchPullRequestMergeStatus(exec, repository, pr);
656
+ if (status.state === "MERGED")
657
+ return "merged";
658
+ if (status.state !== "OPEN" || status.autoMergeRequest == null) {
659
+ return "dequeued";
660
+ }
661
+ await new Promise((resolve) => setTimeout(resolve, intervalMs));
662
+ }
663
+ }
653
664
  export async function closePullRequest(exec, repository, pr, account) {
654
665
  const token = await ghToken(exec, repository, account);
655
666
  return exec(`gh pr close ${pr} --repo ${shellQuote(repoSpecifier(repository))}`, ghTokenEnv(token));
@@ -1,7 +1,7 @@
1
1
  import { mkdir, writeFile } from "node:fs/promises";
2
2
  import { join } from "node:path";
3
3
  import { prRunOutputDir } from "../config/output";
4
- import { closePullRequest, configureGitIdentity, fetchMergeQueueRequirement, fetchPullRequest, fetchUnresolvedThreads, mergePullRequest, postApproval, postChangesRequested, postCloseComment, postReply, pushHead, removeWorktree, resolveThread, waitForMergeQueue, } from "../github/commands";
4
+ import { closePullRequest, configureGitIdentity, fetchMergeQueueRequirement, fetchPullRequest, fetchUnresolvedThreads, mergePullRequest, postApproval, postChangesRequested, postCloseComment, postReply, pushHead, removeWorktree, resolveThread, waitForAutoMerge, waitForMergeQueue, } from "../github/commands";
5
5
  import { composeEditPrompt, composeRereviewCloseReconsiderationPrompt, composeRereviewPrompt, } from "../prompts/compose";
6
6
  import { parseEditOutput, parseRereviewCloseReconsiderationOutput, parseRereviewOutput, } from "../prompts/output";
7
7
  import { throwIfAborted, withAbortSignal } from "./abort";
@@ -426,8 +426,11 @@ async function finishMergeRun(input, result, reportInput) {
426
426
  }
427
427
  async function mergeWithQueue(input, exec, editorAccount) {
428
428
  await mergePullRequest(exec, input.repository, input.pr, editorAccount);
429
- if (!input.repository.merge.mergeQueue)
430
- return "merged";
429
+ if (!input.repository.merge.mergeQueue) {
430
+ if (!input.repository.merge.auto)
431
+ return "merged";
432
+ return waitForAutoMerge(exec, input.repository, input.pr);
433
+ }
431
434
  return waitForMergeQueue(exec, input.repository, input.pr);
432
435
  }
433
436
  export function hasBlockingCiReports(reports) {
@@ -1,10 +1,10 @@
1
1
  import { mkdir, writeFile } from "node:fs/promises";
2
2
  import { join } from "node:path";
3
3
  import { createWorktree, fetchPullRequest, fetchPullRequestCommits, fetchPullRequestReviews, fetchUnresolvedThreads, closePullRequest, mergePullRequest, ensurePullRequestCommits, postApproval, postChangesRequested, postCloseComment, postReply, removeWorktree, resolveThread, shellQuote, } from "../github/commands";
4
- import { composeFindingValidationPrompt, composeCloseReconsiderationPrompt, composeRereviewPrompt, composeReviewPrompt, } from "../prompts/compose";
4
+ import { composeFindingValidationPrompt, composeCloseReconsiderationPrompt, composeRereviewCloseReconsiderationPrompt, composeRereviewPrompt, composeReviewPrompt, } from "../prompts/compose";
5
5
  import { prRunOutputDir } from "../config/output";
6
6
  import { prRunWorktreeDir } from "../config/worktree";
7
- import { parseCloseReconsiderationOutput, parseFindingValidationOutput, parseRereviewOutput, parseReviewOutput, } from "../prompts/output";
7
+ import { parseCloseReconsiderationOutput, parseFindingValidationOutput, parseRereviewCloseReconsiderationOutput, parseRereviewOutput, parseReviewOutput, } from "../prompts/output";
8
8
  import { throwIfAborted, withAbortSignal } from "./abort";
9
9
  import { waitForChecksWithClassification } from "./ci";
10
10
  import { parseRightSideDiffTargets, validateInlineCommentTargets, } from "./inline-comments";
@@ -413,27 +413,49 @@ async function runCloseReconsideration(input) {
413
413
  type: "phase",
414
414
  });
415
415
  return Promise.all(input.entries.map(async (entry) => {
416
- if (!targets.includes(entry.key) || !isReviewOutput(entry.value)) {
416
+ if (!targets.includes(entry.key)) {
417
417
  return entry;
418
418
  }
419
419
  const reviewer = input.reviewInput.repository.agents.reviewers.find((item) => item.key === entry.key);
420
420
  if (!reviewer)
421
421
  return entry;
422
422
  const hasReviewerSession = Boolean(input.sessionIds[reviewer.key]);
423
- const prompt = await composeCloseReconsiderationPrompt({
424
- baseSha: input.meta.baseRefOid,
425
- ciFailureContext: undefined,
426
- closeReason: entry.value.reason,
427
- directory: input.reviewInput.directory,
428
- headSha: input.meta.headRefOid,
429
- includeReviewGuidelines: !hasReviewerSession,
430
- includeSessionContext: !hasReviewerSession,
431
- pr: input.reviewInput.pr,
432
- repository: input.reviewInput.repository,
433
- reviewContext: input.reviewContext,
434
- reviewer,
435
- worktreePath: input.worktreePath,
436
- });
423
+ const isReviewEntry = isReviewOutput(entry.value);
424
+ let prompt;
425
+ if (isReviewEntry) {
426
+ prompt = await composeCloseReconsiderationPrompt({
427
+ baseSha: input.meta.baseRefOid,
428
+ ciFailureContext: undefined,
429
+ closeReason: entry.value.reason,
430
+ directory: input.reviewInput.directory,
431
+ headSha: input.meta.headRefOid,
432
+ includeReviewGuidelines: !hasReviewerSession,
433
+ includeSessionContext: !hasReviewerSession,
434
+ pr: input.reviewInput.pr,
435
+ repository: input.reviewInput.repository,
436
+ reviewContext: input.reviewContext,
437
+ reviewer,
438
+ worktreePath: input.worktreePath,
439
+ });
440
+ }
441
+ else {
442
+ if (!entry.previousHeadSha) {
443
+ throw new Error(`Missing previous review commit for ${reviewer.account}`);
444
+ }
445
+ prompt = await composeRereviewCloseReconsiderationPrompt({
446
+ baseSha: input.meta.baseRefOid,
447
+ closeReason: entry.value.reason,
448
+ directory: input.reviewInput.directory,
449
+ headSha: input.meta.headRefOid,
450
+ includeReviewGuidelines: !hasReviewerSession,
451
+ includeSessionContext: !hasReviewerSession,
452
+ pr: input.reviewInput.pr,
453
+ previousHeadSha: entry.previousHeadSha,
454
+ repository: input.reviewInput.repository,
455
+ reviewer,
456
+ worktreePath: input.worktreePath,
457
+ });
458
+ }
437
459
  const result = await withReviewerFailureProgress({
438
460
  onProgress: input.reviewInput.onProgress,
439
461
  reviewer: reviewer.key,
@@ -466,14 +488,19 @@ async function runCloseReconsideration(input) {
466
488
  options: reviewer.options,
467
489
  parentSessionId: input.reviewInput.parentSessionId,
468
490
  parse: (text) => {
469
- const output = parseCloseReconsiderationOutput(text);
470
- validateInlineCommentTargets(output.findings, entry.inlineCommentTargets);
491
+ const output = isReviewEntry
492
+ ? parseCloseReconsiderationOutput(text)
493
+ : parseRereviewCloseReconsiderationOutput(text);
494
+ const findings = "newFindings" in output ? output.newFindings : output.findings;
495
+ validateInlineCommentTargets(findings, entry.inlineCommentTargets, "newFindings" in output ? "newFindings" : "findings");
471
496
  return output;
472
497
  },
473
498
  permission: reviewer.permission,
474
499
  prompt,
475
500
  repairAttempts: input.reviewInput.config.output?.repairAttempts ?? 3,
476
- schemaName: "close reconsideration",
501
+ schemaName: isReviewEntry
502
+ ? "close reconsideration"
503
+ : "rereview close reconsideration",
477
504
  sessionId: input.sessionIds[reviewer.key],
478
505
  signal: input.reviewInput.signal,
479
506
  title: `magi reconsider close ${input.reviewInput.repository.alias}#${input.reviewInput.pr} ${reviewer.key}`,
@@ -498,6 +525,7 @@ async function runCloseReconsideration(input) {
498
525
  return {
499
526
  inlineCommentTargets: entry.inlineCommentTargets,
500
527
  key: entry.key,
528
+ previousHeadSha: entry.previousHeadSha,
501
529
  raw: result.raw,
502
530
  sessionId: result.sessionId,
503
531
  value: result.value,
@@ -780,6 +808,7 @@ export async function runReview(input) {
780
808
  return {
781
809
  inlineCommentTargets,
782
810
  key: reviewer.key,
811
+ previousHeadSha: previous.commit.oid,
783
812
  raw: result.raw,
784
813
  sessionId: result.sessionId,
785
814
  value: result.value,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-magi",
3
- "version": "0.0.0-dev-20260522221334",
3
+ "version": "0.0.0-dev-20260522222915",
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>",