dsh-tab-complete
v0.1.1
Published
DSH web plugin: Tab completes the highlighted slash-menu candidate in the composer (commands, skills, subagents, @-file references), without executing anything.
Readme
dsh-tab-complete
A DeepSeek Harness web plugin: Tab completes the highlighted slash-menu candidate in the composer input, without executing anything.
Part of the dsh-plugins collection.
Behavior
| Highlighted candidate | Tab |
| --- | --- |
| Command with input (/goal, /feedback) | Completes /goal via the product's own claim path — the token is colored and the parameter hint shows; keep typing args, then Enter executes. |
| Bare command (/compact, …) | Completes /compact as plain text with no trailing space; the menu stays open on the token, so the next Enter executes it exactly like typing it manually. |
| popupSelect command (/resume, /model, …) | Completes /resume bare (no trailing space) — the menu stays open and the next Enter opens the command's second-stage selection panel; a trailing space would silently break that panel trigger. |
| Skill / subagent | Completes /skill-name / @subagent (delegated to each source's own pick). |
| @-file reference (dsh-at-file) | Completes @relative/path from the candidate's value (not the display name); directory candidates keep their / suffix. |
| Menu closed | Tab keeps its default focus behavior. |
Nothing executes on Tab; popupSelect shells (/model, /resume, …) are never
opened by Tab itself — they stay ready for the user's own Enter (which opens
them via the product menu pick). IME composition is never intercepted, and Tab
with a modifier key (Shift/Ctrl/Alt/Meta) always keeps its default browser
behavior. While the menu is open but its candidates are still loading, Tab
keeps the focus inside the composer instead of letting it escape.
How it works
- Host half (
lib/index.js) exists only so the package mounts as a regular loader entry; it contributes nothing. - Client half (
lib/client.js) installs one capture-phasekeydownlistener. While the slash menu is open (detected via itsaria-activedescendantcombobox contract) and the focused composer textarea has a highlighted candidate, Tab:- for the
commandsource, completes the token, then synthesizes Space so the product's ownmatchSpaceclaim path engages (claim-colored token + hint for input-taking commands). When no claim happens (bare commands and popupSelect contributions), no trailing space is added — the menu stays open on the completed token, and the user's Enter goes through the product's menu pick (execute, or open the popupSelect panel for commands like/resume); - for any other source (skill, subagent, dsh-at-file, future plugins), delegates to the source's own pick via the product Enter path, so the candidate's authoritative value is used.
- for the
Install
# from the collection root — bundle channel (takes effect on next dsh start)
dsh plugin --profile web add ./plugins/dsh-tab-complete
# or local-dev channel (hot-applied by the running server, no restart):
./scripts/install.sh web plugins/dsh-tab-completeUninstall: dsh plugin --profile web remove dsh-tab-complete.
