opencode-magi 0.0.0-dev-20260630073228 → 0.0.0-dev-20260630075940
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/dist/magi.js +19 -3
- package/dist/tools/review/action.js +28 -24
- package/package.json +1 -1
package/dist/magi.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { createOpencodeClient } from "@opencode-ai/sdk/v2";
|
|
2
2
|
import { print } from "graphql";
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
|
-
import { mkdir, readdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
5
|
-
import { dirname, isAbsolute, join } from "node:path";
|
|
4
|
+
import { mkdir, readdir, readFile, rm, rmdir, writeFile, } from "node:fs/promises";
|
|
5
|
+
import { dirname, isAbsolute, join, relative } from "node:path";
|
|
6
6
|
import { Octokit } from "octokit";
|
|
7
7
|
import { getConfig, resolvePermissions, validateConfig } from "@/config";
|
|
8
8
|
import { graphql } from "@/graphql";
|
|
@@ -309,7 +309,23 @@ export class Magi {
|
|
|
309
309
|
}
|
|
310
310
|
async deleteOutput(path) {
|
|
311
311
|
try {
|
|
312
|
-
|
|
312
|
+
const resolvedPath = this.getPath(path);
|
|
313
|
+
await rm(resolvedPath, { force: true, recursive: true });
|
|
314
|
+
let dir = dirname(resolvedPath);
|
|
315
|
+
while (dir !== this.input.directory) {
|
|
316
|
+
const value = relative(this.input.directory, dir);
|
|
317
|
+
if (!value || value.startsWith("..") || isAbsolute(value))
|
|
318
|
+
break;
|
|
319
|
+
try {
|
|
320
|
+
if ((await readdir(dir)).length)
|
|
321
|
+
break;
|
|
322
|
+
await rmdir(dir);
|
|
323
|
+
}
|
|
324
|
+
catch {
|
|
325
|
+
break;
|
|
326
|
+
}
|
|
327
|
+
dir = dirname(dir);
|
|
328
|
+
}
|
|
313
329
|
return 1;
|
|
314
330
|
}
|
|
315
331
|
catch {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { MagiError } from "@/magi";
|
|
2
2
|
import { Prompt } from "@/prompts";
|
|
3
|
-
import { command, filterEmpty, isArray, isObject, isString, loop, marker, omitNullish, quote, retry, Worker, } from "@/utils";
|
|
3
|
+
import { command, filterEmpty, isArray, isObject, isString, loop, marker, omitNullish, quote, retry, wait, Worker, } from "@/utils";
|
|
4
4
|
const events = {
|
|
5
5
|
APPROVED: "APPROVE",
|
|
6
6
|
CHANGES_REQUESTED: "REQUEST_CHANGES",
|
|
@@ -247,29 +247,7 @@ export async function automate() {
|
|
|
247
247
|
this.state = await this.magi.updateState(this.state.output, {
|
|
248
248
|
text: `Waiting for merge queue for ${this.getLink()}.`,
|
|
249
249
|
});
|
|
250
|
-
const result = await
|
|
251
|
-
this.context.abort.throwIfAborted();
|
|
252
|
-
const { repository } = await this.graphql.mergeQueueStatus({
|
|
253
|
-
owner: this.config.github.owner,
|
|
254
|
-
pr: this.number,
|
|
255
|
-
repo: this.config.github.repo,
|
|
256
|
-
});
|
|
257
|
-
if (!repository?.pullRequest)
|
|
258
|
-
throw new MagiError("blocked", "Could not fetch merge queue status.");
|
|
259
|
-
const { isInMergeQueue, mergeQueueEntry, state } = repository.pullRequest;
|
|
260
|
-
if (state === "MERGED")
|
|
261
|
-
return "MERGED";
|
|
262
|
-
if (state === "OPEN" && !isInMergeQueue && !mergeQueueEntry) {
|
|
263
|
-
if (await isConflict.call(this)) {
|
|
264
|
-
this.state = await this.magi.updateState(this.state.output, {
|
|
265
|
-
pr: { automation: "CONFLICT" },
|
|
266
|
-
text: `Merge automation found conflicts for ${this.getLink()}.`,
|
|
267
|
-
});
|
|
268
|
-
return "CONFLICT";
|
|
269
|
-
}
|
|
270
|
-
throw new MagiError("blocked", `PR left the merge queue before merging ${this.getLink()}.`);
|
|
271
|
-
}
|
|
272
|
-
}, 30_000);
|
|
250
|
+
const result = await waitMergeQueue.call(this);
|
|
273
251
|
if (result === "CONFLICT")
|
|
274
252
|
return result;
|
|
275
253
|
}
|
|
@@ -405,6 +383,32 @@ function getCheckTime(check) {
|
|
|
405
383
|
return Number.isNaN(time) ? prev : Math.max(prev, time);
|
|
406
384
|
}, 0);
|
|
407
385
|
}
|
|
386
|
+
async function waitMergeQueue(leftMergeQueue = false) {
|
|
387
|
+
this.context.abort.throwIfAborted();
|
|
388
|
+
const { repository } = await this.graphql.mergeQueueStatus({
|
|
389
|
+
owner: this.config.github.owner,
|
|
390
|
+
pr: this.number,
|
|
391
|
+
repo: this.config.github.repo,
|
|
392
|
+
});
|
|
393
|
+
if (!repository?.pullRequest)
|
|
394
|
+
throw new MagiError("blocked", "Could not fetch merge queue status.");
|
|
395
|
+
const { isInMergeQueue, mergeQueueEntry, state } = repository.pullRequest;
|
|
396
|
+
if (state === "MERGED")
|
|
397
|
+
return "MERGED";
|
|
398
|
+
const nextLeftMergeQueue = state === "OPEN" && !isInMergeQueue && !mergeQueueEntry;
|
|
399
|
+
if (leftMergeQueue && nextLeftMergeQueue) {
|
|
400
|
+
if (await isConflict.call(this)) {
|
|
401
|
+
this.state = await this.magi.updateState(this.state.output, {
|
|
402
|
+
pr: { automation: "CONFLICT" },
|
|
403
|
+
text: `Merge automation found conflicts for ${this.getLink()}.`,
|
|
404
|
+
});
|
|
405
|
+
return "CONFLICT";
|
|
406
|
+
}
|
|
407
|
+
throw new MagiError("blocked", `PR left the merge queue before merging ${this.getLink()}.`);
|
|
408
|
+
}
|
|
409
|
+
await wait(30_000);
|
|
410
|
+
return await waitMergeQueue.call(this, nextLeftMergeQueue);
|
|
411
|
+
}
|
|
408
412
|
async function isConflict() {
|
|
409
413
|
if (!this.state.worktree)
|
|
410
414
|
return false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-magi",
|
|
3
|
-
"version": "0.0.0-dev-
|
|
3
|
+
"version": "0.0.0-dev-20260630075940",
|
|
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>",
|