opencode-reviewer 1.0.1 → 2.0.0

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
@@ -1,7 +1,8 @@
1
1
  # OpenCode Reviewer
2
2
 
3
- Reviews pending permissions in the OpenCode sidebar using a separate LLM. Covers
4
- shell commands, file edits, skill loading, MCP calls, custom tools, and external-directory access.
3
+ Reviews pending permissions in the [OpenCode](https://github.com/anomalyco/opencode) sidebar using a separate LLM. Reviews
4
+ native shell commands, file edits, and external-directory access. Skill, MCP and
5
+ custom-tool requests currently remain manual.
5
6
  Supports streaming explanations, saved report history, auto-approval, and Linux
6
7
  desktop notifications with distinct sounds.
7
8
 
@@ -13,20 +14,24 @@ This plugin is meant to enable you to run sessions with less frequent input in a
13
14
 
14
15
  ![](./assets/recording.gif)
15
16
 
16
- Verified with OpenCode 1.18.35 on Linux.
17
+ Targets OpenCode V2 on Linux. Host version numbers do not gate plugin activation;
18
+ the companion protocol and actual scoped API contracts govern review and approval.
19
+ Verified host checks are recorded in the maintainer migration plan.
17
20
 
18
21
  ## Install and config
19
22
 
20
- Add this entry to `~/.config/opencode/tui.json` or `.opencode/tui.json`.
21
- OpenCode installs the [npm package](https://www.npmjs.com/package/opencode-reviewer).
23
+ Add this entry to the global `~/.config/opencode/cli.json`, or
24
+ `$XDG_CONFIG_HOME/opencode/cli.json` when `XDG_CONFIG_HOME` is set.
25
+ There is no project-local CLI configuration. OpenCode loads the
26
+ [npm package](https://www.npmjs.com/package/opencode-reviewer) from this entry.
22
27
 
23
28
  ```json
24
29
  {
25
- "$schema": "https://opencode.ai/tui.json",
26
- "plugin": [
27
- [
28
- "opencode-reviewer@latest",
29
- {
30
+ "$schema": "https://opencode.ai/v2/cli.json",
31
+ "plugins": [
32
+ {
33
+ "package": "opencode-reviewer@2.0.0",
34
+ "options": {
30
35
  "baseURL": "https://openrouter.ai/api/v1",
31
36
  "model": "your-model",
32
37
  "apiKey": "your-api-key",
@@ -61,7 +66,7 @@ OpenCode installs the [npm package](https://www.npmjs.com/package/opencode-revie
61
66
  "maxFiles": 6,
62
67
  "maxEvidenceBytes": 131072
63
68
  }
64
- ]
69
+ }
65
70
  ]
66
71
  }
67
72
  ```
@@ -77,13 +82,33 @@ endpoint. Remove `instructions` to use the built-in prompts and
77
82
 
78
83
  The connection, credential and directory values above are examples, not defaults.
79
84
  All boolean, numeric and per-type notification values shown are the defaults.
80
- Restart OpenCode after changing configuration. Reviews run when OpenCode asks for
81
- permission, so set the relevant rules to `ask` in `opencode.json`. Existing `allow`
82
- rules skip review.
85
+ Restart OpenCode after changing reviewer configuration. Also load the server
86
+ companion in `opencode.json`, globally or in the project. Keep permission rules
87
+ only in this server configuration, not in `cli.json`:
88
+
89
+ ```json
90
+ {
91
+ "$schema": "https://opencode.ai/config.json",
92
+ "plugins": ["opencode-reviewer@2.0.0"],
93
+ "permissions": [
94
+ { "action": "shell", "resource": "*", "effect": "ask" },
95
+ { "action": "edit", "resource": "*", "effect": "ask" },
96
+ { "action": "skill", "resource": "*", "effect": "ask" },
97
+ { "action": "external_directory", "resource": "*", "effect": "ask" }
98
+ ]
99
+ }
100
+ ```
101
+
102
+ Merge these entries with your existing configuration. Rules are ordered; the last
103
+ matching rule wins. Reviews run only when OpenCode asks for permission. Existing
104
+ `allow` rules and native autoaccept skip review. See OpenCode's
105
+ [server config](https://opencode.ai/v2/docs/config),
106
+ [CLI config](https://opencode.ai/v2/docs/cli/config) and
107
+ [CLI plugins](https://opencode.ai/v2/docs/build/plugins/cli) guides.
83
108
 
84
109
  ## Options reference
85
110
 
86
- These are options inside the plugin's configuration object in `tui.json`.
111
+ These are options inside the plugin's `options` object in global `cli.json`.
87
112
  Defaults apply only to omitted options; `null` is invalid. Boolean and integer
88
113
  options require JSON booleans and numbers, not quoted strings. Integer ranges are
89
114
  inclusive, fractions are invalid, and the maximum safe integer is
@@ -96,17 +121,17 @@ inclusive, fractions are invalid, and the maximum safe integer is
96
121
  | `apiKey` | string | Unset | Nonempty Bearer token. Takes precedence over `apiKeyEnv`. |
97
122
  | `apiKeyEnv` | string | Unset | Environment-variable name matching `[A-Za-z_][A-Za-z_0-9]*`. Without an inline key, its value must be set and nonblank when a review runs. Omit both key options for no Authorization header. |
98
123
  | `instructions` | string | Unset (built-ins) | Absolute, NUL-free directory path containing overrides for the [prompt templates](https://github.com/mightykatun/opencode-reviewer/tree/main/prompts), not inline instructions. Missing named files use built-ins; supplied files must be readable, regular, non-symlink, nonempty UTF-8 text up to 64 KiB. Fixed contracts cannot be overridden. |
99
- | `stream` | boolean | `false` | Request SSE and show provisional rating/text updates. Normal automatic approval waits for a completed, validated and rendered report; fast mode can approve on an early Safe rating. |
100
- | `reviewBash` | boolean | `true` | Review native shell-command permissions. |
101
- | `reviewEdits` | boolean | `true` | Review native `edit`, `write` and `apply_patch` permissions. |
102
- | `reviewSkills` | boolean | `true` | Review native skill-load permissions for dangerous guidance and relevance to the current task. Supplies the host's skill instructions and bounded, directly referenced supporting files within the skill directory. |
103
- | `reviewMcp` | boolean | `false` | Review identifiable MCP tool and resource permissions. |
104
- | `reviewCustomTools` | boolean | `false` | Review permissions requested by registered custom tools. |
124
+ | `stream` | boolean | `false` | Request SSE and show provisional rating/text updates. Normal automatic approval waits for a completed, validated report; fast mode can approve on an early Safe rating. Presentation rules are described below. |
125
+ | `reviewBash` | boolean | `true` | Review native `shell` permissions. The option keeps its existing name. |
126
+ | `reviewEdits` | boolean | `true` | Review native `edit`, `write` and `patch` tools, which use the `edit` permission action. |
127
+ | `reviewSkills` | boolean | `true` | Skill-review category switch. Exact mandatory skill instructions are currently unavailable to the V2 collector, so these requests remain manual. |
128
+ | `reviewMcp` | boolean | `false` | MCP-review category switch. V2 MCP collection is currently unsupported; enabling this does not supply missing origin/catalog evidence or permit automatic approval. |
129
+ | `reviewCustomTools` | boolean | `false` | Custom-tool review category switch. V2 custom-tool collection is currently unsupported; these requests remain manual. |
105
130
  | `reviewExternalDirectories` | boolean | `false` | Review directory access independently of operation-review switches. Directory approval can resume the operation without another prompt. |
106
- | `autoApprove` | boolean | `false` | Allow Safe reviews once automatically. Normally waits for completion, validation, rendering and the countdown, including behind this plugin's report history. |
107
- | `fastMode` | boolean | `false` | Requires `autoApprove: true`. Approve a visible, front-of-queue request as soon as a Safe rating is parsed, bypassing the countdown. Respects `stream`; with `stream: false`, waits for the complete validated response. Finish the report and save it in the background after approval. |
131
+ | `autoApprove` | boolean | `false` | Allow Safe reviews once automatically. Normally waits for completion, validation and the countdown. Requires the top-level conversation and physical presentation proof; subagent browsing never permits automatic approval. Normal-mode report-history cover has a separate physical-proof exception. |
132
+ | `fastMode` | boolean | `false` | Requires `autoApprove: true`. Approve an eligible, front-of-queue request as soon as a Safe rating is parsed, bypassing the countdown. Respects `stream`; with `stream: false`, waits for the complete validated response. Finish the report and save it in the background after approval. |
108
133
  | `extraCareful` | boolean | `true` | Include extra-careful guidance when `autoApprove` is enabled. Setting `false` omits that guidance without disabling automatic approval. |
109
- | `autoApproveDelaySeconds` | integer | `15` | `0`–`3600` seconds. Positive values include an extra 200 ms initial grace; `0` skips the wait but retains rendering and eligibility checks. Ignored in fast mode. |
134
+ | `autoApproveDelaySeconds` | integer | `15` | `0`–`3600` seconds. Positive values include an extra 200 ms initial grace; `0` skips the wait but keeps the other approval checks. Ignored in fast mode. |
110
135
  | `notify` | boolean | `true` | Master switch for desktop banners, sounds and reminders. `false` overrides all per-type controls. |
111
136
  | `notifySound` | boolean | `true` | Master switch for notification audio. `false` silences every type and reminder without disabling enabled banners. |
112
137
  | `staleReminderSeconds` | integer | `60` | `0` through the maximum safe integer, in seconds. `0` disables reminders; otherwise eligible pending human interactions repeat at this interval, limited to the native front-of-queue blocker per conversation. |
@@ -115,8 +140,8 @@ inclusive, fractions are invalid, and the maximum safe integer is
115
140
  | `formatRetries` | integer | `1` | `0`–`100` additional assessment-format correction attempts. `0` disables format corrections, not independent transport recovery. |
116
141
  | `maxOutputTokens` | integer | `4096` | `1` through the maximum safe integer. Sent as `max_tokens` on every reviewer POST, including retries/corrections. Your provider/model enforces its supported output limit. |
117
142
  | `timeoutMs` | integer | `30000` | `1`–`3600000` milliseconds shared across evidence collection, HTTP requests, retries and corrections; not a fresh budget per POST. |
118
- | `maxFiles` | integer | `6` | `1`–`1000` distinct file candidates per shell/edit/skill review, including unavailable candidates. Skill reviews count the main instructions as one file. |
119
- | `maxEvidenceBytes` | integer | `131072` | `1`–`16777216` bytes for command/source content, edit diffs or category-specific JSON evidence. Skill reviews share this budget between mandatory skill JSON and UTF-8 supporting-file content. Optional items are omitted whole; oversized mandatory evidence fails analysis. This is not a cap on the full prompt or HTTP request. |
143
+ | `maxFiles` | integer | `6` | `1`–`1000` distinct file candidates per shell/edit review, including unavailable candidates. |
144
+ | `maxEvidenceBytes` | integer | `131072` | `1`–`16777216` bytes for command/source content, edit diffs or category-specific JSON evidence. Optional items are omitted whole; oversized mandatory evidence fails analysis. This is not a cap on the full prompt or HTTP request. |
120
145
 
121
146
  Notification channels are independent: `banner: false, sound: true` is sound-only;
122
147
  `banner: true, sound: false` is banner-only; both `false` disable that type.
@@ -131,37 +156,47 @@ The sidebar shows Safe, Unsafe, or Analysis unavailable. Explanations support
131
156
  Markdown and scrolling. If the sidebar is hidden, use OpenCode's Show sidebar
132
157
  command.
133
158
 
134
- When browsing a direct subagent, the same front-of-queue review appears in a
135
- right-hand panel at terminal widths of at least 120 columns. Its auto-approval
136
- countdown can start there without returning to the parent conversation.
137
-
138
- Skill-load review is enabled by default; set `skill` permissions to `ask` in
139
- `opencode.json` to receive reviews. Its prompt requires both bounded risk and clear
140
- relevance to the current work. A harmless but irrelevant skill is rated Unsafe.
141
- The reviewer receives the exact main instructions from the host's skill catalog,
142
- plus bounded snapshots of directly referenced local files within the skill directory.
143
- It does not execute scripts, follow references in supporting files, expand directory
144
- listings, fetch external URLs, or read supporting files outside that directory.
145
- Built-in skills without a local directory receive instruction-only review.
146
- Customize this guidance with `SKILL-REVIEW-PROMPT.md` in your prompt directory.
147
-
148
- For every review category, subagent requests include the latest immediate delegation
149
- linked to the requesting assistant invocation, alongside the genuine root-user prompt.
150
- Resumed subagents use the current delegation; nested subagents include only their
151
- immediate delegation. Missing or over-64-KiB delegation text is noted rather than
152
- replaced with an older task. Both prompts are context for the reviewer, not instructions
153
- that can override its review contract.
159
+ The reviewer side panel appears only in the top-level conversation. Browsing its
160
+ subagents, including nested subagents, hides the panel and prevents both normal
161
+ and fast automatic approvals. Reviews may finish while hidden. A Safe report that
162
+ has never started a normal countdown may first become eligible after returning to
163
+ the root and receiving real presentation proof, with a fresh countdown. Leaving
164
+ the root after a countdown starts permanently makes that request manual for the
165
+ running controller, even after returning or disabling/re-enabling review.
166
+
167
+ Automatic approval requires mouse tracking for the host's painted-panel ownership
168
+ checks. With mouse tracking disabled, reports remain available for manual review.
169
+ The plugin never enables mouse tracking. It preserves sidebar visibility except
170
+ after an explicit approval-notification click, when a root frame confirms the
171
+ sidebar is absent before revealing it.
172
+
173
+ The category switches are retained, but the current V2 collectors do not support
174
+ skill, MCP or custom-tool reviews. Missing mandatory skill instructions and unproven
175
+ MCP/custom origin or catalog evidence leave these requests manual, not Safe.
176
+
177
+ Native Code Mode and its tool search remain enabled. Exactly linked native calls
178
+ can be reviewed; ambiguously linked nested calls remain manual. The plugin assumes
179
+ installed plugins preserve native tool meanings, do not replace or alias native
180
+ executors, and do not rewrite commands after evidence capture.
181
+
182
+ Subagent requests carry the genuine latest root-user prompt. Exact immediate
183
+ delegation is currently unavailable through the supported V2 evidence path and is
184
+ factually omitted, not guessed from older tasks, sibling requests or queued follow-ups.
185
+ Optional context omissions do not alone prevent review when mandatory operation
186
+ evidence is verified. Context cannot override the review contract.
154
187
 
155
188
  With streaming enabled, Evaluating and its spinner disappear when a rating arrives.
156
189
  The rating remains provisional until the full response is validated. A retry
157
190
  clears the preview and restores the loading indicator. Normal auto-approval
158
- starts only after the full response is validated and rendered.
191
+ starts only after the full response is validated and rendered on the top-level
192
+ conversation, with matching physical presentation proof.
159
193
 
160
194
  With `autoApprove: true` and `fastMode: true`, a parsed Safe rating approves the
161
- current visible permission immediately, without a countdown or waiting for the
162
- rest of a streamed report. Hidden panels and covering dialogs or history prevent
163
- fast approval. Without streaming, fast mode waits for the full validated response
164
- and then skips the countdown.
195
+ current eligible permission immediately, without a countdown or waiting for the
196
+ rest of a streamed report. It still requires native front-of-queue ownership and
197
+ physical presentation on the top-level conversation. Subagent browsing, explicit
198
+ sidebar hiding, covering dialogs and report history prevent fast approval. Without
199
+ streaming, fast mode waits for the full validated response and then skips the countdown.
165
200
 
166
201
  After confirmed fast approval, the live panel shows **Auto-approved; finishing
167
202
  report…** and stays ahead of newer requests until its report finishes. Hiding the
@@ -185,7 +220,10 @@ provider charges, and unreported usage remains unknown.
185
220
 
186
221
  During an auto-approval countdown, click the countdown to allow once immediately,
187
222
  or Cancel to leave the request manual. Hiding or covering the panel also cancels
188
- that request's countdown, except when covered by this plugin's report history.
223
+ that request's countdown, except for this plugin's physically proven report-history
224
+ cover on the root route. Browsing any subagent or switching conversations cancels it.
225
+ Returning, remounting or re-enabling cannot revive a canceled request. An uncertain
226
+ approval write also remains manual and is never retried.
189
227
  Cancel before using native Allow always or rejection
190
228
  forms; those forms alone do not stop the countdown.
191
229
  Positive countdowns add a 200 ms initial grace and then update on remaining-time
@@ -196,6 +234,10 @@ descendants. The setting is saved for resume. Both commands are also in the comm
196
234
  palette. Disabling stops unapproved reviews and countdowns while native permission
197
235
  controls remain available. Already-approved fast-mode reports finish in the background.
198
236
 
237
+ After a server reconnect or companion replacement, the old controller stops reviews
238
+ and automatic replies until the plugin is reloaded or OpenCode is restarted. It does
239
+ not mix old permission caches with a new connection.
240
+
199
241
  ### Report history
200
242
 
201
243
  Use `/reviewer-history` or **Reviewer: Report history** in the command palette to
@@ -214,19 +256,20 @@ native Allow once replies whose submitting client cannot be identified. History
214
256
  keeps the latest completed report, which can differ from the report that caused
215
257
  approval in another window.
216
258
 
217
- History can cover an ongoing review without stopping its countdown. A newly
218
- completed Safe review can also start its countdown beneath history after its full
219
- report is rendered. Native dialogs, including the command palette, still cancel an
220
- active countdown; opening history afterward cannot restart it. Browsing saved
221
- reports never approves a request or replays notifications.
259
+ Normal-mode history cover preserves an ongoing countdown only on
260
+ the root route, with physical proof of the history heading/footer and rendered
261
+ report. A newly completed Safe review may become eligible under that same proof.
262
+ Native dialogs, including the command palette, still cancel an active countdown;
263
+ opening history afterward cannot restart it. Fast mode has no history-cover
264
+ exception. Browsing saved reports never approves a request or replays notifications.
222
265
 
223
266
  Reports are saved only after a qualifying permission resolution. Saved reports
224
267
  can contain private text and are retained in OpenCode's local state directory
225
- until their conversation is deleted. Deleting a root removes its descendants'
226
- details; deletion missed while OpenCode was closed is reconciled when that host
227
- scope is visited again. Windows using the same state directory share this history,
228
- partitioned by host directory and root conversation. Uncommitted reports can be
229
- lost on shutdown or prolonged storage failure.
268
+ unless deletion ownership is proven. A conversation deletion does not authorize
269
+ purging reports without proven server/scope ownership. Uncertain offline deletions
270
+ retain history; a missing list entry or bare 404 is not enough. Windows using the
271
+ same state directory share this history, partitioned by host directory and root
272
+ conversation. Uncommitted reports can be lost on shutdown or prolonged storage failure.
230
273
 
231
274
  ### Usage totals
232
275
 
@@ -236,8 +279,8 @@ views. Use Tab or click a scope to switch. The dialog opens on Lifetime;
236
279
  Conversation uses the session selected when opened, resolving its root and all
237
280
  descendants, including subagents, within the current host-directory scope.
238
281
  Opening from a descendant shows the same combined conversation totals.
239
- OpenRouter
240
- costs use reported charges; other endpoints use available catalog estimates.
282
+ Statistics remain available with review disabled or invalid reviewer configuration.
283
+ OpenRouter costs use reported charges; other endpoints use available catalog estimates.
241
284
  Received usage counts even if a review fails or is interrupted. Unreported charges
242
285
  are missing from the totals.
243
286
 
@@ -332,8 +375,8 @@ interaction per root conversation repeats: permissions precede questions, with
332
375
  the host's session/request ordering. Queued interactions stay silent. Handoff sends
333
376
  the next eligible request's initial notification, then waits a full interval before
334
377
  its first reminder. Independent visited conversations
335
- can each remind. The supported host presents input for roots and direct children;
336
- deeper descendants cannot become a native root-input notification or reminder target.
378
+ can each remind. The supported V2 host's root input queue includes the full descendant
379
+ family, root first and then the host's public family order.
337
380
 
338
381
  Answering/dismissing a question in OpenCode, resolving a permission, deleting its
339
382
  session or closing the plugin stops its reminders. Closing/clicking a desktop
@@ -345,7 +388,7 @@ Notifications cover conversations visited in this terminal and their descendants
345
388
  Existing pending requests at startup/resume are not replayed or reminded, but still
346
389
  participate in queue ordering. Clicking can select
347
390
  the originating GNOME Terminal tab and root conversation. Native input prompts
348
- cover root/direct-child requests in the supported host. Open dialogs are
391
+ cover the root and its full descendant family in the supported host. Open dialogs are
349
392
  left intact; other terminals still receive banners and sounds. Desktop policies
350
393
  control expiry/history and whether activation actually brings a window forward.
351
394
  Clicking **Reviewer approved a permission** opens that permission's unfinished
@@ -389,7 +432,7 @@ Use Node.js 24.15.0+ within 24.x, or 22.22.2+ within 22.x, and npm.
389
432
  Run `npm ci --ignore-scripts`, then `npm run check` for typechecking, source tests,
390
433
  pure-helper tests and the build. `npm run test:helpers` runs the helper checks
391
434
  without building or starting OpenCode. Pull-request CI checks both Node versions
392
- and runs a separate representative Linux OpenCode 1.18.35 fixture profile.
435
+ and runs a separate representative Linux OpenCode 2.0.26 fixture profile.
393
436
  After building, run `node scripts/test-runtime.mjs --profile ci` for that same
394
437
  profile. Use `node scripts/test-runtime.mjs --list` for the complete runtime
395
438
  inventory or `node scripts/test-runtime.mjs --plan --profile ci` for a
@@ -27,6 +27,39 @@ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27
27
  TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28
28
  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
29
 
30
+ # Bundled dependency: @opencode/theme 2.0.26
31
+
32
+ https://github.com/anomalyco/opencode/tree/v2.0.26/packages/theme
33
+
34
+ The pinned theme helper is bundled in the terminal payload. Solid and OpenTUI
35
+ remain host-provided external dependencies.
36
+
37
+ License source: https://github.com/anomalyco/opencode/blob/v2.0.26/LICENSE
38
+
39
+ ```text
40
+ MIT License
41
+
42
+ Copyright (c) 2025 opencode
43
+
44
+ Permission is hereby granted, free of charge, to any person obtaining a copy
45
+ of this software and associated documentation files (the "Software"), to deal
46
+ in the Software without restriction, including without limitation the rights
47
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
48
+ copies of the Software, and to permit persons to whom the Software is
49
+ furnished to do so, subject to the following conditions:
50
+
51
+ The above copyright notice and this permission notice shall be included in all
52
+ copies or substantial portions of the Software.
53
+
54
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
55
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
56
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
57
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
58
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
59
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
60
+ SOFTWARE.
61
+ ```
62
+
30
63
  # Bundled audio decoder and supplied sounds
31
64
 
32
65
  The six notification MP3 files were supplied by the maintainer with