Sessions & Messages
dsh-session-tabs
licat2023/dsh-session-tabs · ★ 0
Browser-style session tab bar for DeepSeek Harness (DSH): every open session gets a top tab — switch, close and create like a browser. The current session is highlighted, with run status at a glance.
Manifest details
安装
dsh plugin --profile web add github:licat2023/dsh-session-tabsGitHub 源码安装:首次需按提示配置 allowBuilds 构建授权后重试
For install and environment setup, plus plugin development tutorials, see DSH community docs ↗
README
Table of contents
English | 中文
A browser-style session tab bar for DeepSeek Harness (DSH): every session you open gets a top tab — click to switch, close per tab, start new sessions, just like a browser. The current session is highlighted and its running state is visible at a glance.
Screenshots
Tab history navigation
The tab history is an activation log: every switch (clicking a tab, closing the active tab, creating a session) truncates the forward chain and appends the current session to the stack tail. Closing a tab only removes its entry from the strip — it is not deleted from the history, so going back onto a closed tab reopens it.
flowchart LR
HOME(("Home<br/>navIndex = −1"))
A["Session A"]
B["Session B"]
C["Session C"]
CUR["Session B*<br/>(current)"]
A --- B --- C
A -. "Back past the first entry → home" .-> HOME
HOME -. "Forward restores the first entry (never returns to home)" .-> A
C -. "Closing active C → right neighbor B appended (normal switch)" .-> CUR
classDef current fill:#eef2ff,stroke:#3964fe,stroke-width:2px;
class CUR current
What each action does:
flowchart TD
OP{"Action on a tab"} -->|"Close active tab"| S1["Switch to right neighbor and record it<br/>(same as a normal switch)"]
OP -->|"Close inactive tab"| S2["Current session stays<br/>nothing recorded"]
OP -->|"Close all tabs"| S3["Terminal home<br/>back restores the most recent entry · forward is a no-op"]
OP -->|"Open session / New"| S4["Truncate forward chain · append to stack tail"]
S1 --> TIP["Home (navIndex = −1) is always outside the stack:<br/>after going back from home to a tab, pressing forward<br/>only moves through history entries — never back to home"]
S3 --> TIP
classDef tip fill:#fff7e6,stroke:#f7ad31,stroke-width:1px;
class TIP tip
Relationship to the existing layout
The tab bar sits beside the sidebar (a position: fixed top bar starting at the sidebar's right edge) and does not squeeze the sidebar:
- The sidebar column stays in place (draggable 264–420px; the bar follows automatically when collapsed to the 56px rail);
- Only the center column's content is pushed down 34px to make room;
- Theme-aware: uses DSH theme tokens (
--dsw-alias-*), adapts to light/dark automatically.
Features
- One tab per opened session (MRU, in open order)
- Current session highlighted (brand underline,
data-active) - Status dot: running (brand pulse) / awaiting interaction (amber) / completed (green)
- × Close tab:
- Closing the active tab is a normal switch — it jumps to the right neighbor tab (the left one when the closed tab was rightmost) and is recorded into the tab history like any switch;
- Closing an inactive tab: the current session stays, nothing is recorded (a closed session can still be restored by going back through the history);
- Closing the last tab enters the home state (no session selected): back restores the most recent history entry, forward is a no-op.
- Middle mouse button: on a tab = close that tab; on a sidebar session row = open it as a background tab (without switching the current session)
- Side mouse buttons: browser-style session history navigation — back/forward move one entry at a time (landing on a closed tab reopens it); home is special: after going back from home to a tab, forward never returns to home
- + New session (
workspaces.startSession()) - Horizontal scrolling when tabs overflow (scrollbar hidden)
- Pure client-side implementation: no Host dependency, no persistent writes
Installation (deployment-level, auto-loads after refresh)
dsh plugin --profile web add github:licat2023/dsh-session-tabs
(For a local checkout you can use the path form instead: dsh plugin --profile web add ./dsh-session-tabs.)
Or manually: add the dependency to the profile's package.json and insert the row into cordis.patch.yml:
- insert:
- id: dsh-session-tabs
name: dsh-session-tabs
Then run pnpm install and restart DSH (or trigger the profile patch hot-reload and refresh the page). After that the tab bar appears automatically on every page load — no approval, no manual activation.
Quick start
- Refresh the page (or restart DSH): the tab bar appears at the top and the current session becomes a tab;
- Open more sessions: click a sidebar session row (open in foreground) or middle-click it (open as a background tab without switching); click
+on the bar for a new session; - Switch by clicking a tab; close via its
×or a middle-click on the tab; - History navigation: mouse side buttons for back/forward (browser-style, see Tab history navigation).
Uninstall
dsh plugin --profile web remove dsh-session-tabs
Refresh the page afterwards — the tab bar disappears (the plugin never writes anything persistent, so no extra cleanup is needed).
Compatibility
| Item | Value |
|---|---|
| Supported DSH versions | Tested on 0.1.0-rc.6 (npm release) and 0.1.0-rc.7 (mainline source); theoretically compatible with every version from 0.1.0-rc.6 onward |
| Last verified | 2026-08-18 |
| Verification coverage | load/unload, tab switching, closing active/inactive/all tabs, middle-click close and background open, side-button back/forward, archived-tab cleanup, light/dark themes |
| Interface dependencies | shell.overlay slot standard props (useSessions/useWorkspaces), sessions.open/sessions.clear, workspaces.startSession |
| Configuration | none (pure client, no Config) |
Compatibility rationale: the plugin only uses public interfaces that have been stable since 0.1.0-rc.6 (slot standard props and public sessions/workspaces methods) and has been verified on two different distribution sources — the npm release (official npx @deepseek-ai/dsh web command, real-machine) and the mainline source (full feature pass). DSH mainline evolves quickly and old results can go stale. If you hit an issue on a newer version, file an issue with your DSH version and commit.
Permissions & data
- Pure client-side: no Host code is injected, no Host dependency, no persistent writes;
- Reads: session list and selection (
useSessions), archived set (useWorkspaces), plus calls tosessions.open/sessions.clear/workspaces.startSession— all public DSH interfaces; the data is used only to render tabs and navigate; - No network, no credentials, no file access; the tab order and nav history live only in the current page's memory and reset on refresh.
Troubleshooting
| Symptom | Fix |
|---|---|
| Tab bar does not appear | Check the profile dependency is installed (pnpm install) and cordis.patch.yml has the insert row; after the patch hot-reload, hard-refresh the page |
| Tab titles look stale | Archived/renamed sessions re-align on refresh (the tab MRU follows the session list) |
| Tab bar is misplaced | Check for other plugins injecting into shell.overlay (multiple occupants are ordered by order) |
| Side buttons trigger browser history navigation | Confirm the latest bundle is loaded (deployment plugins load with the page — hard-refresh once) |
Development notes
lib/client.jsis a browser bundle in__ModuleLoader__.loadformat (same as installed community plugins), loaded by the web shell's module system throughexports["./client"];package.jsondeclaresdsh.client(platform: 'web');- The only dependencies are
react(shell seed) and the Cordis runtime;sessions.clear()(clearing the current selection into the no-session view state) is used only when the last tab is closed.
License
MIT