@capybearista/opencode-adversarial-review 1.0.0 → 2.0.1

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,161 +1,167 @@
1
1
  # opencode-adversarial-review
2
2
 
3
- <p align="center">Challenge code with adversarial review</p>
3
+ <p align="center">Unbiased challenges and reviews for your code</p>
4
4
  <p align="center">
5
- <a href="https://www.npmjs.com/package/@capybearista/opencode-adversarial-review"><img alt="npm" src="https://img.shields.io/npm/v/@capybearista/opencode-adversarial-review?style=flat-square&color=8d60e6" /></a>
6
- <a href="https://www.npmjs.com/package/@capybearista/opencode-adversarial-review"><img alt="npm" src="https://img.shields.io/npm/dm/@capybearista/opencode-adversarial-review?style=flat-square&color=6067e6" /></a>
7
- <a href="https://opencode.ai"><img alt="opencode" src="https://img.shields.io/badge/OpenCode-Plugin-orange?style=flat-square&color=60a5e6
8
- " /></a>
5
+ <a href="https://www.npmjs.com/package/@capybearista/opencode-adversarial-review"><img alt="npm version" src="https://img.shields.io/npm/v/@capybearista/opencode-adversarial-review?style=flat-square&color=8d60e6" /></a>
6
+ <a href="https://www.npmjs.com/package/@capybearista/opencode-adversarial-review"><img alt="npm downloads" src="https://img.shields.io/npm/dm/@capybearista/opencode-adversarial-review?style=flat-square&color=6067e6" /></a>
7
+ <a href="https://opencode.ai"><img alt="opencode" src="https://img.shields.io/badge/OpenCode-Plugin-orange?style=flat-square&color=60a5e6" /></a>
9
8
  <a href="https://opensource.org/licenses/MPL-2.0"><img alt="license" src="https://img.shields.io/badge/License-MPL--2.0-blue.svg?style=flat-square&color=60dfe6" /></a>
10
9
  </p>
10
+
11
11
  ---
12
12
 
13
13
  ## Why?
14
14
 
