Moving the agent plane behind presets left two readers on the wrong side of the host/agent line. `dsh-token-meter` was disabled on the host and mounted inside each preset's `compaction` realm, but its three projection units register into the process-wide `sessionProjections` table. A unit registered from one preset answers for every session, so whether a `minimal` session showed a context meter depended on whether some other session had mounted `standard` since boot, and a process that only ever ran `minimal` showed none. The meter takes no configuration, keys every fold by Session, and registers no tool or prompt section, so it returns to the host composition and leaves the presets' `isolate` map; the realm and `compact-basic` stay, because what a preset chooses is whether its agent compacts, not whether its tokens are counted. Nothing named an agent that joined no preset. The join is a scope-parent link, and without it the tools, prompt-section, and skill views resolve the empty global layer: the agent publishes, the turn runs, and the model receives nothing. `AgentPresets` now logs one warning per such agent while a roster is configured, and the invariant companion fails outright — at `system-prompt/assemble` rather than at publication, because an unjoined agent is legal until it addresses a model and `recompose` binds exactly such an agent. The warning stays advisory: a synchronous `agent/created` throw vetoes publication, and the ACP bridge, SDK server, and headless bundle all create an unjoined agent today. Three limits are recorded rather than fixed: projection key presence is not a per-session capability signal, a superseded standing generation is never reclaimed, and a `cordis_mount` temporary plugin belongs to the composition rather than the session that mounted it. Fixes #2203
@deepseek-ai/dsh-web-app
English | 中文
The dsh browser-surface bundle. cordis.patch.yml rides over dsh-base: it sets the coding persona, inserts the Web host rows (webserver, API gateway, workspace, projection cache, storage) and the browser plugin roster, and mounts this package's web-runtime glue plugin (config {mode, printUrl, surfaceContext, lanAddresses}). That plugin resolves the built frontend dist through @deepseek-ai/dsh-frontend's exports, mounts the frontend-static fallback owner over it, registers the web-surface prompt section and the bash-visible DSH_WEB_URL/DSH_WEB_MODE runtime variables when surfaceContext is true, and prints the dsh web: URL line when printUrl is true. The dsh web launcher alias patches mode/lanAddresses and the flag family over these rows. dsh-headless is a sibling surface over the same base and does not mount this bundle.
Model Experience
Web-surface prompt section and bash runtime variables
What the model sees
When surfaceContext is true, the app:web-surface global section (order −98) orients the model to the GUI: the canonical local URL, the "this page" referent, the HMR/rebuild update contract for the active mode, and the instruction not to start replacement servers. DSH_WEB_URL and DSH_WEB_MODE additionally appear in the managed bash environment with their descriptions, resolved per invocation from the live server. When it is false, neither the section nor the variables are registered.
Token effect
One prompt paragraph per session plus two managed-environment variable lines; constant per process.
KV Cache effect
The prompt section sits near the system prompt's head and is stable for the life of the process (port and mode are boot facts), so it does not invalidate the cache across turns.
Known Limitations and Deferred Work
- The frontend dist must be built —
require.resolveof the dist fails loud at activation with a build hint; there is no source-serving fallback. lanAddressesis a boot-time snapshot — interface changes after boot are not re-advertised; the printed LAN URL always matches the configured trust fence.