Add session management tools and sidebar chat to DeepSeek Harness: list/read/create/send sessions, and open a sub-session panel mounted beside the main session for continuous conversation.
ⓘ This plugin is a sub-package of the Ephemeral-AI-Lab/dsh-plugins monorepo — stars and activity count the whole repository.
- Language
- Python
- License
- MIT
- Branch
- main
Install
$ dsh plugin --profile web add dsh-sessionsRun the command above in your terminal to install this plugin via the dsh CLI. You can switch Profile in the top-right corner. New to dsh? Read the beginner tutorial
Install via your agent
Install the DeepSeek Harness plugin Ephemeral-AI-Lab/dsh-plugins/sessions for me: review the repository at https://github.com/Ephemeral-AI-Lab/dsh-plugins first, then run the install command and verify the plugin loads successfully.
Paste this instruction to the DSH Web GUI assistant — it will install and verify for you.
The landing page's corresponding repository subpath is
sessions, the repository's hosting directory is also calledsessions, the npm package name isdsh-sessions(package.json:3), and it's one of the subpackages in theEphemeral-AI-Lab/dsh-pluginsmonorepo. This wiki focuses on the capabilities corresponding to thesessionspath.
One-Sentence Positioning
Add "session management" and "side chat" capabilities to DeepSeek Harness: enable agents and users to list historical sessions, read conversation content by window, create new sessions, send messages to existing sessions (steer or followup), and open a mountable side session panel that can continue conversations without leaving the main session.
Core Capabilities
- List recent sessions or view single session status:
session_status({ session_id?, recent_n? })returns 50 records in reverse chronological order by default, with status divided into running / idle / cold / missing (src/service.ts:22-60,SPEC §2 session_status). - Read session history by window:
session_read({ session_id, offset?, limit? })read-only, no recovery, no restart generation, skips trace-only data like token streams and lifecycle events (src/service.ts:85-102). - Create new session and queue initial prompt:
session_create({ prompt, preset?, model?, cwd? })returns new session_id andstatus: "queued", does not wait for generation to complete (src/creation-service.ts:26-68). - Send message to existing session:
session_send({ session_id, message, mode? })supports steer (wake up / insert next step) and followup (queue as next turn), cold sessions will be recovered by this plugin before sending message (src/send-service.ts:18-61). - Open a real continuable sub-session:
session_open_sidechat({ prompt })returns subagent_id (not another generated ID), reuses DSH's existing send_message to continue conversation (src/sidechat/sidechat-service.ts:29-49,SIDE_CHAT_SPEC §2). - Equivalent user command
/sessionsplus Web visualization: command covers status / read / create / send / sidechat five actions (/sessions createsupports--preset/--provider/--model/--effort/--cwdand JSON two forms,src/commands.ts:11,72-118,212-325); Web renders side chat as tabbed, state/persistent separated, independent panel that restores tabs when closed and reopened, and presents/sessionscommand results as floating popup (src/ui/SideChatPanel.tsx,src/ui/index.ts:42-91).
Technical Implementation
- Language: TypeScript (compiled to
lib/withtsc -p tsconfig.json,package.json:11declares"type": "module") - Key Dependencies:
@deepseek-ai/cordis(>=4.0.0): Host plugin framework,apply(ctx)follows standard Cordis effect@deepseek-ai/dsh-tools/@deepseek-ai/dsh-commands: UsedefineToolto register five tools, usectx.commands.registerto register/sessionscommand@deepseek-ai/dsh-agent+@deepseek-ai/dsh-subagent+@deepseek-ai/dsh-session-persistence+@deepseek-ai/dsh-session-query+@deepseek-ai/dsh-workspace+@deepseek-ai/dsh-llm: respectively responsible for creating/recovering Agent, subagent startup, session storage/recovery, title snapshot, workspace parsing, message construction@deepseek-ai/dsh-client-ui-*+@deepseek-ai/dsh-client-runtime+react(>=18.2.0): Web injects side chat panel intoshell.overlayslot, command result floating layer intoconversation.input.overlayslot
- Architecture Pattern: Dual-end Cordis plugin. Server-side
apply(ctx)injects eight services insessions/src/index.ts:15-29:tools / commands / agents / subagents / llm / sessionPersistence / sessionQuery / workspaceRegistry, combines four Services (SessionsService,SessionCreationService,SessionSendService,SideChatService) and exposes capabilities viaregisterSessionTools+registerSessionsCommand; Client-sideapply(ctx)insrc/ui/index.ts:18-102listens tocommand/executedevent, injects side chat intoshell.overlayslot, renders transient/sessionscommand results as floating popup viaconversation.input.overlayslot.cordis.patch.ymlinjects a bundle patch nameddsh-sessionsinto the host, allowing the host to mount this plugin during loading. - Entry Files:
sessions/src/index.ts(server-side) +sessions/src/ui/index.ts(client-side), both injected into DSH viapackage.json#dshfieldsbundle.patch+client.inject.
Use Cases
When users want the agent to take "managing multiple sessions" more seriously—for example, jumping back to a session from 3 days ago in a long project to read context, temporarily pulling a parallel agent to look up information without interrupting the current main task, or viewing progress of two sub-tasks side by side without leaving the current chat window—this plugin provides standardized tools/commands and Web panel, making "session list, read, create, send, parallel sub-session" capabilities that the agent can directly invoke.
Prerequisites & Compatibility
| Dependency | Minimum Version | Description |
|---|---|---|
@deepseek-ai/dsh-tools | >=0.1.0-rc.5 | peerDependencies, registering five agent tools depends on this |
@deepseek-ai/dsh-commands | >=0.1.0-rc.5 | peerDependencies, registering /sessions command depends on this |
@deepseek-ai/dsh-agent | >=0.1.0-rc.5 | peerDependencies, SessionCreationService / SessionSendService directly hold Agent |
@deepseek-ai/dsh-subagent | >=0.1.0-rc.7 | peerDependencies, side chat uses ctx.subagents.startContinuable |
@deepseek-ai/dsh-session-persistence | >=0.1.0-rc.5 | peerDependencies, session_status enumerating cold sessions, session_send recovering cold sessions both depend on this |
@deepseek-ai/dsh-session-query | >=0.1.0-rc.5 | peerDependencies, title snapshots read via readTitleSnapshots |
@deepseek-ai/dsh-workspace | >=0.1.0-rc.7 | peerDependencies, cwd parsed via workspaceRegistry.resolveByPath |
@deepseek-ai/dsh-agent-presets | >=0.1.0-rc.7 | peerDependencies, session_create parsing preset depends on this |
@deepseek-ai/dsh-agent-default-model | >=0.1.0-rc.7 | peerDependencies, fallback to deployment default when root call has no explicit model |
@deepseek-ai/dsh-llm | >=0.1.0-rc.5 | peerDependencies, createUserMessage + ReasoningEffortId source |
@deepseek-ai/dsh-client-runtime + @deepseek-ai/dsh-client-ui-commands + @deepseek-ai/dsh-client-ui-conversation + @deepseek-ai/dsh-client-ui-primitives + @deepseek-ai/dsh-client-ui-tool + @deepseek-ai/dsh-client-ui-slots + @deepseek-ai/dsh-api-remotes + @deepseek-ai/dsh-client-connection | each >=0.1.0-rc.5 | peerDependencies, Web side chat panel and floating popup required; listed in package.json:19-26 under dsh.client.inject, missing any won't load Web UI |
@deepseek-ai/cordis | >=4.0.0 | peerDependencies, host plugin framework |
react | >=18.2.0 | peerDependencies, side chat panel is a React component |
| Platform | DSH Web | package.json:27 explicitly declares dsh.client.platform: "web", not declared for CLI/desktop |
| Node.js | Not declared | package.json has no engines field; only devDependencies has @types/node ^22.20.0 |
| Native modules | None | All pure JS dependencies, no node-gyp build items; plugin only uses Node built-in modules like node:crypto / node:fs/promises / node:path |
Installation
dsh plugin --profile web add github:Ephemeral-AI-Lab/dsh-plugins/sessions
Configuration
This plugin requires no additional configuration. After installation, restart DSH and create a new session to use. Session-related parameters (prompt, session_id, cwd, model, preset, reasoningEffort, recent_n, offset, limit, mode, subagent_id, etc.) are all passed at runtime via tool calls or /sessions command; the source code has no .env / settings configuration file reading logic (grep found no process.env / config.get / Schema runtime configuration entry).
The only fields that will be validated are hard constraints of tool/command input parameters: session_id/message/prompt/provider/model/preset/reasoningEffort/cwd must all be non-empty strings, recent_n/offset/limit must be positive integers, limit ceiling is 200 (src/service.ts:16,134-151, src/creation-service.ts:267-274, src/sidechat/sidechat-service.ts:79-83), these are input validations, not configurable items.
FAQ
Q: How to use after installation?
A: Restart DSH and create a new session. Agents can call session_status / session_read / session_create / session_send / session_open_sidechat five tools in natural language; users can also directly type /sessions status, /sessions read <ID>, /sessions create <prompt>, /sessions send <ID> <msg>, /sessions sidechat "PROMPT" in the input box, operating on the same backend (src/commands.ts:21-70). No need to create new preset or toggle any host configuration.
Q: Will session_create wait for model generation to complete before returning?
A: No. Both README §5 and SPEC §2 session_create clearly state it only creates a new session and puts the initial prompt in the inbox then returns immediately; the returned status: "queued" means "queued, not completed"; to see generation results, use session_status to query current status, or session_read to read window messages. followup() rolls back handle and re-throws on failure (src/creation-service.ts:52-60), so either get session_id or throw error, no half-finished products left behind.
Q: What's the difference between steer and followup in session_send?
A: steer (default) wakes up idle agent, and for running agent sends to the most recent step boundary; followup queues as ordinary next turn (src/send-service.ts:50-51, SPEC §2 session_send). Neither interrupts the agent's current running step; the returned message_id is just the acceptance receipt in the inbox, not indicating the model has finished processing.
Q: Is side chat /sessions sidechat the same as session_create?
A: No. session_open_sidechat uses Harness's built-in continuable subagent service (ctx.subagents.startContinuable, src/sidechat/sidechat-service.ts:33-49), returns a real continuable subagent_id, the same as sub-agents seen via list_agents({ scope: "children" }); session_create returns a new top-level session_id. Side chat has a dedicated tabbed panel on Web (src/ui/SideChatPanel.tsx), tabs persist when closed and reopened, main session won't be navigated away; sub-sessions created by ordinary session_create don't have this panel.
Q: How to select model or working directory for session_create?
A: Pass model: { provider, model, reasoningEffort? }, preset, cwd explicitly at creation. Model parsing order: explicit > caller agent routing > deployment default; preset parsing order: explicit > caller preset > deployment default; when cwd is missing, sub-session inherits caller's cwd, root call has no workspace bound (SPEC §2 session_create parsing table). cwd must be an existing absolute directory, will be canonicalized by realpath, otherwise throws cwd must be an absolute path / cwd 'X' is not a directory (src/creation-service.ts:267-274).
Q: Can session_read read the entire history?
A: No, it's bounded reading. limit defaults and caps at 200 message blocks (src/service.ts:16 READ_SESSION_LIMIT = 200, src/service.ts:144 validation), offset is 1-based, out-of-range will be rejected with offset X is out of range. Reading cold sessions uses sessionPersistence.inspect without recovery or restarting generation (src/service.ts:88-90); only projects session specification message blocks, skips raw stream chunks, token deltas, lifecycle and other trace-only events (src/service.ts:153-162, SPEC §2 session_read).
Q: What's the relationship with dsh-loop?
A: Complementary responsibilities. dsh-sessions has cross-session discovery/read/create/send (SPEC §1); dsh-loop has in-session loop alarms (see _wiki/Ephemeral-AI-Lab_dsh-plugins_loop.md for details). dsh-loop uses this plugin's session list capability to fill "existing sessions" option in its panel (SPEC §5), the two won't duplicate the same session state implementation.
Q: How to uninstall?
A: Use dsh plugin --profile web remove with the corresponding installation source. After uninstall, the five tool names (session_status / session_read / session_create / session_send / session_open_sidechat) and /sessions command disappear from new sessions' tool table (the dispose provided in src/index.ts:23-28 will undo registration); already created/sent sessions and side chats will still remain in DSH session storage, not deleted.
Learning Curve
Beginner — Ready to use after installation, no configuration files, no native modules, no special presets to create; as fast as 30 seconds to type /sessions status in input box to see recent session list, or /sessions sidechat "帮我查一下" to open a side chat panel.
Known Issues & Limitations
- v1 has no "session modify/delete/rename" tools:
session_statusis read-only,session_sendonly delivers messages,session_createonly creates new sessions, no delete / rename / archive operations provided (README §5andSPEC §1explicitly list "create + send + inspect" as responsibility boundary). session_createdoes not wait for model generation completion: after returningstatus: "queued", caller needs to poll withsession_statusor pull window withsession_read(README §5/SPEC §2 session_create); getting complete reply in one tool call is not possible.session_senddoes not create new session: passing a non-existentsession_idthrowsmissing, won't auto-create (SPEC §2 session_send); cold sessions will be recovered by this plugin (src/send-service.ts:30-42), but won't create non-existent sessions.session_readwindow ceiling is 200: iflimitexceedsREAD_SESSION_LIMIT = 200it directly throwslimit must be less than or equal to 200(src/service.ts:144), must call multiple times to read in segments.session_open_sidechatrequires a calling agent: throwssession_open_sidechat requires a calling agentin tool call context without current agent (src/sidechat/sidechat-service.ts:31); this is because it needs to reuse subagent framework's parent relationship.- Side chat only visible on Web: the underlying
session_open_sidechattool can also run on command side, but has no panel, only returns JSON; UI's tabbed and state/persistent separation experience is DSH Web exclusive (src/ui/SideChatPanel.tsx,package.json:27 dsh.client.platform: "web"). - CLI/Desktop availability undeclared:
package.json:27only declaresdsh.client.platform: "web", whether CLI/TUI/Desktop bundle will automatically mount this plugin is not explicitly stated in source code (same applies todsh-loop, see same limitation in_wiki/..._loop.md). - Does not modify DeepSeek Harness host code, all goes through Cordis effect and DSH public API (
README §5/SPEC §1); this means once host changes public API shapes likedsh-session/dsh-subagent/dsh-llm, plugin needs to sync upgrade peerDependencies (currently requiresdsh-agent-presets/dsh-agent-default-model/dsh-workspace/dsh-subagentall>=0.1.0-rc.7). - Side chat
subagent_idandsession_idare the same ID type: it's a real child Session ID, consistent with whatlist_agents({ scope: "children" })lists (SIDE_CHAT_SPEC §2), but also meanssession_send({ session_id: <subagent_id>, message })goes through ordinary session delivery rather than subagent'ssend_message; if you want to use send_message's "send by subagent ID" semantics, directly call host tool, don't replace with this plugin'ssession_send(README §6explicitly warns).
Small, focused plugins that make DeepSeek Harness more capable, expressive, and pleasant to use.
Quick start · Packages · Development · Documentation
🧠 Give your DSH sessions better tools, durable workflows, and a cleaner path from idea to execution.
⚡ Quick start
Published plugins install directly into a DSH profile with one command. The
examples below target the web profile; replace web with the profile you use.
🐚 Codex Terminal
# With the DSH CLI:
dsh plugin --profile web add [email protected]
# Without the `dsh` CLI:
npm install [email protected]
🔐 Codex Coding Plan
Reuse an existing file-backed codex login from the DSH Models page:
dsh plugin --profile web add ./coding-plan/codex
# Grok Coding Plan models from the existing `grok login`
dsh plugin --profile web add ./coding-plan/grok
⏰ Loop
# With the DSH CLI:
dsh plugin --profile web add [email protected]
# Without the `dsh` CLI:
npm install [email protected]
🧪 Mock — unstable
dsh-mock is published for early testing. Its commands, API, and UI may
change before a stable release.
# With the DSH CLI:
dsh plugin --profile web add [email protected]
# Without the `dsh` CLI:
npm install [email protected]
🧭 Sessions
Inspect, create, read, and message DSH sessions with the current session tools:
# With the DSH CLI:
dsh plugin --profile web add [email protected]
# Without the `dsh` CLI:
npm install [email protected]
Restart DSH and create a new session after installing a plugin. If dsh is not
on your PATH, run the same command from a DeepSeek Harness source checkout with
pnpm dsh instead.
Direct npm installation downloads the package for use by your project. DSH profile installation is still required when you want DSH to load the plugin as part of a profile.
📦 Packages
| Package | Status | What it adds | Docs |
|---|---|---|---|
dsh-codex-coding-plan | 🧪 Local · 0.1.0 | Reuses a file-backed Codex ChatGPT login through the existing openai-codex pi-ai provider. | README |
dsh-grok-coding-plan | 🧪 Local · 0.1.0 | Reuses a file-backed Grok subscription login through the existing xai pi-ai provider. | README |
dsh-codex-terminal | ✅ Published · 0.1.3 | Codex-compatible exec_command and write_stdin tools with persistent command sessions. | README · npm |
dsh-loop | ✅ Published · 0.1.3 | Session-scoped recurring alarms, loop tools, slash commands, and a web UI. | README · npm |
dsh-mock | ⚠️ Unstable · ✅ Published · 0.1.0 | Deterministic mock model turns and replay commands routed through the real DSH AgentLoop and ToolRuntime. | README · SPEC · npm |
dsh-sessions | ✅ Published · 0.1.1 | Session discovery, bounded reads, creation, and delivery through session tools and /sessions. | README · SPEC · npm |
🐚 dsh-codex-terminal
Run shell commands like a Codex-style agent: start long-running processes, poll for output, and send input to persistent sessions. PTY transport is used by default with a configured pipe fallback when PTY allocation is unavailable.
⏰ dsh-loop
Create durable, session-local recurring prompts that can be managed through
agent tools, /loop commands, and the web UI. Loops resume with the session
and keep each alarm independent from the others.
🧪 dsh-mock
Exercise deterministic mock model turns through /mock run and /mock replay
while preserving the real DSH AgentLoop, ToolRuntime, policy, and event flow.
⚠️ Unstable: published as
[email protected]for early testing. The command, API, and UI surface may change before a stable release.
Install it into the DSH web profile with one command:
dsh plugin --profile web add [email protected]
🛠️ Development
Each plugin is independently installable and testable. For example:
cd loop
pnpm install
pnpm test
pnpm build
The source tree intentionally stays outside the DeepSeek Harness repository; DSH composes plugins through profile-scoped installation and patch layers.
📚 Documentation
- Codex Terminal documentation
- Coding Plan core
- Codex Coding Plan documentation
- Grok Coding Plan documentation
- Loop documentation
- Mock documentation
- Mock implementation specification
- Sessions documentation
- Sessions specification
- DeepSeek Harness
🤝 Contributing
Issues, ideas, and pull requests are welcome. Keep plugins focused, document their runtime contracts, and include tests for changes to tools, persistence, or UI behavior.
📄 License
Released under the MIT License.
Read the usage guide →
Install steps, key points, FAQ and compatibility for this plugin — auto-derived from indexed fields.
Listing badge
[](https://deepseek-plugin.org/plugins/Ephemeral-AI-Lab/dsh-plugins/sessions)Paste this markdown into your GitHub README to link back to this listing. The badge only states the listing — not a security endorsement.