dsh-session-manager
中文 | English
An installable session-management plugin for DeepSeek Harness. It lists every materialized local session, including running, idle, and archived sessions, and provides Resume, Outline, and permanent Delete actions.
Important
No deepseek-harness source changes are required.
Starting with 0.2.0, this package contains all of the following:
- the browser Session-management panel;
- the Host-side
session.deleteRPC; - live Agent stop and Session-detach compatibility logic;
- JSONL and SQLite durable deletion;
- loopback, Host, Origin, and Fetch Metadata trust checks.
Users install this plugin and restart dsh web. They do not copy code into harness or edit SessionsApi, AgentLoop, SessionPersistence, or any harness file.
Features
- Complete session list: live and cold sessions, archived or not, with title, status, working directory, and update time.
- Resume: opens an existing conversation through the browser sessions service.
- Outline: folds the recent
session.historywindow in the browser into turn, message, and tool-call counts. - Permanent delete: stops the target Agent, refreshes the live and durable session tree, preflights the family, and then removes durable data. Deleting a session also cascades to every managed
origin: subagentdescendant (deepest first); ordinary forks remain, but traversal continues through them to managed descendants. - Multi-select bulk delete: check the boxes on the list to pick several sessions and remove them all from the toolbar in one go. Only independent deletion targets are selectable (ordinary sessions and orphaned managed children; a managed child with a live parent is removed with that parent and never appears on its own). Each deleted id runs the full per-session delete flow independently, so one failure does not roll back the already-removed sessions and the leftover ids are listed for a retry.
- JSONL: removes the complete session-owned directory, including the log and colocated snapshots.
- SQLite: deletes through the active backend connection in a transaction; event rows are removed by the schema's foreign-key cascade.
- Forward compatibility: native
AgentLoop.stopandSessionPersistence.deletemethods are preferred when a future harness supplies them.
Ordinary forks are deletable on their own. Managed origin: subagent children die with an existing parent: the UI offers no per-child Delete, the confirm dialog states how many managed children a cascade will remove, and direct requests for a child still return agent-busy. If the parent has disappeared, the row is marked orphaned and gets its own Delete button. The whole family is preflighted before destructive work, so known failures do not delete siblings first.
Compatibility
- Target: DeepSeek Harness
0.1.0-rc.8. - Supported first-party persistence backends:
session-persistence-jsonlandsession-persistence-sqlite. - A custom persistence backend must expose
delete(id)itself; a cascade over multiple durable sessions additionally requires atomicdeleteMany(ids). The plugin rejects unsupported cascades rather than deleting one member at a time. - The delete endpoint accepts loopback authorities only:
localhost,127.0.0.0/8, and[::1]. A page opened through a LAN address retains Resume and Outline but does not offer Delete.
The Host implementation fills three interfaces missing from rc.8 and uses rc.8 lifecycle/coordinator internals. Re-run this repository's tests before upgrading harness. As native upstream methods become available, the plugin selects them first and avoids the relevant compatibility path.
Install
Build the distribution tarball in this repository:
pnpm install
pnpm packInstall the emitted dsh-session-manager-0.2.2.tgz into the web profile:
dsh plugin --profile web add -w ./dsh-session-manager-0.2.2.tgzRestart dsh web after installation.
The -w flag is required because each profile contains a pnpm-workspace.yaml; a bare add fails with ERR_PNPM_ADDING_TO_ROOT. Distribute the built tarball. A git URL installs sources and requires a successful build on the target machine, which can otherwise leave lib/ missing.
The package's dsh.bundle.patch inserts one dsh-session-manager Loader row. That row activates both the Host plugin and its dsh.client browser half, with peers resolved from the dsh application closure. Installers do not edit the profile's cordis.patch.yml manually.
Usage
Open Settings -> Sessions:
- Resume enters an existing conversation;
- Outline displays recent activity statistics;
- Delete opens a confirmation dialog and permanently removes the session.
Deletion is irreversible. Deleting an open live conversation removes it from the Host registries, allowing existing surfaces to react through the normal host/session-removed lifecycle.
How It Works
1. The browser reads session.list and workspace.list for the complete corpus and archive state. 2. Delete uses Connection's generic RPC caller to POST /api/session.delete. 3. The plugin Host half applies the same loopback and same-origin checks used by harness. 4. For a parent deletion it stops the parent first, then reads the live and durable subtree and stops managed lifecycles before deletion, preventing children from being admitted during the window. 5. It preflights the whole plan; JSONL uses recoverable staging, SQLite uses one transaction, and native backends may provide an atomic batch delete. 6. The client reloads the corpus so the view reflects final Host state.
Development
pnpm typecheck
pnpm test
pnpm build
pnpm packTests cover controller races, orphan classification, loopback/Origin rejection, live lifecycle teardown, recoverable JSONL deletion, SQLite transactions, subagent refusal, traversal through ordinary forks, live children, preflight failures, and same-id request coalescing.
Known Limitations
- Outline describes the recent
session.historywindow, not the complete log. - Deleting an archived session does not remove its stale id from
archivedSessionIds; that inert registry entry cannot restore session data. - An orphaned
origin: subagentrow can be deleted directly; any managed descendants below it are removed in the same cascade. - The corpus has no cross-tab push refresh; the panel reloads after deletion and reconnection.
- Delete is unavailable from non-loopback pages.
License
MIT