opencode-reviewer 0.7.0 → 1.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 +248 -60
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/dist/tui.js +3528 -1172
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,13 +1,21 @@
|
|
|
1
|
-
# OpenCode
|
|
1
|
+
# OpenCode Reviewer
|
|
2
2
|
|
|
3
3
|
Reviews pending permissions in the OpenCode sidebar using a separate LLM. Covers
|
|
4
|
-
shell commands, file edits, MCP calls, custom tools, and external-directory access.
|
|
5
|
-
Supports streaming explanations,
|
|
6
|
-
|
|
4
|
+
shell commands, file edits, skill loading, MCP calls, custom tools, and external-directory access.
|
|
5
|
+
Supports streaming explanations, saved report history, auto-approval, and Linux
|
|
6
|
+
desktop notifications with distinct sounds.
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
This plugin is meant to enable you to run sessions with less frequent input in a safer way. Also giving the reviewer context of specific files the agent might want to run/see/... The review prompts are freely configurable, so you can determine the reviewers behavior very accurately.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
> ⚠️ **Disclaimer**
|
|
11
|
+
>
|
|
12
|
+
> This does not make running agents foolproof and safe! An actor running intrusive commands on your machine will always create attack surface! It just reduces risk, and enables you to get more insight into what your agent is doing.
|
|
13
|
+
|
|
14
|
+

