dsh-plugin-session-rename
DSH plugin that gives the agent a native session_rename tool backed by the Cordis sessionTitle service.
- Stars
- 0
- Language
- JavaScript
- Created
- Oct 22, 2026
- Updated
- Oct 22, 2026
Introduction
dsh-plugin-session-rename
English | 中文
A tiny DeepSeek Harness (DSH) plugin that gives the Agent one native tool:
session_rename(title: string)
The tool calls the Cordis sessionTitle service directly — sessionTitle.rename(session, title) — so the current conversation is renamed for real, not just in the model's imagination.
Why
Out of the box the user can rename a conversation from the UI, but the Agent cannot. That matters when a session's title should carry its state:
- a
[wip]/[pending]/[done]prefix that tracks what the session is doing right now; - a title derived from the finished artifact instead of the first prompt;
- a corrected title when the first prompt was vague.
With this plugin the Agent can keep the title honest on its own, at the moment the state actually changes.
What happens on a rename
sessionTitle.rename(session, title) appends a session/title event with source: user to the session log. Three consequences follow:
| Property | Effect |
|---|---|
| Durable | Replay, fork and resume all rebuild the title from the log. |
| Pinned | In-flight automatic title generation is superseded, and later prompts no longer auto-rename the conversation. |
| Live | The session list and the Chat header repaint as soon as the event lands — no page refresh. |
Requirements
- A DSH build that provides the
sessionTitleservice (it ships with the standard Web/Desktop bundles). - No runtime dependencies. The plugin imports nothing at all.
Install
From npm (one command)
dsh plugin --profile <profile> add dsh-plugin-session-rename
This is the form the in-app Plugin Hub and the community index rely on. The
package declares dsh.bundle.patch, so the installer appends it to
dsh.profile.bundles and the row mounts itself:
- insert:
- id: session-rename
name: 'dsh-plugin-session-rename'
Note that a profile named desktop is owned by the Electron application and
cannot be managed from the CLI; use the in-app plugin manager there, or install
from source below.
From source (works before an npm release)
The dsh plugin command is a thin forwarder to pnpm add, so a git spec works
too:
dsh plugin --profile <profile> add git+https://github.com/ccclucky/dsh-plugin-session-rename.git
Local checkout in your profile
Clone this repository anywhere, then point the profile patch at the file. The Loader anchors relative paths beside the patch file:
# ~/.dsh/profiles/<profile>/cordis.patch.yml
- insert:
- id: session-rename
name: './plugins/session-rename/index.js'
Use one channel only: npm, git and a local row at once produce a duplicate
entry id session-rename.
HMR picks up both the module and the patch layer live; no restart is needed.
Usage
Ask in natural language — "rename this conversation to [done] 迁移收尾" — or the Agent calls it directly:
{ "title": "[wip] 迁移进行中" }
Result:
{
"title": "[wip] 迁移进行中",
"eventSeq": 514,
"source": "user"
}
Errors are explicit, never silent:
- an empty or whitespace-only title is rejected before the service is called;
- a call with no owning agent, or an agent without a live session, is rejected;
- a title the service normalizes to empty propagates the service's own error.
Design notes
- Raw JSON Schema, not the authoring dialect.
ctx.tools.register()takes raw JSON Schema.defineTool()'s authoring dialect (required: trueinline in each property) is for packaged, TypeScript-authored tools; mixing them makes the loader row fail to activate. The tests pin this. - The model cannot target someone else's session. The session comes from
exec.agent.session, never from tool arguments. - Zero imports. The registry accepts a plain
ToolDefinition, so nothing has to resolve from the profile'snode_modules. - Dormant rather than broken.
inject = ['tools', 'sessionTitle']keeps the plugin inactive in a profile lacking either service instead of throwing. - Disposal is owned. Registration happens inside
ctx.effect(...), so disabling the row removes the tool.
Test
node --test
14 contract tests, no dependencies, no DSH install needed: they drive the plugin through a stub Cordis context and assert the registration shape, the raw-schema contract, session resolution, cancellation and every error path.
Compatibility
Written against the DSH 0.2.x plugin API (ctx.tools.register, ctx.effect, sessionTitle.rename).
The package declares engines.dsh: ">=0.2.1-rc.2 <0.3.0". DSH checks that range
before installing and refuses an incompatible runtime instead of loading a plugin
that may crash — DSH is in developer preview, so a 0.3.x breaking change should
fail loudly. Because engines.dsh is present it decides alone: the package
deliberately declares no @deepseek-ai/* peer dependencies, since it imports
nothing and should not be gated by peer resolution.
If a future runtime matches the code but not the range, grant the documented
exact-version exemption (dsh plugin allow-version) rather than editing the range.
Distribution status
| Channel | Available |
|---|---|
| npm registry | ✅ dsh-plugin-session-rename@1.0.0 — published with provenance |
dsh plugin add dsh-plugin-session-rename | ✅ verified: installs in seconds, and the installer appends the bundle to dsh.profile.bundles |
| GitHub repository | ✅ https://github.com/ccclucky/dsh-plugin-session-rename |
GitHub topic dsh-plugin | ✅ added — the community hub (dsh-plugin.org) discovers repos by this topic |
dsh plugin add git+https://… | ✅ also works, for an unreleased commit |
Releases are published by .github/workflows/publish.yml on a v* tag: it runs
the tests, verifies the tarball, then publishes with provenance. The NPM_TOKEN
secret must hold a granular access token with "Bypass 2FA" enabled — a token
without that bypass authenticates fine and then fails the upload with a 403.
License
MIT © CCLUCKY