DSH Plugins Marketplace

DSH Plugins

Plugins

/

Tools & Capabilities

/

dsh-qwenpaw-bridge

d

dsh-qwenpaw-bridge

Manifest valid

DSH bundle plugin that upgrades the ACP profile for QwenPaw: live assistant streaming, hot-switchable permission presets, and a one-shot model catalog in _meta.qwenpaw.

hasBundlePatch

dsh-qwenpaw-bridge

A DSH bundle plugin that upgrades the stock acp profile for QwenPaw without touching DSH core. It keeps the wire standard ACP: QwenPaw still talks to @deepseek-ai/dsh-acp, so the adapter needs no private protocol.

This is the standalone repository for the bridge. The QwenPaw-side plugin lives in BillYuan01/qwenpaw-dsh; the bridge can be installed and tested without it.

The upstream half of this idea (opt-in streaming inside dsh-acp itself) remains open; this package is the plugin half and needs no DSH core changes.

What it adds

#CapabilityWire surfaceFail-soft behavior
1Live streamingstandard session/update with agent_message_chunk / agent_thought_chunk from agent/assistant-stream text-delta / reasoning-delta; duplicate committed text/thought suppressedevent missing / subscription fails / client opts out → stock committed projection, unchanged
2Permission presets, hot-switchable_meta['qwenpaw'].permission_presets + a permission_mode select in configOptions; switch through session/set_config_option or qwenpaw/permission/setctx.permissionPresets missing → no option advertised, and permission_mode switches are rejected with -32602 (no silent fallback)
3Model catalog_meta['qwenpaw'].models on initialize and session/new; every model carries its reasoning_effortsctx.llm lookup failure → field omitted, no crash
4Tool kind polish (optional)tool_call.kind mapped from the tool name (read/edit/execute/search/fetch)unknown names stay other

Everything else (images, tool updates, usage, config updates, MCP, resume, cancel) is forwarded verbatim.

Requirements

RequirementValue
Node>= 22
DSH>= 0.2.0-rc.2 < 0.3.0-0 (the <0.3.0-0 upper bound excludes 0.3 prereleases)
@deepseek-ai/dsh-acpsame range, supplied by the dsh-acp-app bundle
@agentclientprotocol/sdk^1.4.0, supplied by @deepseek-ai/dsh-acp
pnpmrequired by dsh plugin add (the CLI shells out to pnpm)
Clientany ACP client; QwenPaw is the reference consumer

DSH enforces the declared peer ranges before it loads a plugin. An incompatible DSH needs an explicit dsh plugin --profile <name> allow-version ... exemption; do not bypass it for a real deployment.

Install

1. Create the profile from the shipped acp template

qwenpaw is not a shipped profile, so create it first. This is important: dsh plugin add on a brand-new name initializes only dsh-base, which has no ACP app and therefore no acp-app-startup row.

# initialize the profile and exit immediately (do not boot ACP here)
dsh --profile qwenpaw --from-default-profile acp --dump-config >/dev/null

Without --dump-config the profile boots its app, which for acp waits on stdin; use the command above for setup.

2. Install the bridge into that profile

# published package
dsh plugin --profile qwenpaw add dsh-qwenpaw-bridge

# local checkout (works before the first npm release)
dsh plugin --profile qwenpaw add /absolute/path/to/dsh-qwenpaw-bridge

dsh plugin add runs pnpm in $DSH_HOME/profiles/qwenpaw, writes the package.json dependency and appends the bundle to dsh.profile.bundles. It needs pnpm on PATH; without pnpm the command exits 127 and installs nothing.

After the install the profile is:

@deepseek-ai/dsh-base
@deepseek-ai/dsh-acp-app
dsh-qwenpaw-bridge

The bundle patch disables the stock acp row and inserts qwenpaw-bridge. acp-app-startup is left in place: it owns stdin EOF and --help.

3. Supply the model route

The bundle defaults to ctx.agentDefaultModel. To pin a route, merge examples/profile/cordis.patch.yml into $DSH_HOME/profiles/qwenpaw/cordis.patch.yml and edit the provider, models and API-key variable. Do not overwrite a patch that already has a route, and do not add a second qwenpaw-bridge row — the bundle already inserts one.

The sample contains only llm-pi-ai + agent-default-model; the bridge row is intentionally absent.

