* 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]>
6.7 KiB
6.7 KiB
- banner:
- navigation "Session hierarchy": Load the editing-cordis-compositions ski
- button "More actions"
- button "Open right sidebar"
- tablist:
- tab "Chat" [selected]
- tab "Trajectory"
- button "More conversation views"
- text: Load the editing-cordis-compositions skill with the skill tool, then reply DONE. {{date}} {{clock}}
- button "Copy"
- status: Completed
- button "Completed in {{duration}}" [expanded]
- button "Called tools" [expanded]
- button "Think Load the requested skill."
- button "Skill editing-cordis-compositions" [expanded]
- region "Instructions": "Instructions <skill_content name="editing-cordis-compositions"> <skill_resources> Base directory for this skill: {{cwd}}/.dsh/skills/editing-cordis-compositions Resolve relative paths mentioned by this skill against the base directory before using them. Load referenced resources only as needed. </skill_resources> <skill_instructions> # Editing Cordis compositions Agent presets are ordinary
@deepseek-ai/dsh-agent-presetdeclarations carried by bundle patches. Nothing edits a declaration in place: a preset is created or changed by installing a bundle whose patch declares or overrides it. This file states the declaration format; when it leaves a question open, read the@deepseek-ai/dsh-agent-presetREADME andlib/typesdeclarations under thepackageDirthatcordis_inspect_queryConfig.listConfigsreturns when queried with apreset-<id>row'sentryid, orpackages/preset/agent-preset/srcin a source checkout. ## Where declarations live The shipped Web presets arepresets/<id>.patch.ymlfiles of the@deepseek-ai/dsh-web-appbundle, idsstandard,ptc,minimalandcordis. Installed, the bundle resolves from the dsh installation, not the profile; queryingConfig.listConfigswith theentryid of anypreset-<id>row it declares returns thatpackageDir. In a source checkout of DSH it ispackages/bundle/web-app/. Read one file with the file-read tool when you need a template;minimal.patch.ymlis the shortest. In Desktop the bundle sits insideapp.asar, which shell commands cannot open. Loadcordis-composition-referencefor the patch dialect and the list of plugin packages a preset can mount. A declaration row has theseconfigfields:id(required, lowercase letters, digits and hyphens),plugins(required Cordis entry list), and optionalname,descriptionandorder(roster position). The Loader rowidispreset-<id>by convention. ## Create a preset Write a bundle directory in the workspace with exactly two files, then install it.review-preset/package.json:json { \"name\": \"@local/dsh-review-preset\", \"version\": \"1.0.0\", \"private\": true, \"type\": \"module\", \"dsh\": { \"bundle\": { \"patch\": \"./cordis.patch.yml\" } } }review-preset/cordis.patch.yml:yaml - insert: - id: preset-review name: '@deepseek-ai/dsh-agent-preset' config: id: review name: Review description: Reviews changes with the shell only. order: 10 plugins: - id: persona name: '@deepseek-ai/dsh-persona' config: prefix: You review software changes. - id: tool-bash name: '@deepseek-ai/dsh-tool-bash'Install withplugin_manager,action: install_bundle,targetset to the absolute bundle directory. It runs package installation and bundle selection itself; do not reproduce those steps with shell commands. ## Change a shipped preset Override the declaration by its Loader row id instead of inserting. The override replaces the completeconfig, so restateid,pluginsand every other field the shipped file carries:yaml - id: preset-standard name: '@deepseek-ai/dsh-agent-preset' config: id: standard order: 1 plugins: # the shipped list with your changes## Migrate a legacy preset Before declaration rows, a user preset was a directory$DSH_HOME/.agent-presets/<id>/holdingpreset.yml(displayname,description,order) andagent.cordis.yml(the plugin entry list). Nothing reads that directory any more. To migrate one, create a bundle as above whose declaration takesidfrom the directory name,name,description, andorderfrompreset.yml, andpluginsfromagent.cordis.ymlverbatim; check each plugin name againstcordis-composition-referencebecause packages renamed since the preset was written fail at activation. Install it, verify the row, then delete the legacy directory. ## Verifyplugin_managerlist_bundleslists the installed bundle;list_pluginsshows thepreset-<id>row with its activation state. A declaration whose activation fails stays on the roster with its diagnostic and cannot compose a session until the bundle is fixed and reinstalled. Existing sessions and their children keep the plugin revision they started with; validate changed behavior in a new session. Installing a bundle executes plugin code in the Host process, so it requires Full access or approval. ## Choose plugin placement Host plugins supply shared services: tools and prompt registries, the Agent loop, sessions, persistence, settings, sandbox policy, model routes, and subagent backends. Preset plugins contribute scoped tools, persona, prompt sections, and policies to those registries. Preset revisions are eagerly activated once and shared by their selecting Agents. A preset plugin that supplies a service must isolate the provider and all its consumers in the same realm. A service consumed by Host plugins belongs in the Host configuration. Scope controls contributions and event visibility;isolatecontrols service instances. Use ordinary Cordis groups for nested plugin lists. Keep!!jsexpressions only in plugin configuration ordisabled; the Loader evaluates them when activating the child plugin. Resolve assets from installed packages rather than a preset directory. ## Extend the Host For new plugin code or profile-wide capabilities, loadcordis-plugin-development, author a workspace bundle, and install it withplugin_manager. Inspect available APIs throughcordis_inspect_listandcordis_inspect_query, including a mounted plugin's Config schema through the HostConfigprovider; those tools do not invoke Remote methods. Verify the installed capability before reporting completion. </skill_instructions> </skill_content>" - button "Inspect"
- button "Think The skill is loaded."
- paragraph: DONE
- button "Copy"
- button "Good response"
- button "Bad response"
- button "Branch into a new conversation"
- text: {{date}} {{clock}}
- textbox "Message or run a task, / commands, @ files or sessions"
- button "Add files or run commands"
- 'button "Access mode, current: Full access"': Full access
- button "Select model, current DeepSeek-V4-Flash": DeepSeek-V4-Flash
- button "Send message" [disabled]
- button "1 turns 2 steps"
- button "310 tok · Cache hit 0%": 310 tokCache hit 0%