dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
Delete sessions from the DeepSeek Harness Web sidebar straight into a Trash settings page, then restore them or delete them permanently.
Delete sessions from the sidebar into a Trash page in Settings, then restore them or delete them permanently.
A global DeepSeek Harness
plugin published as one npm package carrying both halves: a Host plugin mounted
by the bundle patch, and a browser half served from the same package's ./client
export.
This package is a DeepSeek Harness bundle: dsh.bundle.patch is its Host
row, dsh.client is its browser half, and the package resolves both. Install it
into a profile with the harness's own Plugin Manager — point it at this
directory (or at the repository URL) and it records the bundle in the profile:
dsh CLI, if the harness exposes the Plugin Manager surface:
dsh plugin --profile <name> add <source>The profile's own cordis.patch.yml is applied after this bundle's layer, so
it is also where any config below is pinned.
… menu, for keyboard users and
anyone who never hovers a row.Moving a log aside makes the session absent from the Host catalog on the next listing — but nothing schedules one. The browser's session store was filled by a pull that already happened, so a deleted row would otherwise stay on screen (the sidebar renders it as an ungrouped "stray") until the page was reloaded.
After the log actually moves, the Host therefore emits the declared Remote Event
api-session/removed, which Cordis relays to every connected client. That is the
same path the shipped Session controller uses for its own disposal
notifications (dsh-api-session-controller/lib/index.js), so the browser clears
the row through its ordinary list-mutation code — no client-side list surgery,
and no plugin knowledge of another package's internals. The route's response
reports announced: false if the relay was unavailable, so a deployment without
the event simply falls back to clearing on the next load.
The Harness ships no session-deletion API: SessionPersistence creates, opens,
lists, and flushes handles but never removes one, and the browser session
controller exposes no delete verb. What the store does publish is its
addressing rule — a session is visible exactly when its directory holds a
canonical generation log (session.jsonl, session.v<N>.jsonl, either with the
configured compression suffix).
So deleting a session appends .trashed to that one basename inside the
session's own directory. Nothing is copied and the log's bytes are untouched:
stat/list/open all report the session as absent, so the sidebar catalog,
search, title folding, and lineage traces treat it as gone without knowing this
plugin exists. Restoring removes the suffix again, which brings the title back
with the log, and permanently deleting removes the directory and the session's
projection-cache record.
The trash index is this plugin's own plain JSON document. A missing, empty, or hand-edited index is reconciled against the session root on every read, so a trashed session is never stranded by index damage.
The row takes an optional config, set from the profile's own
cordis.patch.yml (the layer applied after this bundle's):
- id: session-trash
name: 'dsh-session-trash'
config:
# Defaults to $DSH_HOME/sessions, the session-persistence root.
sessionsRoot: /absolute/path/to/sessions
# Defaults to $DSH_HOME/storages/dsh-session-trash/index.json.
indexFile: /absolute/path/to/index.json
# Defaults to $DSH_HOME/storages/session_projcache/sessions.
projectionCacheDir: /absolute/path/to/session_projcache/sessions
Two dependency-free suites ship with the package and run against a scratch session root in the system temporary directory:
node verify.mjs # the store: trash, list, restore, purge, empty, recovery
node verify-route.mjs # the route: dispatch, validation, refusals, envelopes
verify.mjs asserts the property this design rests on — a trashed session is
invisible to a canonical-generation scan while its bytes are byte-for-byte
unchanged, and restoring brings back the identical file.
The Host half imports no Harness package; its one contribution is a
connection.fetch exact route on the authenticated /api channel, and the
store knowledge it relies on is the filename grammar above — a storage-format
constant rather than a module API, with v<N> left open-ended so a future
format generation is matched by the same scan. The browser half imports no
Harness Client package either: it uses the module-loader factory contract,
ctx.slots.inject/register, the slot's standard useSessions hook,
ctx.locale, and --dsw-alias-* theme tokens only.