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.
conversation.hero.options seats compact Session options at the right end of
the New Session row, after the workspace and agent-preset controls. It is a
session-scoped list slot rendered only while a Session exists, so plugins can
add choices such as a worktree toggle without displacing the shipped controls.
With HMR, installing, enabling, disabling and removing bundles take effect live. Each profile recomposition compares
the loaded modules below the profile directory and its linked targets with disk, stops the plugins whose files
changed, and recomposes the profile through app-boot's recomposeProfile(): the rows the next generation drops are
removed first, the latest runtime resolution is published once, and the generation is applied and judged. Afterwards
HMR evicts the modules below the mappings the recomposition dropped.
- app-boot: recomposeProfile(); PluginPackages.resolution; ResolutionRestartRequired; the resolver accepts in-place
version changes and relinks, and relocates Node's cached link real paths.
- plugin-manager: with HMR, installBundle refuses an installed package (already-installed), so an upgrade is a
removal and an installation; every restart-required result carries a restartReason; removal uses the registry the
package was installed from.
- ui-plugin-manager: the Official Update removes and then installs; restart prompts name their reason.
Add a placement table to the Definition section: which `groupTree`
position a Chat Node declares for an opening human input, another Turn
input, a Turn notice outside folding, an independent folded row, and
ordinary process content, with links to the contract and the built-in
positions, and a pointer to `exclusive` claims.
State in the `exclusive` JSDoc and the Conversation reference that the
claimed target's fallback does not run and that a fallback's own claim
has no effect. Reword the `input` position as the Turn's opening input
and separate the finalized-answer exemption from position-less
`assistant-step` rows. Point both package READMEs at the claim and the
group-tree positions.
Add the exclusive Conversation matches Agent Note; bring the group-tree
note up to the `input` position and the migrated kind lists, and the
timed-question note up to claim-based reply deduplication. Pair the
Chinese Conversation reference and Chat grouping README with the
English updates.
A match result may set `exclusive: true`. The assembler evaluates every
match of an event before accepting any, so a claim is independent of
registration order: other Definitions of the claimed target build no
Context for the event and the target's fallback does not run, while
Definitions of other targets and target-less Definitions still receive
it. Two claims on one target, or a claim without a target, throw.
The account route no longer accepts a models catalog, so paid Flash
translation compares Account modelOverrides (Official keeps models) when
it checks that the owner's model configuration is unchanged before
dispatch. The paid fixture and the Web e2e serve the account GET /models
listing instead of configuring models on the account entry.
The web-runtime row provides webApp.getAdvertisedUrl(): the row's
configured publicUrl, otherwise the listener origin. harness-dev-context
reads it instead of webStartup.publicUrl, so a profile override of
publicUrl reaches the model as it already reaches DSH_WEB_URL and the
startup URL. The new package no longer injects webServer or webStartup,
and the startup flag provider returns to its master behavior.
- 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.