본문으로 건너뛰기
S

dsh-shortcuts-prompt

smithtomge-alt/dsh-shortcuts-prompt

composer 위에 저장된 프롬프트 칩을 표시합니다. 칩을 누르면 초안의 커서 위치에 텍스트를 삽입합니다. 제자리에서 열리는 인라인 패널에서 프롬프트를 추가, 편집, 재정렬, 삭제할 수 있습니다. 프로필별로 저장하며 에이전트용 quick_prompts 도구도 제공합니다. 새로 설치하면 항목이 없습니다.

설치

dsh plugin --profile web add github:smithtomge-alt/dsh-shortcuts-prompt

README

快捷指令 · Quick Prompts

CI npm

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

FileRole
lib/index.jsHost activation: resolves the Harness bases, mounts the service, registers one agent tool
lib/service.jsDurable list + the five Remote methods (list / create / update / delete / move)
lib/schema.jszod schemas for records and wire payloads
client.jsBrowser bundle: the strip, the inline panel, the draft insertion
cordis.patch.ymlInserts the Host row
locale/{en,zh}.jsonPlugin inventory title/description
icon.svgInventory 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:

  1. npmjs.com → the package → Settings → Trusted publishing.

  2. Add a GitHub Actions publisher: repository smithtomge-alt/dsh-shortcuts-prompt, workflow publish.yml, environment left empty.

  3. 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:

  1. The Client entry never rejects. apply() delegates to activate() inside a try/catch and reports the failure, so a broken entry degrades to "strip unavailable" instead of failing web boot (which shows up as a DSH crash).
  2. The Remote contract is validated locally. preview/harness.js mounts the real client.js through a faithful subset of the API Gateway's validateContribution, 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, at order: 30 so 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 with margin-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 members assertMethodAvailable, has, install, installDirect, installScoped, and remove. A Remote method with one of those names fails to mount with client api: method ... conflicts with its namespace service, so deleting an instruction is exposed as quickPrompts/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, and zod through createRequire against the running installation instead of importing them.

관련 플러그인