Introduction¶
The DSH (DeepSeek Harness) input box only holds the current sentence. In long sessions, you might have just asked “re-sort this log by error”, and a few turns later want to ask “sort by time again”. The native approach is to scroll the chat window, find the old question, copy, and paste; another common approach is to rely on model completion, but that requires waiting for it or fearing it will send directly.
The plugin introduced below handles both in the same input box: Backward scroll – every question sent in this session can be scrolled back to re-edit; Forward guess – based on the recent turns, it gives the sentence you are likely to send next, displayed as gray ghost text, and you accept it by pressing →. Any key press only modifies the draft; sending still requires pressing Enter yourself.
The plugin is client-side. Repository Heeweelee/dsh-prompt-suggestions, package name dsh-composer-suggestions, MIT license, current version v1.1.0, author Heeweelee.
What is this¶
One-sentence definition: A DSH composer plugin that adds “History Rollback + Next Sentence Prediction” to the input box, or in official terms, “like Claude Desktop, no need to type repeatedly”. It does not auto-send, does not add new panels outside the main content, and all operations occur within the input box and the draft.
It solves two specific pain points:
- High cost of retyping old questions; early turns in long sessions might be clipped off the chat interface by compaction, and pagination might not reach the first sentence.
- Next sentence has to be organized from scratch, while it is often just a continuation of the last result (“continue”, “split the second paragraph”).
Core Features¶
| Ability | Usage |
|---|---|
| History Rollback | Press ↑ in an empty input box to step back one by one through questions sent in this session; ↓ to step forward one by one |
| Draft Protection | When stepping past the latest entry, restore the originally unsent draft |
| History Search Panel | Press Ctrl+↑ to open the panel; keyword filtering, ↑↓ to select, Enter to fill in, Esc to close |
| Next Sentence Prediction | When the Session is idle, gray ghost text appears in the input box |
| One-key Accept | Press → to turn the prediction into ordinary editable text, edit it, then send |
| No Auto-send | Any key press only modifies the draft; sending still requires Enter |
Rollback covers the entire session. The basis for judgment is source.kind = user in the session log: manually typed, pasted, sent after accepting a prediction via plugin →, or queued for interjection – in the session, they are all a single user/message, so all are covered. Runtime injected content (time context, skill directory, compression archives, subtask notifications) is also a user role message and is excluded – this is the only basis for distinguishing “sent by human” from “inserted by machine”.
The plugin does not hijack the keyboard: multi-line editing, cursor in the middle, input method composition – arrow keys work normally. ↑ only takes over in three cases: draft is empty, or draft is single-line (content is saved, ↓ can restore), or draft is multi-line but cursor is at the very beginning.
Installation and Enablement¶
Recommended to install directly from GitHub, no registry needed:
dsh plugin --profile desktop add github:Heeweelee/dsh-prompt-suggestions
Other methods are in the repository’s INSTALL.md:
# A. Install from npm
plugin_manager install_bundle dsh-composer-suggestions
# B. Use tarball from Releases, add to profile's package.json
"dsh-composer-suggestions": "file:D:/path/dsh-composer-suggestions-1.1.0.tgz"
# C. Local development directory
plugin_manager install_bundle D:\Ai_Tool\dsh_tool\packages\prompt-suggestions
After installation, it can be toggled in “Plugins → Installed Plugins”.
The package’s engines require dsh >= 0.2.1-rc.5; you can confirm the current DSH version before installation.
Typical Usage¶
Operate directly in the input box; no extra commands to remember:
-
Reuse previous question in long session: Cursor left in empty input box, press
↑to step back one by one, can scroll all the way to the first sentence of the session; press↓to step back one by one; when scrolling past the latest entry, restore the originally unsent draft. -
Too much history don’t know which one: Press
Ctrl+↑to open the history panel. The panel has its own independent input box; type keywords to filter,↑↓to select, Enter to fill in, Esc to close. When the panel is open, the keyboard is handed over to the panel’s own<input>, not competing with the host input box for events. -
Let plugin guess next sentence: After sending a message, keep the input box empty and wait a moment; gray ghost text will appear; press
→to accept it as normal text, edit it, then press Enter to send. -
Gray half-sentence appears while typing: Indicates you have typed the prefix of the prediction; the host will append the remaining part to the body; after pressing
→, the draft equals the full prediction, and it uses the host’s own undo stack.
The source of predictions is clearly marked in the UI, making it easy to judge whether this guess comes from the model:
| Marker | Meaning |
|---|---|
→ Accept |
Model prediction, hover to see time taken |
→ Accept · Local |
Server did not respond, using local rules |
Prediction Unavailable |
Server did not respond and local rules cannot give meaningful suggestions; ghost text does not appear, hover to see failure reason |
DevTools Console outputs a line per round [prompt-suggestions] model 1832ms <text> or local fallback <ms>, along with failure reasons and the actual request URL.
Implementation Details¶
The plugin follows a typical two-part structure, with Host and Web Client managing their respective halves:
| File | Platform | Role |
|---|---|---|
index.js |
Host | Registers POST /prompt-suggestions/suggest and POST /prompt-suggestions/history on the DSH Web server |
client.js |
Web Client | Registers the conversation.input.overlay slot: intercepts arrow keys, backtracks history, draws ghost text |
-
The data source for history fill has two layers, with Host priority. The Host’s authoritative list directly reads the complete event log of that Session, takes all messages where
source.kind === 'user', returns the most recent 200 in chronological order, preserving the full original text (including newlines, max 4000 characters). Therefore it is not limited by chat window pagination, nor affected by compaction clipping early turns off the surface. It falls back touseChat’s local window when the Host route is unreachable. -
Ghost text has two rendering methods: when the draft is empty, it absolutely positions a layer of gray text in the overlay, aligned with the box where the host placeholder is, copies font line height from editor
getComputedStyle, and uses--dsw-specific-input-majorto cover the placeholder; when the draft is the prediction prefix, it writes to the host’s built-in inline hint channel--dsh-composer-hint, which the host CSSp:last-child::afterappends the remaining part to the body; newlines and letter spacing match the real input. -
The prediction request goes through the Host route:
POST /prompt-suggestions/suggest
x-prompt-suggestions: 1
{"sessionId": "session-..."} → {"suggestion": "...", "cached": false}
Context is taken from session.deriveMessages(), last 10 messages, truncated to 700 chars per message, total 4000 chars. The model route takes ctx.agentDefaultModel.currentSelection(), reasoningEffort is forced to the most economical tier for that route, maxTokens: 700. Results are cached for 5 minutes based on sessionId + message count to avoid billing refreshes. The interface parses the URL based on document.baseURI, not assuming http(s) – the desktop interface runs on a custom protocol dsh-app://app/, using this to judge origin gets "null", requests can never be sent.
- Failure handling has two layers. Empty filler: when the model only returns “continue / ok / good” etc., stricter prompts are used to ask for specific suggestions again; if both are filler, no ghost text appears. Request failure retries with 0.6s / 1.2s / 2.4s backoff; if four attempts fail, it falls back to local rules, trying again when the window regains focus or visibility. Adding
x-prompt-suggestions-debug: 1returns adebugfield (stage, attempts, filler, raw output, finish reason, actual route).
Applicability and Notes¶
Suitable for: sessions with many turns, frequent reuse of old questions, and users who want the model to prepare the “next sentence” but don’t want it to decide when to send for them. For scenarios sensitive to keyboard behavior in the input box and wanting full control over arrow keys, note that the plugin only takes over ↑ under the three conditions listed above.
Points to note during use:
- The plugin runs with the current DSH process’s permissions, involving local files, session data, and network requests. Check the source code and license before installing. This repo is MIT; you can read
index.jsandclient.jsdirectly (outsideINSTALL.md) to confirm behavior. - The two routes go through the DSH Web server, unauthenticated by browser Cookies, relying only on custom request headers + loopback address monitoring; cross-site requests cannot carry that header.
- Prediction only requests when the Session is idle; no ghost text during generation.
- Empty session (no messages yet) does not predict; no context to rely on.
- No ghost text when the model gives filler twice in a row – “sometimes no prediction” is an acceptable failure mode by design.
- The panel does not do time grouping or cross-session search, only lists questions from the current session.
- The Host side only keeps the most recent 200, 4000 chars each; older questions remain in the session, just not in the rollback list.
- Falls back to locally loaded window when the Host route is unreachable; in long sessions, the depth you can scroll to depends on how many chat views are loaded.
- The panel uses
position: fixedpositioning; if the host addstransformto the ancestor of the input card in the future, the overlay positioning will change.
Summary¶
The value of this plugin lies not in complex mechanisms, but in filling the two missing pieces of the input box: an ↑/↓ that can scroll back the entire session, and a ghost text that can be edited before accepting. No auto-send throughout, changes are on the draft, risk is controllable. Installation method: install directly from GitHub dsh plugin --profile desktop add github:Heeweelee/dsh-prompt-suggestions, package name dsh-composer-suggestions, MIT, v1.1.0.
- Directory: https://www.skillhub.cn/plugins/Heeweelee/dsh-prompt-suggestions
- Repository: https://github.com/Heeweelee/dsh-prompt-suggestions