DSH Plugins Marketplace

DSH Plugins

Plugins

/

Tools & Capabilities

/

dsh-skill-dollar

d

dsh-skill-dollar

Manifest valid

Invoke DeepSeek Harness skills with a $name gesture — conflict-free with / commands, with composer completion and blue text-ref parity. Invoke DSH skill with $name gesture (conflict-free with / commands).

UI (client)hasBundlePatch

dsh-skill-dollar

Invoke DeepSeek Harness skills with a $ gesture instead of /.

DSH already uses /name for both host commands and user-invocable skills. This bundle keeps / for commands and adds a parallel $name gesture for skills, with the same composer menu, fuzzy ranking, keyboard pick, and deterministic host-side injection that the / skill path uses.

What it does

  • Client half (client.js) registers a candidate source under the trigger char $ over the session skill catalog (skills/list). Typing $ in the composer opens the normal trigger menu (title "Skills" / "技能"). Candidates are ordered by match quality first — name prefix, name substring, name subsequence, then description-only — and ties prefer the most recently picked skill, then the most frequently picked, then the host's own order. Picking a row inserts the literal text $skill-name .
  • Host half (index.js) listens on agent/pre-step, recognises the whitespace-bounded $name token in direct user messages, resolves it through the skills service, and appends the canonical <skill_content> block — byte-identical to what dsh-tool-skill does for /name.

Because the bridge is plain draft text, a menu pick and a hand-typed $name are the same gesture, exactly like the built-in slash pipeline.

How the client half plugs into the core

The input-trigger package hard-codes '/' | '@' in its detectTrigger, but the rest of the pipeline (source registry, menu reducer, keyboard arbitration, span CAS insertion) is keyed by an opaque trigger string. The client half:

  1. declares @deepseek-ai/dsh-client-ui-input-trigger in dsh.client.inject;
  2. requires that module from its factory and patches InputTriggerController.prototype.track;
  3. on a live $query token, synthesises a hit with trigger: '$' and drives the controller's own reduce/fetchCandidates/refreshHeaders against the '$' roster, so MenuView rendering and keyboard arbitration are reused without forking the core package.

When no $token is live the original track runs untouched, so / and @ behaviour is unchanged. Both halves depend on literals DSH may reformat, so neither fails silently: check-core-surface.mjs reports drift with a non-zero exit, the client half logs a console error when the controller shape is gone, and the host half warns once per served bundle when the reference scan no longer matches. The host half still makes a hand-typed $name work.

Install into a profile

The plugin directory is this repository root.

dsh plugin --profile web add /absolute/path/to/dsh-skill-dollar
dsh --profile web --dump-config

dsh plugin forwards to pnpm inside the profile and rebuilds dsh.profile.bundles. Then restart the web app so the new client module joins the boot graph: the host composes the client module manifest at startup, so a running dsh web must be restarted to serve client.js.

Install into DSH Desktop

DSH Desktop runs its own harness home — ~/Library/Application Support/dsh-desktop/harness on macOS — and snapshots every installed plugin into a content-addressed "generation" under profiles/.generations/live/. Two consequences matter:

  • a link: install in ~/.dsh/profiles/web does not reach Desktop; and
  • a running Desktop keeps the generation it booted from, so a plugin edit is only picked up after the profile is refreshed and Desktop restarts.

After editing this repo, reinstall/update dsh-skill-dollar in Desktop's profile (its plugin market or settings surface) so a new generation is built. Generation installs are restart-based: the running harness keeps the code it booted with, so press Cmd/Ctrl+Shift+R ("Restart Harness") — or quit and reopen DSH Desktop — to load the new generation. The version is bumped with each behavior change so the update is visible. Nothing else needs a manual step: the decoration is applied at boot by the plugin's host half (see below), never by editing a file inside the app bundle.

Verify

Repo-local, no external tooling:

node --test                  # transform, drift guard, registry hook, ranking
node check-core-surface.mjs  # DSH core anchors still hold (non-zero on drift)

node --test asserts the textual transform, the served-bytes hook, the drift warning, and the pure ranking/usage helpers against fixtures, and it re-runs the transform against every DSH install it can find on this machine. The client half is browser-side: verify it by opening the web app, typing $ in the composer, and confirming the skill menu appears and a pick loads the skill.

Blue text-ref decoration ($ parity with /)

The composer's blue "this is a reference" treatment is produced by a plain-text scan in @deepseek-ai/dsh-client-ui-conversation. Its token regex is hard-coded to / and @, and the trigger set is closed there — the input-trigger lexicon is already keyed by arbitrary trigger strings, and this plugin already publishes its skill names under $, but the scan never looks for $. No plugin API registers another text-ref trigger, so exact parity needs two literal substitutions in that bundle:

  • TEXT_REF_RE becomes /(^|\s)([/@$])([\w-]+)/g;
  • the /-only end-boundary rule (a token must end at whitespace or the draft end) is applied to $ as well.

Served at runtime (works in DSH Desktop)

Editing the file on disk is not an option inside DSH Desktop: the bundle lives in app.asar/app.asar.unpacked, whose unpacked files carry SHA-256 integrity hashes (ElectronAsarIntegrity in Info.plist), so a modified byte fails Electron's integrity check and invalidates the code signature.

