Files
deepseek-harness/packages/client/ui-entry-customization
5ff29190ed feat(ui): add navigation entry customization (#6247)
* fix(ui): avoid tooltip trigger overlap when a side fits

* feat(ui): add navigation entry customization

* fix(test): keep tooltip geometry independent of JSX types

* fix(ui): align customization catalogs and integration fixtures

* test(ui): complete customization lifecycle and release integration coverage

* fix(ui): return entry discovery to the installed plugin list

* docs: refresh module graph for entry customization

* build: refresh workspace links for the moved entry customization package

* docs: regenerate catalogs and pairing hashes for the moved entry customization package

* test(web): cover default-loaded entry customization in the Web e2e

* test(ui): describe entry customization as a browser plugin in the host entry spec

* build: order entry customization publication files as workspace constraints require

* test(release): drop the moved entry customization package from the experimental family list

* style(ui): use the shared focus ring color on entry customization triggers

* test(web): re-record goldens for the default-loaded More navigation menus

* test(web): add the More conversation views trigger to the remaining CI-reported goldens

* docs: record region-owned pins for plugin entry customization

* refactor(ui): rebuild entry customization on region-owned pins and More menus

- Each navigation region (left sidebar, Conversation header, right sidebar
  guide) persists its own unpinned list under
  dsh.slot.manual-order.<list slot key>.v1, filters its own launchers, and
  draws its own More button and Menu around its actions slot.
- ui-entry-customization only registers the shared menu rows (entries with
  pin buttons, Browse other plugins, Create your plugin) into the three
  actions slots and keeps no state.
- Remove ctx.layout.entryVisibility, the plugin store, left-sidebar drag
  reordering, and agentPresetNavigation; ui-layout and ui-agent-preset match
  release/dsh-0.2.1 again.
- Keep the release <nav> and Conversation tab-bar visibility conditions.
- Move the More glyph into ui-primitives as IconAppsAddOutline{Regular,Medium}.

* docs: compile the entry customization owner props example

* docs(ui): describe the wrapping Conversation tab row in the header comment

* fix(ui): return New Session to the Workspace blank and its unsent draft

- New Session (startSession without options) takes the blank-reuse path
  again instead of creating a fresh Session on every call, which hid the
  previous blank and its unsent draft since a5c9c2aaeef (#5775).
- A request that names an Agent preset skips blanks listing a different
  preset, so Creator entries no longer take over an ordinary draft.
- Record the change in a v0.2.1-rc.2 upgrade guide; the Host refresh of a
  stale loaded blank stays deferred (see the Agent Note).

* docs: regenerate the Cordis inspect catalog for New Session blank reuse

* fix(ui): keep the selected entry visible while unpinned

- Left-sidebar rows and View tabs keep the selected entry, with aria-current or aria-selected, until another entry is selected.
- Entry menu Creator action takes no region argument; the registration's region selects the prompt.
- Document the 2px panel-row and 32px View-tab gaps; drop commit hashes from the New Session Agent Note.

* fix(ui): leave a blank of another preset unstaged when starting Creator

startCreatorDraft stages cordis only when the main blank lists no preset or already lists cordis; navigation opens a separate Creator blank otherwise, so a Standard draft blank keeps its preset.

* feat(ui): choose whether a draft prompt replaces, appends to, or keeps an existing draft

- DraftInitializationOptions gains whenDraftExists ('replace' | 'append' | 'keep', default 'keep'); clearPreviousDraft stays and maps to 'replace' only when whenDraftExists is omitted.
- Append adds the prompt as new paragraphs after the existing text and references; attachments stay in every mode.
- The three Create your plugin entries append their regional prompt.

* test(web): align e2e with New Session blank reuse and the visible selected entry

* refactor(ui): share the draft paragraph writer between setDraft and appendDraft

---------

Co-authored-by: Yif <[email protected]>
Co-authored-by: imccyu <[email protected]>
2026-10-20 15:17:13 +08:00
..

description, kind
description kind
Fill the More menus of three navigation regions with pin controls, plugin browsing, and a Creator draft. package-reference

@deepseek-ai/dsh-client-ui-entry-customization

English | 中文

Summary

Fill the More menus of the left sidebar, Conversation View tabs, and right-sidebar guide with each region's customizable entries, pin buttons, plugin browsing, and a reviewable Creator draft. The Web app loads it by default. Each region draws its own More button and stores its own pin choices; this package stores nothing.

Table of Contents


Use this package

The @deepseek-ai/dsh-web-app bundle loads this package by default; it needs no Plugins switch or profile selection. A region shows its More button only while its actions slot has a registration, so unloading this package removes all three buttons.

Open More beneath the left navigation entries, More conversation views after the Conversation View tabs, or More tools after the right-sidebar guide cards. Each menu lists the region's customizable entries in registration order; Plugins, Chat, and Workspace files always show and are not listed. Selecting an entry's name closes the menu and opens the entry without changing its pin state. The separate pin button pins or unpins the region's launcher and keeps the menu open; a filled pin marks a pinned entry. Unpinned entries stay reachable through the menu, and pin choices persist across reloads. Long entry names wrap, except in the More tools menu, where they truncate to one line.

Browse other plugins opens the Plugins main list without opening an installation dialog. Create your plugin opens a new or reusable blank Session with the Creator preset and adds a short localized request for a plugin in that region to its draft: an empty draft takes the request as its text, and an existing draft keeps its text, references, and attachments with the request appended as a new paragraph. It never sends a message. Review and send the draft yourself. Both actions remain available when a region has no customizable entries; an empty list adds no separator.


Understand the implementation

Implementation internals — click to expand

apply registers EntryMenuContent under id entry-customization into sidebar.panellist.actions, conversation.session.header.views.actions, and sidebar.right.tab.guide.actions through ctx.slots.inject, so each registration follows its region's declaration lifetime. The regions render these slots inside their own Menu and supply the entries, their pin state, onOpen, onPinnedChange, and onDismiss as owner props. The rows call onDismiss before opening an entry or running a footer action; pin changes leave the menu open.

Each registration's inject supplies its region and two callbacks. Browsing calls pluginNavigation.openList(). Creation calls uiWorkspace.startSession(undefined, { agentPreset: 'cordis', prompt, whenDraftExists: 'append' }) with the region's localized prompt; it does not go through ui-agent-preset, so the preset chip plays no introduction. The dsh-web-app bundle patch mounts the browser plugin.


Model Experience

None, as the package manages browser launchers and prepares an unsent, reviewable draft; only user submission sends its text to the model.

KV Cache effect

None; the package neither assembles nor sends model requests.

Known Limitations and Deferred Work

  • If this package is disabled or fails to load after entries were unpinned, those launchers stay hidden and no More menu can restore them. Re-enable the package or clear the region's dsh.slot.manual-order.*.v1 localStorage key.
  • Pin choices live in browser localStorage, which is isolated by protocol, host, and port: changing the Web port or switching between Web and Desktop does not carry them over, and they do not sync across devices.
  • Create your plugin does not check whether the Creator preset exists. Without it, Session creation fails, the Workspace shows its creation-failure notice, and no draft is prepared. Draft preparation also requires a resolvable Workspace; without one, the existing flow reports that a Workspace is required.
  • Entries keep registration order; the menus offer no reordering, and entries cannot move between regions.
  • Conversation controls follow the existing nonblank-Session header and Coding Tools eligibility. Right-sidebar controls require a selected Session and appear on its guide page.
  • Only active registered launchers appear; the menus are not an inventory of disabled or uninstalled plugins.

Dev Note

Working context for maintainers — click to expand

None.