deepseek-harness
deepseek-ai
DeepSeek Harness: Everything is a Plugin.
PROJECT TOPICS
PROJECT README
A plugin for DeepSeek Harness that adds archived-conversation management: a sidebar entry that lists your archived conversations — grouped by workspace — and lets you view (open), restore (unarchive), or reveal the transcript folder of any archived conversation.
Background. DSH has a built-in Archive session action (it hides a conversation from the sidebar by adding its id to the registry-global
archivedSessionIdsset), but it ships no way to view archived sessions and no unarchive API — the shippeddsh-client-ui-workspaceREADME lists "no viewing or unarchive surface" as a known gap. The underlying transcript (session.jsonl*) is never deleted by any DSH code (the persistence seam has no delete interface), so restore is exactly: remove one session id from the archive set. This plugin implements exactly that, as a normal cordis plugin — no core modifications.
session.jsonl* log) in your platform file manager
(Explorer / Finder / xdg-open), so you can inspect or back up the raw log.sidebar.footer.action slot may not provide, never crashes
the web shell, degrades to a read-only panel if the remote mount fails, and
avoids the inject/mount self-deadlock (the archiveManager namespace is
mounted by the bundle itself, so it is fetched with ctx.get(...) and is
deliberately not listed in inject).Deleting a conversation is not something DSH supports, by design, and this plugin intentionally stays within that boundary:
~/.dsh/sessions/.... The
dsh-session-persistence-jsonl README states: "logs accumulate under the
root until removed externally (the seam has no delete interface)". No DSH
code — including this plugin — ever unlinks a transcript file.archivedSessionIds; the log, the
workspace accounting slot, and the session's data all remain intact. That
is precisely what makes restore possible.~/.dsh/sessions/--<project>--/<session-id>/ yourself (the sqlite search
index then reconciles the entry away on the next scan). This plugin instead
gives you the Open conversation folder button to find that directory
quickly and safely.In short: view and restore are reversible and safe; physical deletion is deliberately out of scope — a destructive "delete" button would fight the storage design (append-only logs, rebuildable indexes) and could silently destroy data this plugin cannot restore.
| Layer | What happens |
|---|---|
Host plugin (src/index.js) |
Registers a root-scoped Typert Remote service ctx.archiveManager with two endpoints: archiveManager/unarchive (removes a session id from ctx.workspaceRegistry's archivedSessionIds through the registry's own serialized op queue — enqueueOperation/requireState/setState — and returns the updated set) and archiveManager/openSessionFolder (locates the session's transcript via ctx.sessionPersistence and reveals its directory in the platform file manager). |
Browser plugin (src/client.js) |
Mounts the matching strict remote descriptors via ctx.remote.$mount, then registers a sidebar.footer.action entry (button + panel). The panel reads workspaces.list (items + archivedSessionIds) and sessions.list (both reactive stores), groups archived ids by workspace accounting, calls archiveManager/unarchive for restore, sessions.open(id) to open, and archiveManager/openSessionFolder for the folder button. |
No DSH source is patched. The plugin is discovered by the standard loader
(the profile's cordis.patch.yml) and its browser half by the client module
loader (dsh.client.platform = "web").
0.1.0-rc.x (tested on 0.1.0-rc.6, web profile)Open PowerShell and cd into the repo folder first, then run the script:
cd <path-to-repo> # e.g. cd D:\dsh-archive-manager
powershell -ExecutionPolicy Bypass -File .\scripts\install.ps1
Or from anywhere, with the repo at <repo>:
powershell -ExecutionPolicy Bypass -File <repo>\scripts\install.ps1
# non-default profile:
powershell -ExecutionPolicy Bypass -File <repo>\scripts\install.ps1 -ProfileName headless
The script copies the plugin into
%USERPROFILE%\.dsh\profiles\node_modules\dsh-archive-manager and enables it
in %USERPROFILE%\.dsh\profiles\web\cordis.patch.yml (a timestamped backup of
the patch file is created first). If the plugin entry already exists it is a
no-op.
After install: restart DSH (or let the patch HMR re-compose the config), then hard-refresh the browser (
Ctrl+Shift+R).
Copy this folder to
%USERPROFILE%\.dsh\profiles\node_modules\dsh-archive-manager
(create the folder if needed; the profile's node_modules is the hoisted
resolution root for the loader).
Edit %USERPROFILE%\.dsh\profiles\web\cordis.patch.yml and append:
- insert:
- id: dsh-archive-manager
name: dsh-archive-manager
Restart DSH (or let the patch HMR re-compose the config), then hard-refresh
the browser (Ctrl+Shift+R).
dsh plugin --profile web add "file:<repo>"
dsh plugin forwards to pnpm and only auto-activates packages that declare a
dsh.bundle; this UI plugin does not, so it is installed as a plain
dependency — you still need step 2 (the cordis.patch.yml insert) above.
The sidebar foot now shows an 归档 / Archive button next to Settings.
Click it: archived conversations are listed under their workspace headings with Open, Restore and folder-icon actions.
You can also probe the host endpoints directly:
POST /api/archiveManager/unarchive
{"type":"client-request","rpcId":"x","method":"archiveManager/unarchive",
"payload":{"args":{"request":{"sessionId":"<archived-session-id>"}}}}
POST /api/archiveManager/openSessionFolder
{"type":"client-request","rpcId":"x","method":"archiveManager/openSessionFolder",
"payload":{"args":{"request":{"sessionId":"<archived-session-id>"}}}}
powershell -ExecutionPolicy Bypass -File .\scripts\uninstall.ps1
or manually: remove the dsh-archive-manager entry from
cordis.patch.yml and delete
%USERPROFILE%\.dsh\profiles\node_modules\dsh-archive-manager, then restart
DSH.
No build step: src/index.js is the host plugin, src/client.js is the
browser bundle (module-loader format). Sanity checks:
node --check src/index.js
node --check src/client.js
Host-side smoke test (real cordis Context + stub registry/persistence):
import { Context } from '@deepseek-ai/cordis';
import { apply } from './src/index.js';
const ctx = new Context();
let archived = ['a', 'b'];
ctx.provide('workspaceRegistry', {
enqueueOperation(op) { return Promise.resolve().then(op); },
requireState() { return { archivedSessionIds: archived }; },
async setState(s) { archived = s.archivedSessionIds; },
get archivedSessionIds() { return archived; },
});
const svc = apply(ctx);
console.log(await svc.unarchive({ sessionId: 'b' })); // { archivedSessionIds: ['a'] }
archivedSessionIds set re-syncs on the next workspace baseline
(reconnect / list refresh).openSessionFolder reveals the transcript directory (under
~/.dsh/sessions/...), not the project workspace directory.MIT
CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: 无有效分类标签。