dsh-plugin
DayuanJiang/next-ai-draw-iodsh 的 draw.io 绘图插件:通过 next-ai-drawio MCP 服务器作图,点回复里的链接在右侧栏打开实时预览,可以手动修改图,AI 的每次修改都是可以恢复的版本。需 Node.js 18+,首次使用由 npx 下载 MCP 服务器。
以 advisor / reviewer / designer 角色无头调用 Claude Code,回复作为参考答案。
External-expert consultation for DeepSeek Harness: the agent headlessly invokes the Claude Code CLI through explicit advisor, reviewer, designer, or custom role contracts, then weighs the structured replies as reference answers.
English | 中文
A single harness has one perspective. At a consequential decision, before declaring risky work done, or before significant new code, a second model can supply useful independent evidence. That is a hypothesis to measure, not a guaranteed quality gain: persona research does not show that merely calling a model an expert reliably improves accuracy. This plugin makes consultation a bounded tool call instead of a copy-paste detour. Claude answers under a behavioral and output contract, and DSH receives the result as advice to weigh, not obey.
Phase 1 speaks only to the Claude Code CLI. The settings schema (v2, one workspace per harness), the UI tab catalog, and the runner seam are already multi-backend: codex, zcode, kimi-code, pi, opencode, and omp each land later as a runner behind the same three tools.
| 🎭 Role contracts | Built-in advisor / reviewer / designer with different objectives and JSON contracts, or your own (outputKind, prompt, model, fallback, effort). enabled parks a role without deleting it |
| 🧠 Thinking effort | Native --effort (low / medium / high / xhigh / max) at three levels: per-call argument > role > global default |
| 🔄 Model fallback | One-hop retry on model-level errors (unrecognized_model, model-not-found, …) with usedFallback recorded in run metadata |
| 🤖 Agent tools | consult_expert (one role, one question) · consult_panel (up to N roles in parallel, one wall-clock wait) · consult_roles (live roster) |
| 🎛 Auto consult | Composer-seat toggle (permissions row) picks roles per session; a policy section rides the system prompt and lifecycle nudges fire at write/finish anchors, budgeted per role per session |
| 🖥 Settings workspace | One tab per harness CLI; saves hot-apply — role edits reach the agent's next model step without a dsh restart |
| 🔬 Connectivity test | One real consultation end-to-end (CLI + login + proxy) with turns, duration, cost, and fallback marker |
| 🛡 Defense in depth | Read-only CLI tools, strict MCP isolation when supported, permission pinning, typed schemas, bounded output/turns/time, and explicit untrusted-evidence labels |
| 🌐 Fully bilingual | Every UI string — including built-in role descriptions, reserved-backend notes, and validation messages — follows the UI language (zh/en); agent tooling keeps stable English identifiers |
# from npm (recommended)
dsh plugin --profile web add dsh-capability-optimizer
# or straight from the GitHub repo
dsh plugin --profile web add github:hezhongtang/dsh-capability-optimizer
Restart dsh web (or your profile of choice). Works in any profile — web, tui, headless — because the tools are host-side agent tools.
Requirements: the claude CLI (npm i -g @anthropic-ai/claude-code) on PATH, logged in.
Ask your agent:
"consult the reviewer on this diff before we call it done"
The agent picks the role and calls consult_expert. For a precise task it can send a structured brief: trusted objective, successCriteria, and constraints, plus currentAttempt, artifacts, verification, and unknowns, which are explicitly labeled untrusted evidence. Legacy context remains an artifact shorthand. Claude's role-specific envelope returns with model, turns, duration, cost, and protocol metadata.
| Tool | Read/Write | Purpose |
|---|---|---|
consult_expert | read* | One role, one question, optional structured brief (or legacy context), optional model / effort overrides |
consult_panel | read* | Several distinct role contracts on one brief, in parallel; this is not a majority vote |
consult_roles | read | Live roster including outputKind, role-level model/effort, and global defaults |
* Read-only for your workspace; each call spends your Claude subscription quota — the tool descriptions themselves tell the model to batch material instead of machine-gunning calls.
The composer toolbar (the permissions control's row) carries an Expert Consult toggle. Checked roles add selection criteria and lifecycle reminders for this session; the plugin does not invoke them automatically.
off | remind | hard-remind (default remind). Legacy required settings migrate to hard-remind.hard-remind additionally logs the missed designer checkpoint but never claims the host blocked Write.capPerRole (default 3) counts real consult_* calls per role per session — nudges and the model's own discretionary calls share it. At the cap the promise drops out of the policy text and the anchors go quiet.used/cap) per role; the last selection is remembered per browser. Settings → Expert Consult → Auto consult edits the default checked set and budget (row-config key autoConsult) — the same layer tui/headless profiles consume.A session-scoped card bar above the composer shows every real consultation in near real time: queued / running / fallback retry / succeeded / failed / cancelled. While running, a card shows model, effort, and captured stdout bytes; when finished it shows the failure kind, or a bounded preview of the reply / envelope. consult_panel yields one card per role, so partial failures stay visible per role.
The dock takes no vertical space while idle; terminal cards can be dismissed individually or cleared together, and closing the session clears the bar. Entries live only in plugin memory (the latest 8 terminal cards per session, plus a hard active-card ceiling of 24; never context / brief / artifacts), and replies/errors are server-truncated previews. This is status polling plus a final-reply preview, not token streaming; on hosts without the conversation.input.dock slot or the status route it simply does not mount / stops polling.
Settings → Expert Consult is organized as one workspace per harness CLI — a tab bar over the catalog (claude-code live; codex, zcode, kimi-code, pi, opencode, omp reserved with a planned-status page and no settings stored until their runners land). The Claude Code workspace manages everything at runtime:
--effort: low/medium/high/xhigh/max), fallback model, per-call timeout, max turns, panel size, per-consult dollar cap, extra CLI args (allowlisted; --settings is refused).advisor | reviewer | designer | general), system prompt, model, fallback, and effort. Disabled roles stay in the roster but leave the tool enum.off | remind | hard-remind); the composer toggle overrides the checked set per session.~/.dsh/dsh-capability-optimizer/settings.json (atomic writes, 0600) and hot-applies: the agent tools re-register immediately. Reset removes the file and restores defaults.Call-site model / effort override role values, which override global defaults. The built-in advisor defaults to claude-opus-5 as an overridable quality preference, not a role-name-based prohibition. fallbackModel retries once on a model-level error and records requestedModel, CLI-reported actualModel / actualModels, derived effectiveModel, and usedFallback.
The row's config still works as the base layer (settings file wins once saved):
| Key | Default | Meaning |
|---|---|---|
cliPath | claude | Path to the CLI when it is not on PATH. |
model | CLI default | Model alias (opus, sonnet, ...) applied when a call does not specify one. |
timeoutMs | 300000 | Wall-clock cap per consultation. |
maxTurns | 16 | Agentic turn cap inside the CLI. |
maxPanelRoles | 4 | Roles per consult_panel call. |
maxBudgetUsd | 0 | Per-run dollar cap (--max-budget-usd) when the CLI supports it. 0 means no cap. |
extraArgs | [] | Extra CLI args, allowlisted. Flags that widen permissions, break the JSON protocol, or duplicate typed settings are dropped and reported. |
roles | built-ins | Custom roles: add new ones, or override a built-in by reusing its name. |
autoConsult | { enabled: [], capPerRole: 3, mode: 'remind' } | Default checked set, per-role per-session budget, and trigger mode (off | remind | hard-remind). Legacy required migrates. |
Example — a security-focused custom role:
- id: dsh-capability-optimizer
name: 'dsh-capability-optimizer'
config:
model: sonnet
roles:
- name: security
outputKind: reviewer
description: Threat-model focused reviewer for auth, crypto, and injection surfaces.
systemPrompt: |-
Objective: falsify the security of the supplied change.
Report only concrete authentication, authorization, injection,
secret-handling, or unsafe-parsing defects with a trigger and evidence.
claude -p process per consultation. The labeled brief goes through stdin, the shared trust policy and selected role contract through --append-system-prompt, and the reply comes back as one JSON document.--safe-mode disables user/project instructions, skills, plugins, hooks, MCP, and memory while preserving authentication and built-in tools. Independent layers still apply --tools Read,Grep,Glob, --strict-mcp-config, --setting-sources user, a pinned --permission-mode, and --no-session-persistence; older CLIs use whichever layers they advertise. Write/execute or external-capability-widening extraArgs never reach argv; the documented --add-dir exception may widen read scope. Caller cancellation (AbortSignal) and the wall-clock timeout stay distinguishable.--max-turns (default 8) caps agentic turns inside the CLI.pass cannot contain findings); schema-valid JSON is not treated as proof that its claims are true.objective, question, success-criteria, and constraints define the task. Code, comments, files, current attempts, verification text, unknowns, and tool results are labeled untrusted evidence. This is a model-layer control, not a claim that prompt injection is solved.What the plugin guarantees:
--dangerously-skip-permissions or any permission-bypassing flag. extraArgs is an allowlist, not a passthrough. On a CLI that advertises the containment flags, a consultation gets exactly Read, Grep, Glob and no MCP server — verified against a real CLI, including against a project whose own .claude/settings.json asks for bypassPermissions (evidence, reproducible with DCO_LIVE_CLI=1 npm test). Each flag is feature-detected, so a CLI too old to advertise it degrades rather than failing; meta.safeMode / meta.tools / meta.strictMcp / meta.permissionMode report what was actually enforced.What you should know (inherent to any agent-consults-agent setup):
claude -p yourself. Do not paste secrets you would not send to Claude directly.The repository includes a controlled reviewer benchmark comparing a role-free minimal contract, the frozen 0.5.x prompt, and the current prompt on the same model/effort/tasks over repeated trials. It records prompt hashes, seeded-defect recall, unmatched findings, injection success, envelope reliability, cost, latency, containment, and CLI-reported model(s). Formal runs abort if the reported model does not exactly match the preregistered model. Dry-run plumbing passes; no formal paid result is claimed here. See eval/README.md and the evidence review.
Advisor and designer have role-specific contract tests, but no outcome benchmark yet. Their presence is an interface and workflow choice—not evidence that expert persona wording raises intelligence.
Issues and PRs welcome at hezhongtang/dsh-capability-optimizer. The codebase is intentionally small and dependency-free — plain ESM on the host, a hand-authored CJS bundle in the browser, no build step to set up. Adding a harness backend = one runner module (see lib/claude.js) + flipping available in lib/backends.js.
MIT © 2026 hezhongtang