opencode-magi 0.0.0-dev-20260525154011 → 0.0.0-dev-20260525165911

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
@@ -64,20 +64,18 @@ Add the following content to the configuration file.
64
64
  "agents": {
65
65
  "refs": {
66
66
  "account-1": {
67
- "model": "openai/gpt-5.5",
68
- "account": "account-1"
67
+ "model": "openai/gpt-5.5"
69
68
  },
70
69
  "account-2": {
71
- "model": "anthropic/claude-opus-4-7",
72
- "account": "account-2"
70
+ "model": "anthropic/claude-opus-4-7"
73
71
  },
74
72
  "account-3": {
75
- "model": "opencode/kimi-k2-6",
76
- "account": "account-3"
73
+ "model": "opencode/kimi-k2-6"
77
74
  }
78
75
  }
79
76
  },
80
77
  "review": {
78
+ "account": "your-account",
81
79
  "reviewers": [
82
80
  { "ref": "account-1" },
83
81
  { "ref": "account-2" },
@@ -87,19 +85,22 @@ Add the following content to the configuration file.
87
85
  }
88
86
  ```
89
87
 
90
- After `refs` are expanded, `review.reviewers[].account` is the GitHub account used to post reviews and approvals in the default `review.mode: "multi"`. Must be authenticated with `gh auth token --user <account>` and must be unique.
88
+ By default, `review.mode` is `"single"`. Magi uses one `review.account` to post reviewer-originated GitHub mutations while still running multiple logical reviewer agents and preserving majority voting, finding validation, and close reconsideration. The account must be authenticated with `gh auth token --user <account>`.
91
89
 
92
- For individual setups, use `review.mode: "single"` with one `review.account`. Magi still runs an odd number of at least 3 logical reviewer agents and keeps majority voting, finding validation, and close reconsideration, but GitHub branch protection sees only the one configured review account.
90
+ For team setups that need separate GitHub review identities, set `review.mode: "multi"` and configure a unique account for each reviewer.
93
91
 
94
92
  ```json
95
93
  {
96
94
  "review": {
97
- "mode": "single",
98
- "account": "your-account",
95
+ "mode": "multi",
99
96
  "reviewers": [
100
- { "id": "general", "model": "openai/gpt-5.5" },
101
- { "id": "security", "model": "anthropic/claude-opus-4-7" },
102
- { "id": "compat", "model": "opencode/kimi-k2-6" }
97
+ { "id": "general", "model": "openai/gpt-5.5", "account": "account-1" },
98
+ {
99
+ "id": "security",
100
+ "model": "anthropic/claude-opus-4-7",
101
+ "account": "account-2"
102
+ },
103
+ { "id": "compat", "model": "opencode/kimi-k2-6", "account": "account-3" }
103
104
  ]
104
105
  }
105
106
  }
@@ -113,7 +113,9 @@ export function resolveAgents(config) {
113
113
  const agents = config.agents ?? {};
114
114
  const editor = config.merge?.editor;
115
115
  const creator = config.triage?.creator;
116
- const singleReviewAccount = config.review?.mode === "single" ? config.review.account : undefined;
116
+ const singleReviewAccount = config.review && config.review.mode !== "multi"
117
+ ? config.review.account
118
+ : undefined;
117
119
  return {
118
120
  editor: editor
119
121
  ? {
@@ -208,7 +210,7 @@ export function resolveRepository(config) {
208
210
  },
209
211
  review: {
210
212
  account: config.review?.account,
211
- mode: config.review?.mode ?? "multi",
213
+ mode: config.review?.mode ?? "single",
212
214
  },
213
215
  reviewAutomation: {
214
216
  close: config.review?.automation?.close ?? false,
@@ -386,7 +386,7 @@ function validateAndNormalizeModel(target, path, errors, catalog) {
386
386
  }
387
387
  errors.push(`${path} must contain at least one usable OpenCode model candidate${candidateErrors.length ? ` (${candidateErrors.join("; ")})` : ""}`);
388
388
  }
389
- function validateReviewerList(reviewers, path, errors, catalog, mode = "multi") {
389
+ function validateReviewerList(reviewers, path, errors, catalog, mode = "single") {
390
390
  if (reviewers == null)
391
391
  return;
392
392
  if (!Array.isArray(reviewers)) {
@@ -456,7 +456,7 @@ function validateTriageAgentList(voters, path, errors, catalog) {
456
456
  }
457
457
  });
458
458
  }
459
- function validateResolvedReviewers(reviewers, path, errors, mode = "multi") {
459
+ function validateResolvedReviewers(reviewers, path, errors, mode = "single") {
460
460
  const keys = new Set();
461
461
  const accounts = new Set();
462
462
  for (const reviewer of reviewers) {
@@ -469,7 +469,7 @@ function validateResolvedReviewers(reviewers, path, errors, mode = "multi") {
469
469
  }
470
470
  }
471
471
  function reviewMode(config) {
472
- return config.review?.mode === "single" ? "single" : "multi";
472
+ return config.review?.mode === "multi" ? "multi" : "single";
473
473
  }
474
474
  function validateReviewIdentity(config, errors) {
475
475
  const mode = config.review?.mode;
@@ -477,7 +477,7 @@ function validateReviewIdentity(config, errors) {
477
477
  errors.push("review.mode must be multi or single");
478
478
  }
479
479
  validateString(config.review?.account, "review.account", errors);
480
- if (mode === "single" && !config.review?.account) {
480
+ if ((mode == null || mode === "single") && !config.review?.account) {
481
481
  errors.push("review.account is required when review.mode is single");
482
482
  }
483
483
  }
@@ -213,7 +213,7 @@ async function runRereview(input, worktreePath, previousHeadSha, cycle, sessionI
213
213
  worktreePath,
214
214
  });
215
215
  const artifactDir = outputDir(input);
216
- const singleReviewMode = input.repository.review?.mode === "single";
216
+ const singleReviewMode = input.repository.review?.mode !== "multi";
217
217
  const reviewerKeys = input.repository.agents.reviewers.map((reviewer) => reviewer.key);
218
218
  const singleModeThreads = singleReviewMode
219
219
  ? assignThreadsByReviewFindingMarker({
@@ -16,7 +16,7 @@ import { formatReviewReport } from "./report";
16
16
  import { buildReviewContextSnapshot, renderReviewContext, } from "./review-context";
17
17
  import { checkSafetyGate, hasSafetyGate } from "./safety";
18
18
  function resolvedReviewMode(repository) {
19
- return repository.review?.mode === "single" ? "single" : "multi";
19
+ return repository.review?.mode === "multi" ? "multi" : "single";
20
20
  }
21
21
  export function reviewPostingAccount(repository, reviewer) {
22
22
  return resolvedReviewMode(repository) === "single"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-magi",
3
- "version": "0.0.0-dev-20260525154011",
3
+ "version": "0.0.0-dev-20260525165911",
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>",
@@ -28,26 +28,26 @@
28
28
  "schema.json"
29
29
  ],
30
30
  "dependencies": {
31
- "@opencode-ai/plugin": "^1.15.5",
31
+ "@opencode-ai/plugin": "^1.15.10",
32
32
  "ajv": "^8.20.0",
33
33
  "picomatch": "^4.0.4",
34
- "valibot": "^1.4.0"
34
+ "valibot": "^1.4.1"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@changesets/changelog-github": "^0.7.0",
38
38
  "@changesets/cli": "^2.30.0",
39
39
  "@commitlint/cli": "^21.0.1",
40
40
  "@commitlint/config-conventional": "^21.0.1",
41
- "@types/node": "^25.9.0",
41
+ "@types/node": "^25.9.1",
42
42
  "@types/picomatch": "^4.0.3",
43
- "@typescript/native-preview": "7.0.0-dev.20260518.1",
43
+ "@typescript/native-preview": "7.0.0-dev.20260525.1",
44
44
  "@vitest/coverage-v8": "^4.1.7",
45
45
  "@vitest/ui": "^4.1.7",
46
46
  "eslint-plugin-perfectionist": "^5.9.0",
47
47
  "eslint-plugin-unused-imports": "^4.4.1",
48
- "lefthook": "^2.1.6",
49
- "oxfmt": "^0.50.0",
50
- "oxlint": "^1.65.0",
48
+ "lefthook": "^2.1.8",
49
+ "oxfmt": "^0.51.0",
50
+ "oxlint": "^1.66.0",
51
51
  "oxlint-tsgolint": "^0.23.0",
52
52
  "rimraf": "^6.1.3",
53
53
  "vitest": "^4.1.7"
package/schema.json CHANGED
@@ -366,7 +366,7 @@
366
366
  "type": "object",
367
367
  "additionalProperties": false,
368
368
  "properties": {
369
- "mode": { "enum": ["multi", "single"], "default": "multi" },
369
+ "mode": { "enum": ["multi", "single"], "default": "single" },
370
370
  "account": { "type": "string", "minLength": 1 },
371
371
  "reviewers": {
372
372
  "type": "array",