|
|
15
|
+
|
|
16
|
+
Requires OpenCode 1.18.35 or newer on Linux.
|
|
17
|
+
|
|
18
|
+
## Install and config
|
|
11
19
|
|
|
12
20
|
Add this entry to `~/.config/opencode/tui.json` or `.opencode/tui.json`.
|
|
13
21
|
OpenCode installs the [npm package](https://www.npmjs.com/package/opencode-reviewer).
|
|
@@ -27,16 +35,28 @@ OpenCode installs the [npm package](https://www.npmjs.com/package/opencode-revie
|
|
|
27
35
|
"stream": false,
|
|
28
36
|
"reviewBash": true,
|
|
29
37
|
"reviewEdits": true,
|
|
38
|
+
"reviewSkills": true,
|
|
30
39
|
"reviewMcp": false,
|
|
31
40
|
"reviewCustomTools": false,
|
|
32
41
|
"reviewExternalDirectories": false,
|
|
33
42
|
"autoApprove": false,
|
|
43
|
+
"fastMode": false,
|
|
34
44
|
"extraCareful": true,
|
|
35
45
|
"autoApproveDelaySeconds": 15,
|
|
36
46
|
"notify": true,
|
|
37
47
|
"notifySound": true,
|
|
48
|
+
"staleReminderSeconds": 60,
|
|
49
|
+
"notifications": {
|
|
50
|
+
"attention": { "banner": true, "sound": true },
|
|
51
|
+
"unsafe": { "banner": true, "sound": true },
|
|
52
|
+
"question": { "banner": true, "sound": true },
|
|
53
|
+
"approved": { "banner": true, "sound": true },
|
|
54
|
+
"error": { "banner": true, "sound": true },
|
|
55
|
+
"ended": { "banner": true, "sound": true }
|
|
56
|
+
},
|
|
38
57
|
"notificationSoundDirectory": "/absolute/path/to/notification-sounds",
|
|
39
58
|
"formatRetries": 1,
|
|
59
|
+
"maxOutputTokens": 4096,
|
|
40
60
|
"timeoutMs": 30000,
|
|
41
61
|
"maxFiles": 6,
|
|
42
62
|
"maxEvidenceBytes": 131072
|
|
@@ -47,7 +67,7 @@ OpenCode installs the [npm package](https://www.npmjs.com/package/opencode-revie
|
|
|
47
67
|
```
|
|
48
68
|
|
|
49
69
|
Only `baseURL` and `model` are required. Use any OpenAI-compatible Chat Completions
|
|
50
|
-
endpoint
|
|
70
|
+
endpoint: `/chat/completions` is appended to the base URL. Choose a model available
|
|
51
71
|
at that endpoint.
|
|
52
72
|
|
|
53
73
|
Replace `apiKey`, or remove it and set the variable named by `apiKeyEnv` before
|
|
@@ -55,68 +75,169 @@ launching OpenCode. The inline key takes precedence. Omit both for an unauthenti
|
|
|
55
75
|
endpoint. Remove `instructions` to use the built-in prompts and
|
|
56
76
|
`notificationSoundDirectory` to use the bundled sounds.
|
|
57
77
|
|
|
58
|
-
The
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
|
73
|
-
|
|
|
74
|
-
| `
|
|
75
|
-
| `
|
|
76
|
-
| `
|
|
77
|
-
| `
|
|
78
|
-
| `
|
|
79
|
-
| `
|
|
80
|
-
| `
|
|
81
|
-
| `
|
|
82
|
-
| `
|
|
83
|
-
|
|
84
|
-
|
|
78
|
+
The connection, credential and directory values above are examples, not defaults.
|
|
79
|
+
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.
|
|
83
|
+
|
|
84
|
+
## Options reference
|
|
85
|
+
|
|
86
|
+
These are options inside the plugin's configuration object in `tui.json`.
|
|
87
|
+
Defaults apply only to omitted options; `null` is invalid. Boolean and integer
|
|
88
|
+
options require JSON booleans and numbers, not quoted strings. Integer ranges are
|
|
89
|
+
inclusive, fractions are invalid, and the maximum safe integer is
|
|
90
|
+
9,007,199,254,740,991. Unknown option names are rejected.
|
|
91
|
+
|
|
92
|
+
| Option | Type | Default | Accepted values and behavior |
|
|
93
|
+
| --- | --- | --- | --- |
|
|
94
|
+
| `baseURL` | string | Required | HTTP(S) API base URL; `/chat/completions` is appended after removing trailing slashes. Embedded credentials, query strings and fragments are rejected. |
|
|
95
|
+
| `model` | string | Required | Nonempty model identifier accepted by the configured endpoint. |
|
|
96
|
+
| `apiKey` | string | Unset | Nonempty Bearer token. Takes precedence over `apiKeyEnv`. |
|
|
97
|
+
| `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
|
+
| `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. |
|
|
105
|
+
| `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. |
|
|
108
|
+
| `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 have an extra one-second initial hold; `0` skips the wait but retains rendering and eligibility checks. Ignored in fast mode. |
|
|
110
|
+
| `notify` | boolean | `true` | Master switch for desktop banners, sounds and reminders. `false` overrides all per-type controls. |
|
|
111
|
+
| `notifySound` | boolean | `true` | Master switch for notification audio. `false` silences every type and reminder without disabling enabled banners. |
|
|
112
|
+
| `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. |
|
|
113
|
+
| `notifications` | object | All types: `banner: true`, `sound: true` | Keys: `attention`, `unsafe`, `question`, `approved`, `error`, `ended`. Each entry is an object with optional `banner` and `sound` booleans. Omitted types/fields remain enabled; unknown types/fields are invalid. Controls also apply to reminders. |
|
|
114
|
+
| `notificationSoundDirectory` | string | Unset (bundled sounds) | Absolute, NUL-free path, at most 4096 string code units. Use the six notification type names as basenames: usable `.wav` first, then `.mp3`, then the corresponding bundled sound. |
|
|
115
|
+
| `formatRetries` | integer | `1` | `0`–`100` additional assessment-format correction attempts. `0` disables format corrections, not independent transport recovery. |
|
|
116
|
+
| `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
|
+
| `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. |
|
|
120
|
+
|
|
121
|
+
Notification channels are independent: `banner: false, sound: true` is sound-only;
|
|
122
|
+
`banner: true, sound: false` is banner-only; both `false` disable that type.
|
|
123
|
+
`notify` and `notifySound` take precedence. Invalid notification settings disable
|
|
124
|
+
notification work without invalidating otherwise valid review settings.
|
|
85
125
|
|
|
126
|
+
My LLMs insist on writing a bunch of useless text to my README, so I collapsed them here in case anyone wants to inflict themselves (or more likely their agent) the pain of reading it.
|
|
127
|
+
|
|
128
|
+
<details>
|
|
129
|
+
<summary>Usage</summary>
|
|
86
130
|
The sidebar shows Safe, Unsafe, or Analysis unavailable. Explanations support
|
|
87
131
|
Markdown and scrolling. If the sidebar is hidden, use OpenCode's Show sidebar
|
|
88
132
|
command.
|
|
89
133
|
|
|
134
|
+
Skill-load review is enabled by default; set `skill` permissions to `ask` in
|
|
135
|
+
`opencode.json` to receive reviews. Its prompt requires both bounded risk and clear
|
|
136
|
+
relevance to the current work. A harmless but irrelevant skill is rated Unsafe.
|
|
137
|
+
The reviewer receives the exact main instructions from the host's skill catalog,
|
|
138
|
+
plus bounded snapshots of directly referenced local files within the skill directory.
|
|
139
|
+
It does not execute scripts, follow references in supporting files, expand directory
|
|
140
|
+
listings, fetch external URLs, or read supporting files outside that directory.
|
|
141
|
+
Built-in skills without a local directory receive instruction-only review.
|
|
142
|
+
Customize this guidance with `SKILL-REVIEW-PROMPT.md` in your prompt directory.
|
|
143
|
+
|
|
144
|
+
For every review category, subagent requests include the latest immediate delegation
|
|
145
|
+
linked to the requesting assistant invocation, alongside the genuine root-user prompt.
|
|
146
|
+
Resumed subagents use the current delegation; nested subagents include only their
|
|
147
|
+
immediate delegation. Missing or over-64-KiB delegation text is noted rather than
|
|
148
|
+
replaced with an older task. Both prompts are context for the reviewer, not instructions
|
|
149
|
+
that can override its review contract.
|
|
150
|
+
|
|
90
151
|
With streaming enabled, Evaluating and its spinner disappear when a rating arrives.
|
|
91
|
-
The rating remains provisional until the full response is validated. A
|
|
92
|
-
clears the preview and restores the loading indicator.
|
|
152
|
+
The rating remains provisional until the full response is validated. A retry
|
|
153
|
+
clears the preview and restores the loading indicator. Normal auto-approval
|
|
93
154
|
starts only after the full response is validated and rendered.
|
|
94
155
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
156
|
+
With `autoApprove: true` and `fastMode: true`, a parsed Safe rating approves the
|
|
157
|
+
current visible permission immediately, without a countdown or waiting for the
|
|
158
|
+
rest of a streamed report. Hidden panels and covering dialogs or history prevent
|
|
159
|
+
fast approval. Without streaming, fast mode waits for the full validated response
|
|
160
|
+
and then skips the countdown.
|
|
161
|
+
|
|
162
|
+
After confirmed fast approval, the live panel shows **Auto-approved; finishing
|
|
163
|
+
report…** and stays ahead of newer requests until its report finishes. Hiding the
|
|
164
|
+
panel, changing conversations or disabling review does not stop that already-approved
|
|
165
|
+
assessment. Normal retries and the original deadline still apply. The panel closes
|
|
166
|
+
when the assessment finishes; history saves continue in the background. Only a
|
|
167
|
+
completed validated report is saved, including a final Unsafe rating after a retry.
|
|
168
|
+
A failed remainder creates no report entry and cannot undo the earlier approval.
|
|
169
|
+
|
|
170
|
+
Transient connection failures, HTTP 408/429/500/502/503/504 responses, and rejected
|
|
171
|
+
assessment streams share up to two internal retries within `timeoutMs`, honoring
|
|
172
|
+
server cooldowns. Stream protocol failures and output-token truncation regenerate
|
|
173
|
+
the report from a fresh, identical request; previous previews are cleared and never
|
|
174
|
+
joined to the next response. Socket failures after text starts, provider error/refusal
|
|
175
|
+
events, tool calls, invalid JSON/UTF-8, incomplete SSE framing and resource-limit
|
|
176
|
+
failures remain terminal. This recovery is separate from `formatRetries`.
|
|
177
|
+
If token-limit errors persist, increase `maxOutputTokens` within your model's limits.
|
|
178
|
+
Providers enforce this limit and may include reasoning tokens; the plugin's byte
|
|
179
|
+
limits and overall timeout still apply. Retried requests can incur additional
|
|
180
|
+
provider charges, and unreported usage remains unknown.
|
|
100
181
|
|
|
101
182
|
During an auto-approval countdown, click the countdown to allow once immediately,
|
|
102
183
|
or Cancel to leave the request manual. Hiding or covering the panel also cancels
|
|
103
|
-
that request's countdown
|
|
184
|
+
that request's countdown, except when covered by this plugin's report history.
|
|
185
|
+
Cancel before using native Allow always or rejection
|
|
104
186
|
forms; those forms alone do not stop the countdown.
|
|
105
187
|
Positive countdowns hold their configured starting number for one extra second
|
|
106
188
|
before counting down. A zero-second setting still approves without that hold.
|
|
107
189
|
|
|
108
190
|
`/reviewer-disable` and `/reviewer-enable` control the current conversation and its
|
|
109
191
|
descendants. The setting is saved for resume. Both commands are also in the command
|
|
110
|
-
palette. Disabling stops
|
|
111
|
-
controls remain available.
|
|
192
|
+
palette. Disabling stops unapproved reviews and countdowns while native permission
|
|
193
|
+
controls remain available. Already-approved fast-mode reports finish in the background.
|
|
194
|
+
|
|
195
|
+
### Report history
|
|
196
|
+
|
|
197
|
+
Use `/reviewer-history` or **Reviewer: Report history** in the command palette to
|
|
198
|
+
open the newest saved report for the current conversation and its descendants.
|
|
199
|
+
Left/Right or the arrow buttons select older/newer entries; Up/Down and
|
|
200
|
+
PageUp/PageDown scroll. Close or Escape closes history. Repeating the command
|
|
201
|
+
returns to the newest report. History remains available with review disabled or
|
|
202
|
+
invalid reviewer configuration. The history command preserves a hidden sidebar;
|
|
203
|
+
clicking an approval notification reveals it and selects that permission's live or saved report.
|
|
204
|
+
|
|
205
|
+
Each entry shows the original report, available usage, model, provider and outcome:
|
|
206
|
+
**Auto approved**, **Manually approved**, **Cancelled**, or **Rejected**. Cancelled
|
|
207
|
+
records a linked interruption or removed request after automation was cancelled;
|
|
208
|
+
it does not prove that the tool never ran. Ambiguous outcomes are omitted, including
|
|
209
|
+
native Allow once replies whose submitting client cannot be identified. History
|
|
210
|
+
keeps the latest completed report, which can differ from the report that caused
|
|
211
|
+
approval in another window.
|
|
212
|
+
|
|
213
|
+
History can cover an ongoing review without stopping its countdown. A newly
|
|
214
|
+
completed Safe review can also start its countdown beneath history after its full
|
|
215
|
+
report is rendered. Native dialogs, including the command palette, still cancel an
|
|
216
|
+
active countdown; opening history afterward cannot restart it. Browsing saved
|
|
217
|
+
reports never approves a request or replays notifications.
|
|
218
|
+
|
|
219
|
+
Reports are saved only after a qualifying permission resolution. Saved reports
|
|
220
|
+
can contain private text and are retained in OpenCode's local state directory
|
|
221
|
+
until their conversation is deleted. Deleting a root removes its descendants'
|
|
222
|
+
details; deletion missed while OpenCode was closed is reconciled when that host
|
|
223
|
+
scope is visited again. Windows using the same state directory share this history,
|
|
224
|
+
partitioned by host directory and root conversation. Uncommitted reports can be
|
|
225
|
+
lost on shutdown or prolonged storage failure.
|
|
226
|
+
|
|
227
|
+
### Usage totals
|
|
112
228
|
|
|
113
229
|
Token and cost totals appear below completed reports when available. Open
|
|
114
|
-
Reviewer:
|
|
230
|
+
**Reviewer: Statistics** in the command palette for **Lifetime** and **Conversation**
|
|
231
|
+
views. Use Tab or click a scope to switch. The dialog opens on Lifetime;
|
|
232
|
+
Conversation uses the session selected when opened, resolving its root and all
|
|
233
|
+
descendants, including subagents, within the current host-directory scope.
|
|
234
|
+
Opening from a descendant shows the same combined conversation totals.
|
|
235
|
+
OpenRouter
|
|
115
236
|
costs use reported charges; other endpoints use available catalog estimates.
|
|
116
237
|
Received usage counts even if a review fails or is interrupted. Unreported charges
|
|
117
238
|
are missing from the totals.
|
|
118
239
|
|
|
119
|
-
|
|
240
|
+
Both views show completed reviews, retries, tokens, cost, Safe/Unsafe
|
|
120
241
|
percentages, confirmed auto-approvals, and average time to a rating and full report.
|
|
121
242
|
Percentages use recorded completed reviews as their denominator. Each validated
|
|
122
243
|
review counts once, even without usage data; a fresh review after re-enabling counts
|
|
@@ -125,49 +246,115 @@ corrections and transport recovery. Manual approvals are not auto-approvals.
|
|
|
125
246
|
Timings run from evaluation start, including evidence and retries, to the accepted
|
|
126
247
|
attempt's first rating and final validated response, excluding rendering/countdown
|
|
127
248
|
time. Non-streaming reviews use the final response time for both measurements.
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
249
|
+
Averages use running means and sample counts; stored review details also retain
|
|
250
|
+
their individual timings. Both scopes persist in the existing history database
|
|
251
|
+
across restart/resume. Conversation totals keep independent roots separate;
|
|
252
|
+
Lifetime combines activity across conversations and host directories using the
|
|
253
|
+
same state directory. Browsing and switching views do not add usage.
|
|
254
|
+
|
|
255
|
+
Older retained history can provide a **partial** conversation baseline. Previously
|
|
256
|
+
deleted details and usage predating history tracking cannot be attributed or
|
|
257
|
+
reconstructed from legacy lifetime aggregates. Once recorded in conversation totals,
|
|
258
|
+
deleting report details does not reduce those totals or Lifetime. Storage failures
|
|
259
|
+
show unavailable, not zero.
|
|
260
|
+
|
|
261
|
+
Tokens describe received provider usage, not just the visible explanation. One
|
|
262
|
+
report may sum several reviewer POSTs, including format corrections and transport
|
|
263
|
+
retries with received usage. Each POST can resend the prompt and evidence;
|
|
264
|
+
corrections also include the failed response and feedback. Cached input remains
|
|
265
|
+
part of the provider's input-token count. Lifetime and Conversation also retain
|
|
266
|
+
received usage from unsuccessful or interrupted reviews, which do not count as
|
|
267
|
+
completed reviews. Averages include measured reviews only.
|
|
132
268
|
|
|
133
269
|
Reviews send the pending request, latest user prompt, project context, and relevant
|
|
134
270
|
file snapshots, diffs, or tool arguments to your endpoint before approval. Shell
|
|
135
271
|
file snapshots can follow symlinks outside the project. Missing evidence is noted
|
|
136
272
|
in the report; ratings are advice based on the supplied evidence.
|
|
273
|
+
</details>
|
|
137
274
|
|
|
138
|
-
|
|
139
|
-
|
|
275
|
+
<details>
|
|
276
|
+
<summary>Desktop notifications</summary>
|
|
140
277
|
Transient banners have an **Opencode (Session name)** heading and a small status icon: green
|
|
141
|
-
checkmark for approvals, orange exclamation mark for attention, red
|
|
278
|
+
checkmark for approvals, orange exclamation mark for attention, red exclamation mark
|
|
279
|
+
for Unsafe reviews, purple question mark for questions, red X
|
|
142
280
|
for errors, and a neutral code mark for completed responses. GNOME controls the
|
|
143
281
|
heading's font weight. The event message appears beneath it, even while the
|
|
144
282
|
terminal is focused:
|
|
145
283
|
|
|
146
|
-
- **Session needs attention:**
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
284
|
+
- **Session needs attention:** manual permissions. Reviewed requests
|
|
285
|
+
stay silent during identification, report generation and retries. Final Safe
|
|
286
|
+
reports notify when auto-approval is disabled or canceled, or after failed approval
|
|
287
|
+
is confirmed to remain pending. Waiting for rendering, queue position or an
|
|
288
|
+
automatic countdown to start does not trigger attention. Disabled/unsupported
|
|
289
|
+
reviews and terminal analysis failures can notify without a report.
|
|
290
|
+
- **Unsafe permission needs human approval:** a completed, validated Unsafe review,
|
|
291
|
+
with its own sound. Provisional streamed ratings never notify.
|
|
292
|
+
- **Agent has a question:** a pending agent question at the front of the native
|
|
293
|
+
input queue, with its own sound.
|
|
150
294
|
- **Reviewer approved a permission:** sent with the approval sound after confirmed
|
|
151
|
-
automatic approval,
|
|
295
|
+
automatic approval, including fast mode while its report is still streaming.
|
|
296
|
+
Positive and zero delays also notify on success; the countdown is silent.
|
|
152
297
|
Approval sounds are limited to
|
|
153
298
|
one every two seconds; every eligible banner is retained for delivery.
|
|
154
299
|
- **Session error:** an unrecovered session/provider failure, not a review failure.
|
|
155
300
|
- **Session ended:** a completed root-agent response, not a question/permission
|
|
156
301
|
pause or an explicit user interruption.
|
|
157
302
|
|
|
303
|
+
Permission attention, Unsafe and question notifications, including their reminders,
|
|
304
|
+
apply only to the current native input blocker in each visited root conversation.
|
|
305
|
+
Requests queued behind it stay silent and are re-evaluated from their current
|
|
306
|
+
state when they become actionable. Questions wait behind pending permissions and
|
|
307
|
+
earlier questions. A request resolved while queued never sends a delayed alert.
|
|
308
|
+
A sequence of permissions that proceeds
|
|
309
|
+
through automatic approval stays free of attention notifications. Losing the
|
|
310
|
+
actionable position, restarting analysis or entering automatic approval cancels
|
|
311
|
+
pending attention delivery and reminders.
|
|
312
|
+
|
|
313
|
+
Each type's `banner` and `sound` can be controlled independently. For example,
|
|
314
|
+
`notifications.approved.banner: false` keeps approval sounds without banners;
|
|
315
|
+
`notifications.question.sound: false` keeps question banners silent. Set both to
|
|
316
|
+
`false` to disable that type. `notify: false` overrides all types and disables
|
|
317
|
+
reminders too; `notifySound: false` silences all types and their reminders.
|
|
318
|
+
Sound-only delivery does not require a desktop banner or delivery acknowledgement.
|
|
319
|
+
Invalid notification settings disable notification work without disabling reviews.
|
|
320
|
+
|
|
321
|
+
Pending permissions and questions repeat after `staleReminderSeconds`, measured
|
|
322
|
+
from initial dispatch, even if desktop delivery fails. Reminders replace their
|
|
323
|
+
previous banner and append **(Reminder)** to the event text, reusing the same
|
|
324
|
+
sound, icon, session heading and click target. Only the native front-of-queue
|
|
325
|
+
interaction per root conversation repeats: permissions precede questions, with
|
|
326
|
+
the host's session/request ordering. Queued interactions stay silent. Handoff sends
|
|
327
|
+
the next eligible request's initial notification, then waits a full interval before
|
|
328
|
+
its first reminder. Independent visited conversations
|
|
329
|
+
can each remind. The supported host presents input for roots and direct children;
|
|
330
|
+
deeper descendants cannot become a native root-input notification or reminder target.
|
|
331
|
+
|
|
332
|
+
Answering/dismissing a question in OpenCode, resolving a permission, deleting its
|
|
333
|
+
session or closing the plugin stops its reminders. Closing/clicking a desktop
|
|
334
|
+
banner, activating the terminal or viewing a conversation does not. Countdown
|
|
335
|
+
and approval submission remain silent. Approval, error and completed-response
|
|
336
|
+
notifications never repeat. Setting `staleReminderSeconds: 0` disables all reminders.
|
|
337
|
+
|
|
158
338
|
Notifications cover conversations visited in this terminal and their descendants.
|
|
159
|
-
Existing pending requests at startup/resume are not replayed
|
|
339
|
+
Existing pending requests at startup/resume are not replayed or reminded, but still
|
|
340
|
+
participate in queue ordering. Clicking can select
|
|
160
341
|
the originating GNOME Terminal tab and root conversation. Native input prompts
|
|
161
342
|
cover root/direct-child requests in the supported host. Open dialogs are
|
|
162
343
|
left intact; other terminals still receive banners and sounds. Desktop policies
|
|
163
344
|
control expiry/history and whether activation actually brings a window forward.
|
|
345
|
+
Clicking **Reviewer approved a permission** opens that permission's unfinished
|
|
346
|
+
fast-mode report, or its matching saved report if it has completed, revealing the
|
|
347
|
+
sidebar if hidden. If a dialog is open, navigation waits until it closes and then
|
|
348
|
+
checks whether the report is still live. A clicked live panel closes on completion
|
|
349
|
+
like any fast-mode report. A pending save gets up to five seconds; if the report is
|
|
350
|
+
unavailable or deleted, the click just opens its conversation rather than a different report.
|
|
164
351
|
GNOME Terminal clicks use the desktop activation token to bring the correct tab
|
|
165
352
|
forward across workspaces. GNOME may attribute the notification source to Terminal;
|
|
166
353
|
the banner heading remains Opencode.
|
|
167
354
|
|
|
168
355
|
Linux delivery uses `notify-send`, `stdbuf`, and `gdbus`; audio uses `paplay` or `pw-play`.
|
|
169
356
|
On Ubuntu, `libnotify-bin`, `coreutils`, `libglib2.0-bin`, and `pulseaudio-utils` provide these
|
|
170
|
-
utilities. The MP3 decoder and
|
|
357
|
+
utilities. The MP3 decoder and six default sounds are bundled; FFmpeg is not
|
|
171
358
|
required. MP3 and mono/stereo PCM/float WAV files up to 4 MiB and 10 seconds are
|
|
172
359
|
normalized toward -20 dBFS RMS with a -3 dBFS peak ceiling before playback.
|
|
173
360
|
Custom sounds are loaded on first use; restart after replacing them.
|
|
@@ -176,6 +363,7 @@ with a low-latency buffer; preparation never blocks permission approval.
|
|
|
176
363
|
`stdbuf` makes delivery acknowledgements immediate instead of waiting for
|
|
177
364
|
`notify-send` to flush its output when the banner closes.
|
|
178
365
|
Disable overlapping notification plugins to avoid duplicate alerts.
|
|
366
|
+
</details>
|
|
179
367
|
|
|
180
368
|
## Development
|
|
181
369
|
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -29,7 +29,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
29
29
|
|
|
30
30
|
# Bundled audio decoder and supplied sounds
|
|
31
31
|
|
|
32
|
-
The
|
|
32
|
+
The six notification MP3 files were supplied by the maintainer with
|
|
33
33
|
permission to redistribute them with this plugin. Their original bytes are
|
|
34
34
|
embedded in the bundle. Normalization occurs during playback preparation.
|
|
35
35
|
|