dsh-session-orb
dsh-session-orb
A draggable floating ball for quick multi-session management inside DeepSeek Harness (DSH) Web.
- A single draggable orb that hides/unhides a "recent sessions" panel.
- Per-session unread red-dot with an animated ripple — fires whenever a turn finishes (an answer is done, or the model is waiting on you in a Q&A).
- Click the ball to jump to the newest unread session; expand the panel to pick any of the 5 most recent sessions in one tap.
- Position is persisted, so the orb stays where you put it across updates.
- Smooth single-surface expand/collapse morph (content scales with the card).
Install (bundle, no build)
This is a DSH bundle: it ships a cordis.patch.yml that mounts the
session-orb plugin row, plus the host half (lib/index.js) and the browser
half (lib/client.js). Both halves run on the bundle runtime, so there is
no compile step — the browser client is served verbatim by the host's
client-modules route.
Install it into a profile (here web, the default used by
npx @deepseek-ai/dsh web):
npx @deepseek-ai/dsh plugin --profile web add dsh-session-orb
dsh plugin add installs the package and auto-appends it to the profile's
dsh.profile.bundles, so it mounts on the next boot:
npx @deepseek-ai/dsh web
The orb appears, and the plugin persists across restarts.
Requires
pnpmonPATH(used internally bydsh plugin).
How it works
| Half | File | Responsibility |
|---|---|---|
| Host | lib/index.js |
Listens for agent/session events (turn finished, Q&A waiting, approval, error) to track which sessions "need attention"; answers unreadCount / unreadTop / unreadClearSession / setCurrent / lastTurn RPC |
| Client | lib/client.js |
Renders the orb in the shell.overlay slot; polls counts, drags, morphs, jumps sessions, persists position to localStorage |
The browser half talks to the host through DSH's Typert Remote channel: the
host registers a sessionOrb service (ctx.typert.register), and the client
mounts the same descriptors (ctx.remote.$mount) and calls
ctx.remote.sessionOrb.*. This is the same no-compile RPC channel the
dsh-paste-file bundle plugin uses.
Unread rules
- Marked "needs attention" when a session:
- completes a reply/task (
agent/turn-stopping), - asks you a question (
ask_user_question), - requests an approval (
session/eventapproval/asked), - or errors (
agent/error). One session counts once (dedup), ordered by recency.
- completes a reply/task (
- Cleared automatically (view = read) when you:
- switch to that session,
- send a new message there,
- scroll the conversation to the bottom,
- or a reply completes while you are already at the bottom.
An approval is also cleared once it is decided (
approval/decided).
- Badge shows the number of non-current sessions needing attention.
- The current session's own pending shows only a red ripple — never a number.
Development
The local source also keeps the dynamic Cordis versions under plugin/ and
a load.mjs helper that prints them for pasting into cordis_define on any
DSH — useful for trying the orb in one session without installing anything.
node load.mjs # print the two dynamic halves
node --check lib/index.js && node --check lib/client.js
Requirements
- DSH Web (
@deepseek-ai/dsh-web-appbase bundle). - The host provides the
typertservice; the client providesslots,timer,sessions, andremote.
License
MIT