4. Boot

dsh --profile qwenpaw

Verify the composition

dsh --profile qwenpaw --dump-config > /tmp/qwenpaw.dump

grep -A8 -- "- id: qwenpaw-bridge" /tmp/qwenpaw.dump
grep -A12 -- "- id: acp$" /tmp/qwenpaw.dump | grep "disabled: true"
grep -A2 -- "- id: acp-app-startup" /tmp/qwenpaw.dump
grep -c -- "- id: qwenpaw-bridge" /tmp/qwenpaw.dump   # must print 1

Expected: qwenpaw-bridge exists exactly once, its name is dsh-qwenpaw-bridge, the acp row has disabled: true, and acp-app-startup is present.

_meta['qwenpaw'] contract (protocol = 1)

initialize result:

{
  "_meta": {
    "qwenpaw": {
      "protocol": 1,
      "bridge": "dsh-qwenpaw-bridge",
      "version": "0.1.0",              // always package.json.version
      "streaming": true,
      "models": [
        {
          "id": "deepseek-v4.1-flash",
          "name": "DeepSeek V4.1 Flash",
          "provider": "opencode-go",
          "provider_name": "opencode-go",
          "selection_value": "[\"opencode-go\",\"deepseek-v4.1-flash\"]",
          "description": "…",              // optional
          "context_window": 1000000,       // optional
          "max_tokens": 384000,            // optional
          "input_modalities": ["text", "image"], // optional
          "reasoning_efforts": [{"id": "low", "name": "Low"}, …],
          "default_reasoning_effort": "high",    // optional
          "default": true                  // current route
        }
      ],
      "current_model": {"provider": "opencode-go", "model": "deepseek-v4.1-flash"},
      "permission_presets": [{"id": "workspace-write", "name": "workspace-write"}, …],
      "default_permission_preset": "workspace-write",
      "permission_preset": "workspace-write"
    }
  }
}

session/new / session/resume results repeat the same object (with current_model/permission_preset resolved for that session), and configOptions gains:

{
  "id": "permission_mode",
  "name": "Permission mode",
  "category": "permission",
  "type": "select",
  "currentValue": "workspace-write",
  "options": [{"value": "read-only", "name": "read-only"}, …]
}

The model count is route-dependent. Do not hard-code a number in a client; assert non-empty, per-model efforts, and exactly one default: true.

Client-side switches

// standard ACP: hot switch, no process restart
{"method": "session/set_config_option",
 "params": {"sessionId": "…", "configId": "permission_mode", "value": "read-only"}}

// optional private helpers (ACP extension methods; the SDK sends the leading
// underscore automatically: `_qwenpaw/permission/set`)
{"method": "qwenpaw/permission/set", "params": {"sessionId": "…", "preset": "read-only"}}
{"method": "qwenpaw/permission/get", "params": {"sessionId": "…"}}
{"method": "qwenpaw/streaming/set", "params": {"enabled": false}}

An initial preset can be requested in session/new: params._meta.qwenpaw.permission_preset = "read-only".

To opt out of live deltas for a connection, send initialize._meta.qwenpaw.streaming = false; the response then advertises "streaming": false and the stock committed projection is used.

Package layout

lib/index.js      plugin entry: inject acp services + acpAppStartup, build the ACP stream, call acp.apply
lib/inbound.js    bridge-owned requests; permission_mode interception
lib/outbound.js   _meta decoration, committed-duplicate suppression, config options
lib/stream.js     agent/assistant-stream -> session/update; duplicate flags
lib/catalog.js    provider/model/efforts discovery for _meta
lib/presets.js    ctx.permissionPresets projection + switch
lib/toolkind.js   tool name -> ACP kind
lib/protocol.js   _meta key, bridge name/version, config ids, response helpers
cordis.patch.yml  disables `acp`, inserts `qwenpaw-bridge`
examples/profile/cordis.patch.yml
                  sample model route (no bridge row)
test/probe.py     live acceptance probe (streaming / meta / presets / committed fallback)
test/spike_lib.py self-contained ACP client helpers used by the probe
test/protocol.test.js
                  asserts BRIDGE_VERSION == package.json.version
status-plugin/    host-only web-profile plugin: QwenPaw connection card
CHANGELOG.md

There is no profile/install.sh and no static profile package.json in this repository: profile creation and package installation are owned by dsh.

