The composer model seat shows a catalog model's badge after its name in
the trigger, the root-menu value, and each option: a Tag in the badge's
tone whose text is resolved for the active locale through
ctx.locale.resolveText. A conversation.input.model.label contribution
replaces the name and badge together and receives the badge in its
owner props.
Remove ui-deepseek-model-label-1017, which hard-coded `1017` beside
DeepSeek-V4.1-Flash for two providers, and its Web bundle row. The badge
now comes only from the model listing, so the build ships none of its
own; the upgrade guide covers profile patches that still target the
removed row. The Web e2e replaces the fixed-badge case with replay
catalogs that declare literal and translated badges, and the replay
adapter validates and advertises a configured badge.
Bring master 45d1196d3fe into the release/dsh-0.2.1 squash commit of #6247
so the release commit stays an ancestor of master.
Conflict resolutions:
- apps/web/tsconfig.json, tsconfig.host.json: keep the entry-customization
e2e and master's Computer Use e2e entries.
- docs/subsystems/slots.{md,zh.md}: keep both added paragraphs; re-record the
slots, ui-primitives, and ui-workspace README translation pairs.
- ui-sidebar SidebarRoot.tsx and locales.ts: keep the More menu imports and
copy next to master's version-copy toast.
- apps/web/tests/agent-preset-selection.e2e.ts: keep the New Session
blank-reuse assertions, read presets through master's
sessionProjections.checkpoint() instead of the deprecated stateOf().
Follow-ups on master's side:
- ui-sidebar sidebar-root spec: give master's version-copy render the entry
pin props that SidebarRootInjected now requires.
- snapshots/web/steering/trajectory.expected.md: add the More conversation
views trigger to master's new Trajectory golden.
* 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]>
Read configured plugin market indexes on the Host, search them with fuzzy
multilingual matching, and install a chosen version from the Plugins page.
- dsh-plugin-market-index validates format-1 indexes and builds install
arguments; inline icons are capped at 32 KiB.
- The pluginMarket service fetches configured http(s) URLs, parses bodies in
a Worker Thread, caches documents, and pages filtered, ordered results with
installation status and engines.dsh compatibility.
- Discover is an opt-in experimental bundle; the Plugins page gains a
plugins.tab slot and confirmed installs.
- The plugin_market tool lists indexes, plugins, and versions for Creator mode.
- Plugin compatibility reads engines.dsh before DSH peer dependencies.
- WebServer exposes getOrigin() instead of an origin getter, and it fails
loud before listen binds a port.
- The earlier Web-surface paragraph is a frozen literal, so later guidance
edits cannot stop earlier Sessions from matching; the projection reads a
prompt version with the loop's single-text-block rule.
- web-app drops its unused dsh-system-prompt dependency and stale
prompt-section wording in its description, README, patch comment,
--public-url help, and the round-trip test title.
The harness checkout path and Web GUI URL now reach the model as runtime
context from the new dsh-harness-dev-context plugin, so a process started
on another port, checkout, or installation no longer rewrites a Session's
logged system prompt. A Session whose prompt already embeds the earlier
value-bearing paragraphs keeps them verbatim through a host-only session
projection.
dsh-host-webserver gains WebServer.origin and bindUrlHost(); web-app keeps
only DSH_WEB_URL, the startup URL, and the browser handoff, and its root
declares the webStartup service type. app-boot drops
addHarnessSourceSection and HARNESS_SOURCE_SECTION.
The reminder stack no longer hides behind an optional experimental bundle.
`packages/bundle/web-app/cordis.patch.yml` inserts `schedule` and
`ui-schedule`, so a shipped profile mounts the task store, the delivery
runtime, and the Automation tasks page; the
`@deepseek-ai/dsh-experimental-schedule-bundle` package and its wiring are
removed.
Preset ownership is unchanged: `standard`, `cordis`, and `ptc` declare the
clock and the four reminder tools in their own scope, and `minimal` declares
neither, so a minimal session carries no reading and no reminder tool even
though the service is mounted.
`apps/cli` depends on `@deepseek-ai/dsh-tool-schedule`, and
`packages/bundle/web-app` declares `@deepseek-ai/dsh-schedule` and
`@deepseek-ai/dsh-client-ui-schedule`: preset and profile rows resolve plugin
names from the installation anchor, so a missing declaration leaves the row
without a fiber and every session creation fails with
`agent-preset/invalid`.
Documentation, Agent Notes, and the recorded Web fixtures follow the shipped
composition.
master now ships the reminder stack as the optional
`@deepseek-ai/dsh-experimental-schedule-bundle`, which inserts the rows the
Web composition leaves out. This branch keeps the preset-level ownership
beside it.
Resolutions:
- The bundle inserts `schedule` and `ui-schedule` only. It no longer inserts
`time-context`: the clock belongs to the `standard`, `cordis`, and `ptc`
presets, and a Host row for the same package would mount it in two scopes
and append two readings per step.
- `packages/bundle/web-app/package.json` declares `@deepseek-ai/dsh-time-context`
again: the presets reference it by bare name, so `verify-cordis-config`
requires the dependency.
- The bundle's patch spec, locale, package, README pair, the optional-bundle
composition spec, the plugin-manager component list, and the
`schedule-after` roster assertions describe the two-row bundle and the
preset-owned clock and tools.
- Documentation and Agent Notes follow the same split; the note master
archived stays frozen with its manifest hashes.