为业务包提供命令UI层,包括会话级命令目录缓存、/命令源、execute/popupSelect/leadingInput三种派发方式和popupSelect注册,解决命令发现执行与UI展示
ⓘ 此插件是大仓库 deepseek-ai/deepseek-harness 的子包,星数与活跃度统计的是整个仓库。
- 语言
- TypeScript
- License
- MIT
- 分支
- master
安装
$ dsh plugin --profile web add npm:@deepseek-ai/dsh-client-ui-commands在终端中运行以上命令,通过 dsh CLI 安装此插件。可在右上角切换 Profile。 第一次用 dsh?看这篇新手教程
对话式安装
帮我安装 DeepSeek Harness 插件 deepseek-ai/deepseek-harness/packages/client/ui-commands:先查看仓库 https://github.com/deepseek-ai/deepseek-harness 确认安全性,然后执行安装命令并验证插件加载成功。
把这段指令粘贴给 DSH Web GUI 里的助手,由它代你完成安装与验证。
English | 中文
Client command API (ctx.commandUi): the session-keyed command-directory cache, the / command source with matchSpace/matchEnter decision hooks, three-kind dispatch (execute / popupSelect / leadingInput), and popupSelect registration for business packages. The web command Agent Note records the decision.
src/client/contract.ts is the fixed business contract: CommandUiContract.register(name, spec) and decorate(name, spec) are everything a business package consumes; CommandUiSpec{options, onSelect} keeps popup data self-contained — the shell component belongs to this package and business packages never see it. A contribution is a client-owned command (a host-name collision fails loud); a decoration adds a bare-invocation popup to an EXISTING host command. The host keeps its catalog row, argument claim (space / argued Enter), and lifecycle logging, and a decorated name with no host row in the session's directory never fires. Command kinds derive per dispatch, never per registration: a host descriptor with input is leadingInput, a registered CommandUiSpec is popupSelect, and everything else is execute.
CommandDirectory (src/client/directory.ts) is the one wire-derived cache, keyed by session. Ordinary sessions fetch through command.list({sessionId}), and the source's scope-birth warm hook prewarms the session's entry. Catalog-addressed continuable children resolve an empty command directory locally: command.list is Agent-bound, so prewarming it would activate a child merely to view persisted history. Entries are soft-invalidated by the forwarded commands/change owner event (old snapshots serve while the repull flies) and by forwarded agent-preset/selected for that one session (recomposing an agent registers nothing, so the registry-wide signal never fires for it), hard-invalidated by connection/reset, and epoch-guarded so a superseded pull can never overwrite a newer one. matchSpace answers synchronously from this cache only; matchEnter strong-waits it on the SubmitAttempt signal and rejects on warmup failure — a / line is never silently downgraded to a plain prompt.
matchEnter also enforces the submission envelope: when the composer submits with image attachments, only a host command declaring input.images proceeds (its claim carries images: true and its submit forwards the serialized payloads to command.execute); every other command route — contribution popup, decorated popup, non-declaring claim, bare detached execute — throws the localized notice.imagesUnsupported refusal, which the input machine publishes as one error notice and the composer renders as a transient Toast banner with the draft and images retained. An image-carrying submit whose host handler answers an error result maps to an error outcome so the composer keeps the images; imageless submits keep the plain success mapping because the durable flow node owns the outcome rendering.
After command.execute returns a matched command result, this browser emits local command/executed(sessionId, name, result). Other clients receive the durable command nodes through the Host event stream but never this acknowledgment, so a browser-only side effect can select successful results from the client that submitted the command without treating Session replay as an action request. Listener failures are logged and contained one by one; they cannot change the already-admitted command result or prevent later listeners from running.
Menu queries fuzzy-match ordered, case-insensitive subsequences of command names. Prefixes rank first; separator boundaries, adjacent characters, and shorter gaps rank the remaining matches, with directory and contribution order breaking ties. This affects discovery only: space and Enter still require an exact command name. Rationale: Web slash-command fuzzy discovery.
PopupSelectController (src/client/popup.ts) is the headless shell state: PopupSelectView self-registers into conversation.input.overlay (the SlotMap key is ui-conversation's; this package pulls the declaration in with a type-only import — no runtime edge). The shell is a transient layer holding focus while open; token-segment consumption after onSelect runs both branches through consumeTokenSegment (menu-path span CAS, enter-path bare-token equality) against the draft face the wiring layer binds via bindDraft.
The /client entrypoint exports the plugin body (apply/inject), CommandUiRuntime, the directory and popup classes with their state types, and the fixed contract types; the shell component itself is internal to the overlay registration.
Model Experience
Indirectly, through the host command.execute RPC this package's dispatch and claim.submit paths trigger: a matched command's handler mutates host domain state that other packages project into the next request (the /plan handler flips plan mode, whose owning package injects its plan:policy system-prompt section), while the command line itself, the detached result, and every menu/notice rendering stay client-side and never enter the session log.
KV Cache effect
None directly; this package neither assembles nor sends a provider request. Command handlers it triggers may change what the owning host packages contribute to the next request's system prompt (a section appearing or disappearing replaces earlier request tokens and invalidates the provider prefix from that point), but that effect is owned and documented by each command's host package.
Known Limitations and Deferred Work
- Detached-result notices fall back to the console off-session — the fire-and-forget paths route results to the triggering session's composer via
SessionInput.notify; after session teardown the console line is the only remaining surface.
收录徽章
[](https://deepseek-plugin.org/plugins/deepseek-ai/deepseek-harness/packages/client/ui-commands)把这段 markdown 粘贴到你的 GitHub README,链接回本插件详情页。徽章只声明已被本站收录,不代表安全认证。