Instead the host half (index.js) rewrites the bundle while it is served. @deepseek-ai/dsh-client-modules snapshots every client bundle in memory at boot and hands responses back through ClientModuleRegistry.bundleResource; the plugin wraps that method, substitutes $ into the scan, and returns the patched bytes. Degradation stays graceful:

  • the wrapper only touches text/javascript bodies that contain the shipped scan, so source maps and unrelated bundles pass through untouched;
  • if there is no clientModules service (older DSH), the plugin logs a hint and the $ menu and host injection still work;
  • the substitution is idempotent, so replaying it changes nothing.

Immutable /plugins URLs are cached by the browser for a year, so different bytes under the same URL would never be fetched. The plugin also salts the conversation row's revision (captureArtifactBaseline) and calls rebuilt(), which recomposes the boot graph with a fresh URL and forces the fetch. Bump TEXT_REF_PATCH_VERSION in bundle-patch.mjs when the patched bytes change.

A host that derives revisions from bundle content instead of file metadata does not see that salt (DSH 0.1.5 and earlier, including the current npx dsh web). On such a host the plugin logs a hint and you run the legacy patch once; the host's content-derived revision then changes and busts the cache by itself.

Legacy fallback

patch-core.mjs still applies the same two substitutions to a bundle on disk for hosts whose bundle revisions come from content (DSH 0.1.5 and earlier), which cannot be cache-busted in memory:

node patch-core.mjs            # resolve the bundle from the dsh install
node patch-core.mjs --check    # exit non-zero when the patch is missing
node patch-core.mjs --file <client.js>

Re-run it after a DSH upgrade only if you are on such a host; on DSH 0.1.7+ the served-at-runtime patch leaves nothing to re-apply.

Self-check

Everything this plugin adds beyond the official inputTriggers.registerSource pipeline hangs off two literals in DSH core:

  • ui-input-trigger detects only / and @ (type TriggerChar = '/' | '@'), so client.js hooks InputTriggerController.prototype.track;
  • ui-conversation's plain-text scan is /(^|\s)([/@])([\w-]+)/g, so the host half rewrites the served bytes.

Run the check after every DSH upgrade and before shipping a change to either patch:

node check-core-surface.mjs           # auto-locate installed DSH homes
node check-core-surface.mjs --root <node_modules/@deepseek-ai>
node check-core-surface.mjs --json

It prints one line per installed surface, quotes the offending scan when one changed shape, exits 1 on drift, and exits 2 when no installed DSH was found. If upstream ever widens the scan to $, it reports decoration-obsolete: the decoration patch and the TEXT_REF_PATCH_VERSION salt can then be deleted.

Design notes

  • The trigger char is deliberately fixed at $. The host and client halves must agree on it, and a host-only config knob would silently break the picked text, so there is no such knob.
  • The host half adds no bare package imports (only the node:crypto builtin and its own relative ./bundle-patch.mjs) so a link:-installed profile can resolve it; the two small framework helpers it needs (renderSkillContent, createUserMessage) are inlined byte-for-byte from @deepseek-ai/dsh-skill and @deepseek-ai/dsh-llm.
  • The decoration never writes to the DSH install. Both the served bytes and the salted revision are applied in memory, so DSH Desktop's integrity-sealed app.asar and code signature stay valid.
  • $VARS and shell-style tokens do not open the menu: a live query must match ^[a-z0-9-]*$, the skill-name grammar.
  • The ranking usage table lives in localStorage under dsh-skill-dollar/usage, is capped at 200 skills, and is best-effort: a locked-down profile or a corrupt value degrades to host order instead of throwing. It adds no runtime dependency.

Comments

Loading…

Similar plugins

dsh-command-skill-list

by weilantianhai

/skills command for DSH — list skills with auto-translated descriptions (zh↔en)

Manifest valid

★ 3

MIT

JavaScript

Sep 10, 2026

dsh plugin --profile web add dsh-command-skill-list

by a735624258

DSH 实现 workbuddy 同款选择 skill 功能 | WorkBuddy-style skill picker for DeepSeek Harness: pick a skill in the composer, insert the official /skill-name gesture, and DSH loads it with your message.

UI & ExperienceManifest valid

★ 35

↓ 1.5k/wk

MIT

JavaScript

Oct 2, 2026

dsh plugin --profile web add dsh-skill-picker

by jasonguide

一个多 Agent 平台的 Skills 统一管理插件(DeepSeek Harness 插件),可以在DSH中统一管理codex、claude code、PI、OpenCode、Hermes、Openclaw等平台的Skills技能

Manifest valid

★ 0

MIT

JavaScript

Aug 28, 2026

dsh plugin --profile web add dsh-skills-hub

by xingyingyuzhui

Manage DeepSeek Harness skills from Settings: list, disable without editing SKILL.md, and install/uninstall user-root copies. 设置里管理技能:清单 / 本机开关 / 用户根安装卸载。

Manifest valid

★ 0

MIT

JavaScript

Aug 17, 2026

dsh plugin --profile web add dsh-skill-manager

by SugarFatFree

DeepSeek Harness plugin for workspace commands, skills, and path-scoped rules.

Development & InfrastructureTools & CapabilitiesManifest valid

★ 0

MIT

JavaScript

Sep 23, 2026

dsh plugin --profile web add dsh-agent-extension

by DreamsTOF

DeepSeek Harness 的三合一能力台:提示词定制(按名称屏蔽 / 替换 / 注入 / 排序,按会话阶段与 agent 预设分层)+ 技能集合管理(导入 / 分组 / 开关)+ MCP Server 接入(分层遮蔽与工具级启停)。纯插件注入,不动官方源码。

Terminal & ClientsManifest valid

★ 0

MIT

JavaScript

Sep 19, 2026

dsh plugin --profile web add dsh-prompt-customizer