dsh-shortcuts-prompt
smithtomge-alt/dsh-shortcuts-prompt
在会话输入框上方维护常用 prompt:点胶囊把内容插入草稿光标处,并可展开内联面板新增、编辑、排序、删除;条目按 profile 持久化,同时以 quick_prompts 工具提供给 agent,初始不预置任何条目。
安装
dsh plugin --profile web add github:smithtomge-alt/dsh-shortcuts-promptREADME
快捷指令 · Quick Prompts
A DeepSeek Harness (DSH) plugin that keeps a strip of reusable prompts directly above the conversation composer.
- The strip starts empty: a single dashed pill reading 快捷指令.
- Click a chip to insert its prompt at the draft caret.
- Click the pill (or the 管理 control once chips exist) to expand the management panel inline, between the strip and the composer — no dialog, no scrim.
- The panel holds the list (name + summary + insert / edit / move up / move down / delete) and the form. Both the name and the prompt body are required. A successful add or save always collapses the panel; a failed write keeps it open and shows the error, so the draft is not lost.
- The strip itself never edits: it only inserts and opens the manager.
Everything is stored per profile through the DSH storage domain, so the list survives restarts. Nothing is pre-seeded.
Layout
| File | Role |
|---|---|
lib/index.js | Host activation: resolves the Harness bases, mounts the service, registers one agent tool |
lib/service.js | Durable list + the five Remote methods (list / create / update / delete / move) |
lib/schema.js | zod schemas for records and wire payloads |
client.js | Browser bundle: the strip, the inline panel, the draft insertion |
cordis.patch.yml | Inserts the Host row |
locale/{en,zh}.json | Plugin inventory title/description |
icon.svg | Inventory artwork |
The model sees the same data through the quick_prompts tool, which calls the
same service methods as the UI.
Install
From npm:
dsh plugin --profile <profile> add dsh-shortcuts-prompt
From this repository (source install; it is plain JavaScript, so no build step):
dsh plugin --profile <profile> add github:smithtomge-alt/dsh-shortcuts-prompt
In the desktop app, install it from Plugins (Plugin Manager) instead of the CLI: the desktop profile is managed by the application. Restart or reload the page after installing so the browser half joins the Client module graph.
Publish
The package is a bundle: dsh.bundle points at cordis.patch.yml, and
dsh.client declares the browser artifact. It ships no runtime npm
dependencies — the Host resolves the Harness packages it needs at activation.
First publish (once, by hand)
npm requires an interactive two-factor challenge for publishing, so the first version is released from a terminal:
npm adduser --auth-type=legacy --registry https://registry.npmjs.org
npm run check && npm test
npm publish --otp=<current 6-digit code> # publishConfig picks the registry
The OTP is required even when you are logged in: the token npm adduser writes
is a login token, and npm only accepts a bypass token (being retired) or an
interactive code for publish.
Automated releases (trusted publishing)
.github/workflows/publish.yml publishes on a GitHub Release (or a v* tag)
using npm trusted publishing: GitHub's OIDC identity is exchanged for a
short-lived registry token, so there is no NPM_TOKEN secret to leak or rotate.
Set it up once, after the first publish:
-
npmjs.com → the package → Settings → Trusted publishing.
-
Add a GitHub Actions publisher: repository
smithtomge-alt/dsh-shortcuts-prompt, workflowpublish.yml, environment left empty. -
Bump and tag:
npm version patch # or minor / major — updates package.json + tag git push --follow-tags gh release create "v$(node -p "require('./package.json').version")" --generate-notes
The workflow refuses to publish when the tag does not match the manifest
version, runs the same checks as CI, publishes with --provenance, and then
waits for the registry to serve the new version. A manual workflow_dispatch
run defaults to --dry-run.
Bypass-2FA granular tokens still work for direct publish today, but npm is retiring that path for publishing, which is why this workflow does not use a secret. See Restricting npm bypass-2FA granular access tokens.
Community listing: open a PR against
awesome-dsh-plugin
adding data/plugins/<owner>__<repo>.yml; the site, the market, and the
dsh-plugin-catalog index are generated from those files. Listing the plugin is
a one-time entry — later releases need no further PR.
Boot safety
Two guarantees keep this plugin from ever aborting the page load again:
- The Client entry never rejects.
apply()delegates toactivate()inside a try/catch and reports the failure, so a broken entry degrades to "strip unavailable" instead of failingweb boot(which shows up as a DSH crash). - The Remote contract is validated locally.
preview/harness.jsmounts the realclient.jsthrough a faithful subset of the API Gateway'svalidateContribution, so a malformed contribution fails in the preview instead of in the app.
The contribution must be { package, descriptors: [...] }; the Gateway iterates
contribution.descriptors, and an object shaped as { package, methods } throws
TypeError: contribution.descriptors is not iterable — which aborts web boot.
Design notes
- Placement. The entry registers in
conversation.input.dock, the slot for full-width rows directly above the composer card, atorder: 30so it sits closest to the card. Its width and centering mirror--dsh-composer-card-max-width, so its left and right edges line up with the input box. - Theming. Colors come only from
--dsw-alias-*tokens; the stylesheet is a single element inserted for the Client run and removed with it. - Dock placement. The strip registers at
order: 19— above the built-in queue dock (order: 20) and below the goal dock. That dock ends withmargin-bottom: calc(0px - var(--dsh-composer-stack-gap) - 3px)to tuck its panel under the composer card; registering above it keeps the strip out of that negative margin instead of being dragged under the card with it. - Wire method names. The Client Gateway's Remote namespace service reserves
ctx,empty,invokeRemote,methods,name,namespace, plus the prototype membersassertMethodAvailable,has,install,installDirect,installScoped, andremove. A Remote method with one of those names fails to mount withclient api: method ... conflicts with its namespace service, so deleting an instruction is exposed asquickPrompts/delete(the UI and the agent tool keep calling it "delete"/"remove" in prose). - Host dependencies. A profile install keeps DSH's own packages inside the
application, so the Host half resolves
TypertRemoteService, the storage domain helpers, andzodthroughcreateRequireagainst the running installation instead of importing them.