Web UI status card (status-plugin/)

status-plugin/ is a separate, host-only DSH web plugin. It adds a QwenPaw 桥接状态 card under 插件 → 已安装 and probes QwenPaw's /api/harnesses when the web profile boots:

  • Green + 运行中 — QwenPaw is reachable and its dsh backend is available.
  • Red + 失败 — QwenPaw is down, or the dsh backend is unavailable; open the card for the error.

Install it into the web profile (not qwenpaw):

dsh plugin --profile web add /path/to/dsh-qwenpaw-bridge/status-plugin
# restart dsh web / dsh-web.service

The bridge itself remains the qwenpaw-profile package at this repository's root; the status card only reports whether QwenPaw is connected. It samples at web-profile boot, so a later disconnect needs a web restart to turn red.

Development checks

for f in lib/*.js; do node --check "$f"; done
node --test test/protocol.test.js
npm pack --dry-run

The tarball must contain lib/, cordis.patch.yml, README.md, LICENSE and CHANGELOG.md, and must not contain profile/install.sh, a static profile manifest, or any reference to the old scoped package name.

The live probe requires an installed qwenpaw profile and real model credentials:

~/.qwenpaw/venv/bin/python test/probe.py \
    --dsh-home "$DSH_HOME" --profile qwenpaw

# committed-mode fallback
~/.qwenpaw/venv/bin/python test/probe.py \
    --dsh-home "$DSH_HOME" --profile qwenpaw --committed

The probe never creates or rewrites a profile. If the profile is missing it reports not-verified and exits 2.

Compatibility / failure policy

  • No DSH core changes; the stock @deepseek-ai/dsh-acp apply() is reused directly with a custom config.stream (the same runtime-only field the community dsh-acp-door uses).
  • Non-public dependencies are optional: agent/assistant-stream, ctx.permissionPresets, ctx.llm catalog calls, and ctx.agentDefaultModel are all read defensively. Missing anything degrades to plain committed ACP.
  • Peer range: the DSH packages are declared as >=0.2.0-rc.2 <0.3.0-0. The upper bound deliberately excludes 0.3.0-rc.1; a 0.3 runtime must be retested before widening the range.

See TESTING.md for historical monorepo evidence and the evidence measured for this standalone repository.

License

MIT. See LICENSE.

Comments

Loading…

From the same category

reactive-resume

DeepSeek Harness plugin for Reactive Resume: bridges your resumes and job applications into a Harness session over MCP.

Tools & CapabilitiesManifest valid

★ 41.7k

↓ 121/wk

MIT

Aug 24, 2026

dsh plugin --profile web add dsh-plugin-reactive-resume

by Tencent

Let AI agents use your real, logged-in browser without interrupting your work. CLI + extension for browser automation across any shell-capable AI agent.

Tools & CapabilitiesManifest valid

★ 9.4k

↓ 8.7k/wk

MIT

TypeScript

Oct 23, 2026

dsh plugin --profile terminal add @wxg-prc-cpg/browser-skill-dsh-plugin

by dsh-market

The plugin market inside DeepSeek Harness — browse, search, one-click install · DSH 可视化插件市场

Tools & CapabilitiesManifest valid

★ 8.3k

↓ 163.6k/wk

MIT

TypeScript

Oct 22, 2026

dsh plugin --profile web add dshmarket

by yjh051108

dsh-routing-suite — injector + router-standard kit: install the runtime injector first, then the task-aware reasoning-mode router preset (measured P1-P23).

Tools & CapabilitiesManifest valid

★ 7k

MIT

JavaScript

Sep 18, 2026

dsh plugin --profile web add @dsh-external/dsh-super-injector

by Q00

Agent OS: the agent gets smarter on its own. We just hold the line: Interview-gated, staged evaluation, budgeted evolution loop. MCP server, 14 runtimes: Claude Code, Codex CLI, Gemini CLI, OpenCode,

Tools & CapabilitiesManifest valid

★ 6.3k

MIT

Python

Oct 23, 2026

Index only — not installable

by superdesigndev

OpenRouter for agent tools. Join community here: https://discord.gg/6mQYYfFMAn

Tools & CapabilitiesManifest valid

★ 6k

NOASSERTION

Python

Oct 23, 2026

dsh plugin --profile web add treg-dsh