15
- > Provides an adversarial code review agent that challenges implementation approach and design choices, not just finding bugs. Uses a clean-context subagent so the review is unbiased by conversation history.
15
+ > Two code review agents with a clean-context subagent each, so reviews are unbiased by conversation history: an **adversarial reviewer** that challenges approach and design choices (modeled on the Codex CLI's review system), and a general **constructive reviewer** that checks correctness first and suggests improvements.
16
16
 
17
17
  ## Philosophy: Extending OpenCode
18
18
 
19
- OpenCode is designed to be highly extensible. This plugin hooks into the OpenCode lifecycle to provide additional functionality seamlessly into your workflows. This plugin is modeled after the Codex CLI's adversarial review system, focusing on "breaking confidence" rather than validating changes.
19
+ OpenCode is designed to be highly extensible. This plugin adds adversarial and constructive review passes directly to your workflow.
20
20
 
21
21
  ### Architecture
22
22
 
23
23
  ```mermaid
24
24
  graph TB
25
- subgraph Host [OpenCode Host]
26
- User([User]) -->|/adversarial-review| Command[Command Template]
25
+ subgraph OpenCode [OpenCode]
26
+ User([User]) -->|"/adversarial-review / /constructive-review"| Command[Installed Command Templates]
27
+ Command -->|"$ARGUMENTS + five shell blocks"| Reviewer
27
28
  end
28
29
 
29
- subgraph Injection [Context Injection]
30
- direction LR
31
- Command -->|!git status| S[Status]
32
- Command -->|!git log| L[Commits]
33
- Command -->|!git diff| D[Diff Summary]
34
- Command -->|!cat| U[Untracked]
30
+ subgraph Plugin [Plugin]
31
+ Setup[setup] -->|registers| Reviewer{"adversarial-reviewer<br/>constructive-reviewer<br/>hidden subagents"}
32
+ Setup -->|"atomic install; stamped refresh"| Command
35
33
  end
36
34
 
37
- subgraph Adversary [Adversarial Subagent]
38
- direction TB
39
- Reviewer{Adversarial Reviewer}
40
- S & L & D & U --> Reviewer
41
-
42
- Reviewer -->|Self-Collect| Tools[Explorer Tools]
43
- Tools -->|Source Code| Reviewer
35
+ subgraph Review [Review Session]
36
+ Reviewer -->|self-collected evidence| Tools[read / grep / glob / git / gh]
37
+ Tools --> Reviewer
38
+ Reviewer -->|"requested output: JSON / Markdown"| User
44
39
  end
45
40
 
46
- Reviewer -->|Structured JSON| User
47
-
48
- classDef host fill:#bbf,stroke:#333,stroke-width:2px;
49
- classDef collection fill:#dfd,stroke:#333,stroke-width:1px,stroke-dasharray: 5 5;
41
+ classDef opencode fill:#bbf,stroke:#333,stroke-width:2px;
42
+ classDef plugin fill:#dfd,stroke:#333,stroke-width:1px,stroke-dasharray: 5 5;
50
43
  classDef adversary fill:#f9f,stroke:#333,stroke-width:2px;
51
-
52
- class Host host;
53
- class Collection collection;
54
- class Adversary adversary;
44
+
45
+ class OpenCode opencode;
46
+ class Plugin plugin;
47
+ class Review adversary;
55
48
  ```
56
49
 
57
- The plugin uses a **stateless subagent architecture**. When the command is invoked, a deterministic shell script collects git metadata (diff stat, untracked files, recent commits) and injects it into a fresh subagent session. This ensures the review is unbiased by the primary agent's conversation history.
50
+ One config drives two sandboxed subagents: agents register in memory and commands install to disk,
51
+
52
+ - **Agents**: setup registers the hidden `adversarial-reviewer` and `constructive-reviewer` subagents; nothing is written to your agents directory.
53
+ - **Commands**: setup installs `~/.config/opencode/commands/adversarial-review.md` and `~/.config/opencode/commands/constructive-review.md` into your OpenCode config directory.
54
+ - **Prompts**: `src/prompt.ts` holds both system prompts; `src/prompts/adversarial-review.md` and `src/prompts/constructive-review.md` are their reference copies. All review doctrine — target selection, evidence rules, output contract — lives there, never in the command templates.
58
55
 
59
56
  ## Features
60
57
 
61
- - **Adversarial Persona**: A specialized subagent prompted to find reasons *not* to ship, prioritizing auth gaps, race conditions, and data loss.
62
- - **Dynamic Context Collection**: Automatically switches between full-inline diff (for 1-2 files) and high-level stat (for larger changes).
63
- - **Subagent Self-Collection**: The subagent uses whitelisted git and file tools to "pull" the specific file contents it needs based on the initial diff summary.
64
- - **Structured JSON Output**: Returns findings with severity, file locations, confidence scores, and concrete recommendations.
65
- - **Configurable Scope**: Support for `--base <ref>`, `--scope branch`, and `--scope working-tree`.
58
+ - **Two reviewers**: adversarial (reasons *not* to ship) and constructive (correctness first, then suggestions).
59
+ - **Reviewer-collected evidence**: changed files, untracked files, and branch diffs are inspected with read-only tools; only verified findings are reported.
60
+ - **Auto-installed commands**: both slash commands are written on first setup; stamped files refresh on `/reload`, user-owned edits are preserved (see note below).
61
+ - **Targets**: `--scope`, `--base`, bare commit SHA, or PR URL/number on both commands.
66
62
 
67
63
  ## Install
68
64
 
69
- Add the plugin to `opencode.json` or `opencode.jsonc`:
65
+ ### OpenCode V2
66
+
67
+ Add it under the `"plugins"` key in `opencode.json(c)`:
68
+
70
69
  ```json
71
70
  {
72
- "plugin": ["@capybearista/opencode-adversarial-review"]
71
+ "plugins": ["@capybearista/opencode-adversarial-review@latest"]
73
72
  }
74
73
  ```
75
74
 
76
- You can also install it through the CLI:
75
+ Server entry only, so `cli.json` needs no entry.
77
76
 
78
- ```bash
79
- opencode plugin -g @capybearista/opencode-adversarial-review # global install
80
- opencode plugin @capybearista/opencode-adversarial-review # project-local install
81
- ```
77
+ ### OpenCode V1
82
78
 
83
- ## Usage
79
+ Add it under the `"plugin"` key in `opencode.json(c)`:
84
80
 
85
- Run a review on your current working tree changes:
86
- ```bash
87
- /adversarial-review
81
+ ```json
82
+ {
83
+ "plugin": ["@capybearista/opencode-adversarial-review@1.0.0"]
84
+ }
88
85
  ```
89
86
 
90
- ### Arguments
87
+ Server entry only, so `tui.json(c)` needs no entry.
91
88
 
92
- | Argument | Values | Description |
93
- | :--- | :--- | :--- |
94
- | `--scope` | `auto`, `working-tree`, `branch` | The range of changes to review. Defaults to `auto`. |
95
- | `--base` | `<git-ref>` | The base reference (branch or commit) to compare against when using `branch` scope. |
89
+ See the [V1 plugin guide](../../docs/v1-plugins.md) for details.
96
90
 
97
- - **`auto`**: Reviews using the broadest context the provided information supports.
98
- - **`working-tree`**: Reviews staged and unstaged changes against `HEAD`.
99
- - **`branch`**: Reviews all changes on the current branch since it diverged from the upstream or main branch.
100
- - **`focus ...`**: Any trailing text is treated as a focus area for the review.
91
+ On setup, both command files install at `~/.config/opencode/commands/{adversarial-review.md,constructive-review.md}`. The directory **must already** exist; if a file cannot install, setup fails loudly and **neither** agent is registered.
101
92
 
102
- ### Examples
93
+ ### Uninstall
103
94
 
104
- Force review of only working tree changes (ignoring branch history):
105
- ```bash
106
- /adversarial-review --scope working-tree
107
- ```
95
+ Remove the plugin from `"plugin(s)"` from the respective config files they were added to. Then delete both installed command files—plugin removal does not delete them, and OpenCode would otherwise keep discovering commands with no agents behind them.
108
96
 
109
- Review all changes on the current branch (automatically finds the fork point):
110
- ```bash
111
- /adversarial-review --scope branch
112
- ```
97
+ ## Usage
113
98
 
114
- Review a specific branch against its fork point from `main`:
115
- ```bash
116
- /adversarial-review --base main
117
- ```
99
+ Both commands accept `--scope auto|working-tree|branch`, `--base <ref>`, a bare commit SHA, or a PR URL/number. A PR URL always wins; otherwise the first bare token decides (all-decimal → PR, 7+ hex chars with a letter → commit); an explicit target beats the flags. `/adversarial-review` treats remaining text as a focus area; `/constructive-review` ignores trailing non-flag text (no focus support).
118
100
 
119
- Review with a specific focus area:
120
101
  ```bash
121
- /adversarial-review --base main focus on race conditions in the auth middleware
102
+ /adversarial-review # working tree (or branch, if tree is clean)
103
+ /adversarial-review --scope branch # current branch since fork point
104
+ /adversarial-review 4f2a9c1e # a commit
105
+ /adversarial-review 42 # PR #42 (bare number; hex SHAs stay commits)
106
+ /constructive-review --scope working-tree # constructive pass, working tree only
107
+ /constructive-review --scope branch # constructive pass, current branch since fork point
108
+ /constructive-review 4f2a9c1e # constructive pass, a commit
109
+ /constructive-review 42 # constructive pass, PR #42
122
110
  ```
123
111
 
112
+ > [!NOTE]
113
+ > The installed command files are managed via a `managed_version` stamp in their frontmatter. Keep the stamp and the file refreshes from the bundled template on `/reload`; remove it to take ownership — the file is then left untouched with a warning. Unknown or newer stamps are likewise preserved (downgrades never clobber). A failure partway can leave the first file as a harmless orphan; it is reconciled on the next `/reload`, and registration still waits for both files. Delete a file and `/reload` to force-reinstall; uninstall the plugin *and* delete both files to fully remove the commands.
114
+ >
115
+ > The same ownership rule cleans up an upgrade leftover: a pre-rename build installed the second command as `commands/review.md` with `agent: reviewer`, an agent this version no longer registers, so OpenCode discovers it as a broken `/review`. Setup removes that exact file only when it carries `agent: reviewer` plus a `managed_version` stamp this build knows; any other `review.md` is preserved, with a warning when it carries the old agent id. Setup never deletes a file on a failed refresh unless its `O_TRUNC` open already ran — an unreadable/unwritable managed file is left intact and setup fails loudly instead.
116
+
124
117
  ## Configuration
125
118
 
126
- | Property | Type | Description |
127
- | :--- | :--- | :--- |
128
- | `agent.adversarial-review.model` | `string` | The model to use for the subagent (defaults to `openai/gpt-5.4`). |
129
- | `agent.adversarial-review.temperature` | `number` | Sampling temperature (defaults to `0.1` for deterministic review). |
130
- | `command.adversarial-review.template` | `string` | The shell-injected template used to gather git context. |
119
+ Nothing is pinned — model and temperature are both inherited. Resolution order for the model: frontmatter `model` (add manually to pin) → agent `model` in OpenCode config → invoking session's model, with its temperature. To pin a reviewer model, set it in `opencode.json`/`opencode.jsonc`:
131
120
 
132
- This plugin requires no manual configuration out of the box, but you can override the subagent model in your local `opencode.json`.
121
+ ```jsonc
122
+ {
123
+ "agents": {
124
+ "adversarial-reviewer": { "model": "openrouter/openai/gpt-6-sol" },
125
+ "constructive-reviewer": { "model": "openrouter/openai/gpt-6-sol" }
126
+ }
127
+ }
128
+ ```
133
129
 
134
130
  ## Permissions & Security
135
131
 
136
- This plugin is designed with a "least privilege" security model. The adversarial subagent is strictly sandboxed to prevent accidental or malicious modifications to your codebase:
132
+ Both reviewers are sandboxed and unattended; the single accepted risk is pasted arguments (below). Details:
133
+
134
+ **Pasted arguments become executable template content.** `$ARGUMENTS` is substituted before the snapshot blocks run, so argument text can execute as shell. Inspect arguments before invoking, and never pass untrusted or pasted Markdown containing backtick blocks.
137
135
 
138
- - **Edit**: Explicitly denied (`edit: deny`).
139
- - **Bash**: Restricted to a read-only whitelist of 12 Git patterns (e.g., `git diff`, `git log`, `git status`). All other shell commands are blocked.
140
- - **Read/Grep/Glob**: Allowed (read-only) to enable code inspection.
141
- - **Network**: Web fetch and search are disabled to ensure the review remains focused on the files at hand.
136
+ One shared sandbox: `edit`/`write`/`patch`, `subagent`, `skill`, `webfetch`/`websearch`, `question` denied (zero ask — reviewers run unattended); shell limited to 13 read-only `git` patterns plus `gh pr view*`/`gh pr diff*` and the `gh auth status*` diagnostic (token-printing and all other `gh` denied); `read`/`grep`/`glob` allowed except `.env`/`.env.*` (`.env.example` allowed, as is `git show <rev>:<path>` of a `.env.example` blob). See `AGENTS.md` for the full rule inventory.
142
137
 
143
138
  ## Troubleshooting
144
139
 
145
- - **"No changes to review"**: Ensure you have staged or unstaged changes, or use `--base` to review a committed branch.
146
- - **Model timeouts**: Large diffs may require a model with a larger context window or more time. The subagent is whitelisted to `read` files if the diff stat is too long to include.
147
- - **Git errors**: Ensure you are running within a git repository. The command relies on `git` being available in your PATH.
140
+ - **Setup failed installing a command file**: create (or fix permissions on) `<config>/commands/`, then `/reload`. A readable-but-unwritable managed file is left untouched, never deleted.
141
+ - **"Leaving it untouched" warning**: the file is user-owned or carries an unknown/newer stamp — edit in place, or delete to reinstall.
142
+ - **Broken `/review` after upgrading**: a pre-rename build's `commands/review.md` references the removed `reviewer` agent. Setup removes it when it carries a known stamp; an unstamped copy is preserved with a warning — delete that file manually.
143
+ - **File replaced on `/reload`**: it kept a known stamp and was refreshed; remove the stamp to take ownership.
144
+ - **"No changes to review"**: stage changes or pass `--base`.
145
+ - **PR target fails**: needs authed `gh`; the reviewer reports that plainly (stderr verbatim on failure).
146
+ - **Large diffs**: use a model with a bigger context window; reviewers also read files as they work.
147
+ - **Not a git repo**: the template needs `git` on `PATH` inside a repository.
148
148
 
149
149
  ## Contributing
150
150
 
151
151
  This package lives in the `opencode-plugins` monorepo.
152
152
 
153
- - Run `bun run build`, `bun run typecheck`, `bun run lint`, and `bun test` before opening a PR.
154
- - Keep the plugin focused on the adversarial code review function.
153
+ See the [contribution guidelines](../../CONTRIBUTING.md) before opening a pull request.
154
+
155
+ - From the monorepo root, run `bun run build` before artifact checks, then `bun run typecheck`,
156
+ `bun run lint`, and the canonical `bun run test` Turbo pipeline. Do not use bare root `bun test`
157
+ as the workspace check.
158
+ - For a focused run, `bun test` is supported from this package directory; its tests include the
159
+ real local-directory resolver regression.
160
+ - `bun run check` writes Biome changes; use it only when formatting changes are intended.
155
161
  - Prefer small, direct changes.
156
162
 
157
163
  Please open an issue or check for existing ones before creating a pull request.
158
164
 
159
165
  ## License
160
166
 
161
- [MPL-2.0](LICENSE)
167
+ [MPL-2.0](./LICENSE.txt)
@@ -0,0 +1,28 @@
1
+ ---
2
+ description: "Adversarial code review: challenges the implementation. Args: [<sha|pr-url|pr-number>] [--base <ref>] [--scope auto|working-tree|branch] [focus ...]"
3
+ agent: adversarial-reviewer
4
+ subagent: true
5
+ managed_version: 2
6
+ metadata: Managed by @capybearista/opencode-adversarial-review. Keep the managed_version stamp to receive bundled-template updates on /reload or restart; remove it to take ownership and your version is then preserved with a warning; a stamp newer than the shipped template is also preserved.
7
+ ---
8
+
9
+ # Adversarial review handoff
10
+
11
+ You are the adversarial reviewer for this repository. Review the change and return the structured JSON verdict defined in your system prompt.
12
+
13
+ Target selection, focus weighting, evidence rules, and the output contract live in your system prompt — follow them.
14
+
15
+ Args and focus: $ARGUMENTS
16
+
17
+ The blocks below are a point-in-time snapshot rendered by this template. They can be incomplete: commands can fail, output can be empty, and untracked file contents are not inlined. Verify everything with your own read-only tools before reporting.
18
+
19
+ - Branch:
20
+ !`git branch --show-current 2>&1 || true`
21
+ - Status:
22
+ !`git status --short --untracked-files=all 2>&1 || true`
23
+ - Recent commits:
24
+ !`git log --oneline -3 2>&1 || true`
25
+ - Working-tree diff against HEAD:
26
+ !`git diff HEAD 2>&1 || true`
27
+ - Untracked files (paths only; read their contents with your tools):
28
+ !`git ls-files --others --exclude-standard 2>&1 || true`
@@ -0,0 +1,30 @@
1
+ ---
2
+ description: "Constructive code review: correctness and risk. Args: [<sha|pr-url|pr-number>] [--base <ref>] [--scope auto|working-tree|branch]"
3
+ agent: constructive-reviewer
4
+ subagent: true
5
+ managed_version: 2
6
+ metadata: Managed by @capybearista/opencode-adversarial-review. Keep the managed_version stamp to receive bundled-template updates on /reload or restart; remove it to take ownership and your version is then preserved with a warning; a stamp newer than the shipped template is also preserved.
7
+ ---
8
+
9
+ # Review handoff
10
+
11
+ You are the constructive reviewer for this repository. Review the change for correctness first, then for material maintainability risk, and return the Markdown report defined in your system prompt.
12
+
13
+ Review only: do not modify the repository; report findings and suggestions for the author to apply.
14
+
15
+ Target selection (scope flags and explicit targets; no focus text), evidence rules, and the output contract live in your system prompt — follow them.
16
+
17
+ Args: $ARGUMENTS
18
+
19
+ The blocks below are a point-in-time snapshot rendered by this template. They can be incomplete: commands can fail, output can be empty, and untracked file contents are not inlined. Verify everything with your own read-only tools before reporting.
20
+
21
+ - Branch:
22
+ !`git branch --show-current 2>&1 || true`
23
+ - Status:
24
+ !`git status --short --untracked-files=all 2>&1 || true`
25
+ - Recent commits:
26
+ !`git log --oneline -3 2>&1 || true`
27
+ - Working-tree diff against HEAD:
28
+ !`git diff HEAD 2>&1 || true`
29
+ - Untracked files (paths only; read their contents with your tools):
30
+ !`git ls-files --others --exclude-standard 2>&1 || true`
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import type { Plugin } from "@opencode-ai/plugin";
2
- export declare const AdversarialReviewPlugin: Plugin;
3
- declare const _default: {
4
- id: string;
5
- server: Plugin;
6
- };
1
+ import { Plugin } from "@opencode/plugin";
2
+ export declare const CURRENT_TEMPLATE_VERSION = 2;
3
+ export declare const KNOWN_TEMPLATE_VERSIONS: readonly number[];
4
+ export declare function managedVersionOf(markdown: string): number | undefined;
5
+ export declare function isManagedUpgrade(installedVersion: number, knownVersions: readonly number[], currentVersion: number): boolean;
6
+ declare const _default: Plugin.Plugin;
7
7
  export default _default;