Skip to main content
4

dsh-session-recycle-tools

4wgtty4zm7-a11y/dsh-session-recycle-tools

Adds two entries to the DSH web sidebar above the settings row: a batch picker that groups sessions by workspace, filters them by a search box and moves the selected ones into a recycle bin, and a recycle bin that restores sessions one by one or all at once, or permanently deletes them. The recycle bin keeps its own list in browser storage and hides its sessions by wrapping the host session-visibility check, so it does not use the host archive; a moved session keeps its log on disk until it is permanently deleted. Sessions that are currently running are refused and reported instead of being moved.

Install

dsh plugin --profile web add github:4wgtty4zm7-a11y/dsh-session-recycle-tools

README

dsh-session-recycle-tools

Adds two entries to the DeepSeek Harness web sidebar, stacked above the settings row at the bottom left:

  ☑  Batch delete            <- this plugin
  🗑  Recycle bin            <- this plugin
  ⚙  Settings                <- the host's own row

The recycle bin is its own list, not the host archive

The sidebar's built-in archive writes workspaces.archivedSessionIds and shares one "archived" view. This plugin does not touch it: the two coexist and neither knows about the other.

Host archiveThis recycle bin
Recorded inarchivedSessionIds in the workspace recordthe plugin's own list in localStorage (dsh-session-tools.trash.v1)
Hidingthe host filters the rowthe plugin wraps uiWorkspace.isSessionVisible; only ids in its own list return false
Restoreunarchive through the hostdelete the id from the list; the session is back immediately
Relationshipunaware of the recycle bincalls the host's original filter unchanged, then intersects it with its own set

How client.js does it:

  1. apply() resolves ctx.get('uiWorkspace') and replaces isSessionVisible with (id) => trash.has(id) ? false : original(id), restoring the original in the ctx.effect cleanup. Whatever the host already filtered (a workbench session filter, for example) still runs through original(id) with the same meaning.
  2. After the list changes, uiWorkspace.sessionVisibility is bumped so the sidebar tree recomputes its rows.
  3. Moving a session sends no archive request. Permanently delete is the only path that calls the host's uiWorkspace.deleteSession(), the same path as "permanently delete session" in the session context menu.
  4. A session that is currently running is refused: it would otherwise vanish from the list while still working in the background. The dialog says so instead.
  5. An id that disappears from the session list entirely is pruned from the bin after a 60-second grace period.

Known cost: the list lives in the browser's localStorage for the current origin (http://127.0.0.1:<port>). Clearing site data or switching ports empties the recycle bin; the only consequence is that those sessions reappear in the list, and no content is lost.

Layout

The host half is a single loader row whose only job is to let dsh-client-modules see this package's dsh.client declaration and serve client.js to the page. The plugin registers no host service, route, or tool, so the model cannot see it.

.
|- package.json           # dsh.bundle.patch + dsh.client { platform: 'web' }
|- cordis.patch.yml       # one insert line: - id: dsh-session-recycle-tools
|- lib/index.js           # host half: an empty apply()
|- client.js              # the two buttons and the two dialogs
|- screenshots.json       # 1-8 storefront screenshots
|- assets/icon-180.png    # 180x180 storefront tile

Host capabilities client.js relies on:

PurposeSource
Session summariesctx.get('sessions').list (ids / byId, including running)
Workspace groupingctx.get('workspaces').list (items[].sessionIds)
Hide and restorewrap uiWorkspace.isSessionVisible and bump uiWorkspace.sessionVisibility
Permanent deleteuiWorkspace.deleteSession()
The recycle-bin listthe plugin's own localStorage key
Registrationsidebar.footer.action (a list slot, one row above sidebar.settings); dialogs use shell.overlay
Icons, buttons, checkboxes, dialog@deepseek-ai/dsh-client-ui-primitives

The two dialogs

EntryDialogWhat it does
Batch deleteevery session, grouped by workspace, with a search boxcheck sessions (whole group or all), then move them into the recycle bin, which is the only action here
Recycle binsessions in the list, grouped by workspace, newest firstrestore one or all; permanently delete one or empty the bin

Both dialogs are 1240px wide and follow the application body text: 20px title, 16px description, 16px session title, 14px timestamps and paths, 15px buttons.

Install

dsh plugin --profile web add github:4wgtty4zm7-a11y/dsh-session-recycle-tools

Then restart the running DSH web service. No host tool, route, or configuration is added.

Compatibility

Requires a DSH build that serves client plugins through dsh-client-modules and exposes uiWorkspace with isSessionVisible, sessionVisibility, and deleteSession. If isSessionVisible is missing, the plugin still records the list and says so in the dialog rather than hiding anything silently.

Related plugins