Bundle
dsh-session-handoff
Hand your long session over to a fresh one: /handoff summarizes the recent conversation with an LLM, creates a clean new session in the same workspace, injects the summary as its first message, and auto-opens it. The origin session is unchanged.
- Source
- WeiYe6
- stars
- 4 stars
- License
- MIT
- Updated
- Updated 8 hours ago
Readme
# dsh-session-handoff
[](LICENSE)
[](package.json)
[](https://github.com/deepseek-ai/deepseek-harness)
English | [中文](README.zh-CN.md)
**Hand your long DSH session over to a clean one.** `/handoff` summarizes the recent
conversation with an LLM, creates a **brand-new session + agent** in the same workspace
(no history copied), injects a structured handoff document as its first message, and
**auto-opens** it — the model continues from the summary instead of replaying the whole
old history. The origin session is untouched.
## Features
- **One command** — `/handoff [<N>|all]` (defaults to the last 8 user messages; `all`
covers everything)
- **Clean handoff** — a fresh session with the origin's workspace, model route, and
agent preset (system prompt / tools / skills), no context bloat
- **Structured summary** — 任务目标 / 当前进度 / 关键决策 / 涉及文件 / 下一步 / 遗留问题
- **Auto-open** — the client half waits for the new session to be ready and navigates
to it (each child auto-opens once; history replay never re-jumps)
- **Robust by default** — summaries run with thinking off (fast, cheap), oversized
excerpts keep the newest messages instead of erroring, and finish reasons
(`max-tokens` / `error` / `aborted`) are translated into actionable errors
- **Zero core changes** — a single `dsh.bundle.patch` row; only public services are used
## Install
```sh
# 1. Build the bundle from source (or grab a release tarball)
npm install && npm run build && npm pack # → dsh-session-handoff-0.2.1.tgz
# 2. Install into your web profile
dsh plugin --profile web add ./dsh-session-handoff-0.2.1.tgz
# 3. Restart and verify the row is mounted
dsh web
dsh --profile web --dump-config | grep handoff
# expected: # == dsh-session-handoff / - id: handoff / - name: dsh-session-handoff
```
> Dev-time source link (`dsh plugin --profile web add D:/path/to/dsh-session-handoff`) requires
> the source dir's `node_modules` to resolve `@deepseek-ai/*` peers; prefer the tarball.
## Usage
Type in any conversation's input box:
```text
/handoff # summarize the last 8 user messages (default)
/handoff 20 # summarize the last 20 (same as turns=20)
/handoff all # summarize every user message (same as turns=all)
```
What happens:
1. A command card shows "summarizing…";
2. An LLM produces the handoff document (goal / progress / decisions / files / next
steps / open questions), which becomes the new session's first message;
3. The new session **auto-opens**; the origin session stays intact and is linked back.
> ⚠️ **Privacy**: the recent conversation text (user + assistant messages in the
> requested window) is sent to the configured model to produce the summary.
## Configuration
```yaml
- id: handoff
name: dsh-session-handoff
config:
turns: 8 # user-message rounds to extract (1–50)
maxInputChars: 24000 # byte cap for the summary input (oldest dropped first)
maxTokens: 2000 # summary output budget
reasoningEffort: off # off (default, fast/cheap) | high | max | inherit
timeoutMs: 120000 # summary call timeout
# provider: deepseek-official # optional fixed model route
# model: deepseek-v4-flash # must be paired with provider
```
Without `provider`/`model`, the current session's latest logged model route
(`session.requestHeader()`) is used.
## How it works
- **Host half** (`index.mjs`, plain ESM): public services only — `commands`
(`/handoff`), `llm` (`ctx.llm.stream`, following official `session-title-llm`),
`agents` (`ctx.agents.create` — session **and** agent together, inheriting the
origin's cwd / model route / agent preset via `agentPresets.mount`), plus
`workspaceRegistry.attachSession` (same-workspace grouping) and
`sessionTitle.rename` (a `handoff: <source>` title).
- **Client half** (`src/client/`, tsdown → `lib/client.js`): a `handoff`
conversation node matches the `/handoff` success event and auto-opens the child
session (polling until it is addressable, deduped via localStorage).
## Development
```sh
npm install # devDeps: tsdown / typescript / @types/react / vitest / jsdom ...
npm test # 22 tests: 17 host+client pure functions + 5 client component
npm run typecheck
npm run build # tsdown → lib/client.js (CJS factory, official client-module format)
npm pack # prepack runs typecheck + build automatically
```
Publish checklist: add the `dsh-plugin` GitHub topic → open a PR to
[awesome-deepseek-harness](https://github.com/0xsline/awesome-deepseek-harness) →
optionally `npm publish`.
## Known limitations
- The handoff document lives in the session only; it is not written to disk
(`HANDOFF.md` is a future enhancement).
- Supports the DSH `0.1.0-rc.5` through `rc.8` line and `0.1.1-rc.2`.
DSH `0.1.2-alpha.1` is intentionally excluded because its conversation UI/service
split requires a separate client-side migration.
- The auto-open path has jsdom component coverage, but real browser timing still
needs end-to-end verification.
## License
[MIT](./LICENSE)
Install
dsh plugin --profile web add github:WeiYe6/dsh-session-handoff
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install dsh-session-handoff from the hub
- This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
- This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.