본문으로 건너뛰기
L

dsh-capability-toggle-plugin

lifeopsgo/dsh-capability-toggle-plugin

Toggle individual agent capabilities (skills, MCP, tools, prompt, approval, guards) from the DSH WebUI composer — session / project / global. DSH 各种能力(mcp/skill/tool等)多层级开关灵活控制

설치

dsh plugin --profile web add github:lifeopsgo/dsh-capability-toggle-plugin

README

dsh-capability-toggle-plugin

Turn individual agent capabilities on and off from the DSH WebUI composer — and have it actually enforced.

platform tests license node

English · 简体中文

The capability popup: five tabs, one row per capability, three level switches each

Three switches per row — session, project, global. Blue check = on · red cross = off · dashed dash = unset.
The small badge on a set switch clears it; the right-hand badge is the resolved result.


What it is

A composer-row control for the DeepSeek Harness (DSH) WebUI. While the agent is idle, open the popup and switch individual skills, MCP servers, tools, prompt injections, the approval gate, and safety guards on or off — independently at the session, project, or global level.

Disabling something is not a cosmetic filter. A disabled capability really disappears from the model's tool schema set and skill catalog on the agent's next step, and a forced call is hard-refused.

🎛️ Five tabs, six familiesSkills · MCP · Tools · Prompt · Security
🧭 Three levels per rowsession › project › global › default (enabled)
🔒 Real enforcementremoved from the schema set, not hidden in the UI
Takes effect next stepno session restart
🌐 Bilingualzh-CN + en, follows the WebUI language

Quick start

Install into your DSH profile at a pinned tag — one command:

dsh plugin --profile web add github:lifeopsgo/dsh-capability-toggle-plugin#v0.1.0

Restart the GUI, then refresh the page:

dsh --profile web web

The control appears in the composer row next to the ➕ button. Click it while the agent is idle.

That is it. dsh plugin forwards to pnpm in the profile directory, then reconciles dsh.profile.bundles for you — a package declaring dsh.bundle (this one does) joins the layer stack automatically. No manual package.json editing.

Notes & other commands
  • Pin a tag — replace v0.1.0 with the tag you want; see releases. Use #main to track the branch instead.
  • --profile web is the usual profile for the Web GUI; substitute your own name if it differs.
  • No build step — the tag ships a prebuilt lib/, so installing runs no prepare script. You will not hit pnpm's build-approval prompt (allowBuilds) that git-hosted plugins otherwise require.
# upgrade to another tag
dsh plugin --profile web add github:lifeopsgo/dsh-capability-toggle-plugin#v0.2.0

# remove
dsh plugin --profile web remove dsh-capability-toggle-plugin

Features

The three-level model

Every capability exposes a session, project, and global switch, each either on, off, or unset.

session  ›  project  ›  global  ›  default (enabled)

The nearest level that is set wins; an unset level defers to the next one down. With all three unset, the capability stays enabled. The badge at the row's end always shows the resolved result across all three levels — so you never have to compute precedence in your head.

A switch shows only its current stance: click to flip on ↔ off, or hit the small clear badge to return it to unset.

The six capability families

FamilyTabOne row isNotes
skillSkillsOne model-invocable skillDisabling shadows it with a same-named modelInvocable:false skill
mcpMCPOne MCP server (mcp__<server>__* collapses into one switch)Denies every tool that server exposes; the row expands to list its member tools
toolToolsOne model-visible toolAlso hides that tool's tool:<name> guidance section — saves tokens, avoids "tool gone, guidance still there"
promptPromptOne gateable system-prompt injection pointA curated allowlist, probed for real presence: absent injection points show no switch
approvalSecurityThe approval-escalation gate (singleton)Off ⇒ every approval request from this agent is auto-rejected. Independent of the system /permission setting
guardSecurityOne opt-in safety presetDefault off. On ⇒ the guard acts on matching calls

How enforcement actually works

All five seams act on the agent's own scope, filtering the capability surface it inherits. Nothing global is mutated, and everything is restored when the agent is released.

FamilyMechanismResult
tool / mcpctx.tools.restrict({ deny }) on the agent's scopeThe tool leaves the model's schema set; request/header snapshots stop listing it; a forced call is refused
skillA same-named modelInvocable:false runtime skill shadows the real oneThe skill vanishes from <available_skills>; the skill tool's isModelInvocable check fails and throws
promptA same-named empty-text systemPrompt.section / .context shadow, or suppressRuntimeContext()The section is overridden during assembly and dropped at render; the owning service keeps running — only what the model is told changes
approvalA scoped approval/request listener resolving 'rejected'Every approval request from this agent is denied deterministically, without touching the deployment's shared policy
guardA tools/pre-execute listener matching the preset's predicateBlock refuses the call outright; Confirm raises one approval prompt and proceeds only if allowed

Security tab

Approval escalation (default on) — lets this agent raise actions that need your approval. Turn it off and every approval request from this agent is auto-rejected: no prompt, no elevation. Independent of the system /permission setting.

Guard presets (default off, opt-in). A guard reads inverted from the other families: on means protection is active, so its badge reads Guarding when it is doing something.

GuardActionCatches
Read-only mode🚫 BlockEvery file write / create / edit — the agent can read but not change files
Protect secrets🚫 BlockAny read, write, or shell command touching .env, *.pem, id_rsa, credentials, .ssh/
Confirm dangerous shell⚠️ Confirmrm -rf, dd, mkfs, chmod 777, curl | sh, fork bombs
Confirm destructive git⚠️ Confirmpush --force, reset --hard, clean -fd, branch -D
Confirm outbound network⚠️ Confirmweb_search, read_page, curl/wget, git push, npm publish

Block guards are evaluated before Confirm guards, so a blocking rule always wins over a confirmation prompt.

Prompt tab

The system-prompt registry exposes many entries, but most are unsafe to blank. This plugin gates only a curated few, and probes the live assembly so a switch appears only when your deployment actually registered that entry:

  • deployment:persona — the order-0 persona section; empty text is a documented first-class state.
  • sandbox:policy / approval:policy — the runtime-context snapshots that tell the model the sandbox mode and approval policy. Gating changes only what the model is told; the owning services still enforce for real.
  • Hide all runtime context — one coarse switch for this scope.

Deliberately excluded, because blanking them breaks the model or the render: harness:identity (identity foundation), tools:code-only / tools:sdk (critical to the code-mode protocol), and the strict interpolation variables provider / model / cwd.

Behaviour details

  • Locked while running — every switch is read-only while the agent works (session.running); toggles apply when it goes idle.
  • Survives popup close and turn boundaries — state lives in a settings namespace and the Host caches the last-known inventory, so reopening the popup between turns still shows disabled state correctly.
  • Framework-contract self-check — the seams this plugin binds to are asserted at activation and printed as one greppable banner line. If a host event is ever renamed, enforcement would fail open and silently stop — the most dangerous direction — so it is made observable.

MIT — see LICENSE

관련 플러그인