Bundle
dsh-review-squad
并行多角色代码评审小队:/review 一条命令派出安全/正确性/测试/风格四名只读评审员子代理(每人可单独指定模型与思考强度),汇总为按严重度分组的结构化报告。Parallel multi-role code review squad: /review dispatches security/correctness/tests/style reviewer subagents (each on its own model) and aggregates one severity-grouped report.
- Source
- luomeii
- License
- MIT
- Updated
- Updated yesterday
Readme
# dsh-review-squad
[](https://github.com/luomeii)  
[中文说明](./README.zh.md)
A **parallel multi-role code review squad** for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness).
One `/review` command dispatches independent reviewer subagents — **security**, **correctness**, **tests**, and **style** — that gather evidence themselves (read the diff, trace callers, check conventions) in strict read-only mode, and merges their work into one severity-grouped report. Each reviewer can optionally run on **its own model**: put your strongest model on security and a cheap fast model on style.
## Why
Existing dsh git plugins stop at diff viewers and worktree cleanup. Review is the workflow other agent ecosystems keep voting for with their stars (Claude Code's official security review, compound-engineering, Superpowers), and dsh's subagent registry — parallel spawned children, per-child model routing, tool filters — is exactly the right primitive for it.
## Install
```bash
# into a profile (default profile is `web`)
dsh plugin --profile web add dsh-review-squad
```
Or straight from a GitHub checkout:
```bash
dsh plugin --profile web add github:<owner>/dsh-review-squad
```
Requires dsh ≥ 0.1.1-rc.2 (the base bundle with `spawn` subagent provider and `tool-str-replace-editor` — both ship in `@deepseek-ai/dsh-base`).
## Use
### Slash command (you)
```
/review # full squad on uncommitted changes (git diff HEAD)
/review staged # staged changes only
/review commit abc1234 # one commit
/review path src/lib # one path
/review security tests # only these reviewers
/review --style # everyone except style
/review stop # stop this session's running review jobs
/review watch the retry logic # extra focus text for every reviewer
```
### Tool (your agent)
The model gets a `code_review` tool and can run the squad on its own work before calling a task done:
| parameter | meaning |
|---|---|
| `scope` | `diff` (default) · `staged` · `commit:<sha>` · `path:<dir-or-file>` |
| `focus` | extra concerns for every reviewer |
| `reviewers` | comma-separated keys, `--key` excludes |
### Background execution
`/review` runs the squad as a **background job** by default (`commandBackground: true`): the command returns instantly with a job id, so the chat input is never locked while the reviewers work. When the job settles, the session agent is notified; read the report with `job_output` (or just ask the model "read the review job result"). Set `commandBackground: false` (settings.yaml `review-squad:` section) to wait inline instead. The `code_review` tool always runs foreground.
### The report
```markdown
# Code review report — uncommitted changes
Reviewers: security, correctness, tests, style · findings: 5
| severity | count |
|---|---|
| CRITICAL | 1 |
## CRITICAL
- **SQL injection in user lookup — `src/db/users.ts:42` *(security)***
## Reviewer verdicts
- **security**: Would block merging: yes, because of the injection.
...
```
Failed reviewers are reported per-reviewer (stop reason + diagnostic + partial output) instead of dragging the whole run down. Reports are deterministically aggregated — no extra LLM call — and hard-capped (`maxReportChars`, INFO→LOW→MEDIUM sections dropped first).
## How it works
```
/review ──┐
├──► engine: pick reviewers ──► ctx.subagents.start("spawn", …) × N (parallel)
code_review ┘ │ per reviewer:
│ · prompt = persona + evidence guide + read-only rules + output format
│ · agentOptions = optional per-reviewer provider/model/effort
│ · toolFilter.deny = str_replace_editor, write, edit, subagent, subagent_fork
▼
results collected (timeout + cancel per reviewer) ──► deterministic merge
```
Reviewers are spawned dsh children: fresh context, their own tools, your workspace. They find the evidence themselves — `git diff`, reading files, tracing code — which is what makes the review deep instead of a prompt over a diff. Read-only is enforced twice: prompt discipline and a `toolFilter` deny list.
## Configuration
Override the `review-squad` row from a later patch layer (`~/.dsh/profiles/<profile>/cordis.patch.yml` or a `--patch` overlay). Patch rows replace whole configs — restate everything you keep.
| field | default | meaning |
|---|---|---|
| `provider` | `spawn` | `ctx.subagents` provider used for reviewers |
| `commandName` | `review` | slash command name |
| `toolName` | `code_review` | tool name |
| `toolFilterDeny` | `['str_replace_editor','write','edit','subagent','subagent_fork','workflow','ralph','send_message','web_search']` | tools reviewers lose — includes every delegation tool (they must not spawn anything) and web search (cost); unknown names are healed automatically |
| `timeoutMs` | `600000` | per-reviewer wall-clock budget |
| `maxConcurrent` | `2` | reviewers run in batches of this many (gentler on API limits) |
| `maxReportChars` | `24000` | report hard cap |
| `language` | `en` | descriptive text language (severity/file/line markers stay English so parsing works) |
| `reviewers` | built-in four | the squad (see below) |
### Custom squad — the "strong brain, cheap hands" pattern
```yaml
- id: review-squad
name: dsh-review-squad
config:
language: zh
reviewers:
- key: security
role: Security reviewer
instructions: Hunt for injection, authz gaps, committed secrets, unsafe crypto.
agentOptions:
provider: deepseek-official
model: deepseek-v4-pro
reasoningEffort: max
- key: style
role: Style reviewer
instructions: Naming, duplication, complexity, conventions.
agentOptions:
provider: my-cheap-gateway
model: glm-4.6-flash
```
`agentOptions` needs a provider that supports the `agentOptions` subagent capability (the built-in `spawn` provider does).
### Settings page (Web UI)
The plugin ships its own **"Review Squad"** section in the dsh web Settings page: edit each reviewer's model route (provider / model / reasoning effort / max tokens), report language, timeout, report budget, and the tool deny list. Saving goes through dsh's `settings.update` channel into the `review-squad:` section of `settings.yaml` and applies live (no restart).
### Runtime overrides — settings.yaml (hot-reloaded)
Every field except the structural ones (`commandName`/`toolName`) can also be changed **without restarting dsh** via the `review-squad:` section of `$DSH_HOME/settings.yaml` (`~/.dsh/settings.yaml`). Values there override the bundle config at every invocation:
```yaml
# ~/.dsh/settings.yaml
review-squad:
language: zh
timeoutMs: 300000
reviewers:
- key: security
role: Security reviewer
instructions: Hunt for injection, authz gaps, committed secrets, unsafe crypto.
agentOptions:
provider: deepseek-official
model: deepseek-v4-pro
reasoningEffort: max
- key: style
role: Style reviewer
instructions: Naming, duplication, complexity, conventions.
agentOptions:
provider: my-cheap-gateway # any provider configured on the Models page
model: glm-4.6-flash
```
Omit the section to fall back to the bundle config. (The bundle-config `reviewers` example in the patch layer above does the same thing at load time; prefer `settings.yaml` for day-to-day tuning.)
### Compat notes (verified)
- Verified end-to-end on **dsh 0.1.1-rc.2** (Windows, `deepseek-v4-flash`): real dispatched reviewer via `spawn`, per-reviewer `agentOptions` routing honored by the in-process driver, findings parsed and aggregated from real model output.
- On 0.1.1-rc.2 the `spawn` provider does not *declare* the `agentOptions` capability (it is honored at the driver level). The plugin pre-checks `capabilities.agentOptions` and, if a runtime rejects the route, retries the reviewer on the session's model and states that in the report — per-reviewer routing degrades loudly, never breaks the run.
- `toolFilterDeny` names are validated fail-loud by dsh; the defaults all exist in the base bundle on 0.1.1-rc.2.
- Overriding the plugin row from a `--patch` overlay or profile `cordis.patch.yml` uses the direct row form (`- id: review-squad` + `config:`), not `- insert:` (inserting a second row with the same id fails the boot).
## Development
```bash
pnpm install
node --test # 70 unit/integration tests, no dsh runtime needed
```
Smoke-test the composition without a running server:
```bash
dsh plugin --profile dshrs-dev add ./dsh-review-squad
dsh --profile dshrs-dev --dump-config | grep review-squad
```
> Note: while another dsh web instance is running, a second instance can hang at boot (shared `$DSH_HOME`); stop the first one before booting the dev profile — or point `DSH_HOME` at a scratch directory for fully isolated runs.
## Submit to awesome-dsh-plugin
`docs/awesome-entry.yml` is the ready-made YAML entry (category `git`). Fill in your `owner`, add the `dsh-plugin` topic to your repo, and follow the one-entry-per-PR rules of [awesome-dsh-plugin](https://github.com/awesome-dsh-plugin/awesome-dsh-plugin).
## Feedback & contact
Found a bug or want a feature? Open an [issue](https://github.com/luomeii/dsh-review-squad/issues) or start a [discussion](https://github.com/luomeii/dsh-review-squad/discussions). For direct contact: luomeiy@outlook.com · https://github.com/luomeii
## License
MIT
Install
dsh plugin --profile web add github:luomeii/dsh-review-squad#aaa6d1fb1e6e6007822ae5580202f7a0c7055452
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install dsh-review-squad from the hub