heartmove
dsh-side-chat
一个 DSH 网页插件:在对话中选中部分内容后,即可在 侧边聊天里提问 —— 侧边聊天是位于右侧面板、按发起它的主会话隔离的独立聊天。
- Stars
- 0
- Language
- TypeScript
- Created
- Aug 14, 2026
- Updated
- Aug 14, 2026
Introduction
dsh-side-chat — 侧边聊天 (Side chat)
A DSH web plugin that lets you select part of a conversation and ask about it in a side chat — a dedicated chat opened in a right-side panel, scoped to the conversation it was started from. Side-chat AI replies can also be brought back to the main conversation (directly or as a summary, into the composer draft or as a collapsed context row).
中文文档见 README.zh.md.
What it does
- Select text → ask in a side chat. Select any part of a message and a floating button "Ask in side chat" appears. The selected text is carried into the side chat automatically.
- Per-conversation isolation. Each side chat is a hidden ordinary DSH
session (
meta.parentSessionlinks it to the conversation that started it, and the session is archived so it never appears in the main session list). Every conversation gets its own side chat. - Inherits main-conversation context. The side chat is aware of the conversation it was started from and its working directory, and inherits the main conversation's model, thinking effort, and permission preset by default.
- Model / effort / permission are adjustable. A two-level model menu (provider → model → effort) and a permission menu are copied from the main conversation, so each side chat can be tuned independently.
- "Look up workspace / parent when needed" switch (default off). When on, the side chat may read files from the workspace and the parent conversation when it needs more information.
- Normal conversation capabilities. Markdown replies, thinking/reasoning display, image attachments (paste / drag-and-drop), send/stop controls, and thinking-duration display — all reuse the same UI primitives as the main conversation.
- Bring AI replies back to the main conversation. Every assistant reply in the side chat can be brought into the current main conversation: select part of it with the mouse, or insert the whole reply in one click. Either way you can choose "Insert directly" (verbatim) or "Summarize & insert" (the side chat's inherited model summarizes it first). Where it lands is configurable: into the composer draft, or as a collapsed context row (injected as context — not into the composer, never sent).
- Ask about the current question dialog. When the main conversation shows a question dialog (the agent asking you something), the side panel automatically lists the question and each option with a "Bring" button: the header's "Bring all" carries every option into the side chat, while an option's "Bring" carries just that one — no manual text selection needed.
- Resizable, collapsible panel. Drag to resize (280–720 px), collapse and expand; no close button.
- Language-aware. The plugin follows DSH's language setting (Chinese / English).
Requirements
Build
pnpm install
pnpm build
pnpm build clears lib/, runs tsc -p tsconfig.build.json for type
declarations, then bundles the host (lib/index.js) and client
(lib/client.js + lib/client-registry.js) with tsdown.
Deploy
DSH web loads external plugins from the active profile. This package is a
bundle: its package.json declares dsh.bundle.patch →
cordis.patch.yml, whose insert row mounts the plugin.
That declaration is what lets dsh plugin add install the package and
activate it in one step.
Install from GitHub
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:heartmove/dsh-side-chat
dsh plugin forwards to pnpm inside ~/.dsh/profiles/web/, then reconciles the
bundle into the profile's dsh.profile.bundles layer list. A git install
fetches sources, so pnpm runs the package's prepare script (tsdown) to build
lib/ from src/ after checkout.
pnpm ≥ 10 refuses to run a git dependency's prepare script until it is
allowlisted, so the first add fails with an "Ignored build scripts" hint. Copy
the exact package key pnpm printed into the profile's pnpm-workspace.yaml
(~/.dsh/profiles/web/pnpm-workspace.yaml):
allowBuilds:
dsh-side-chat: true
then re-run the add. That allowance means "run this package's code on my
machine at install time" — only allow packages whose source you trust, and pin a
commit (github:heartmove/dsh-side-chat#<sha>) so a later push cannot silently
change what runs.
Restart dsh web, then hard-refresh the page (Ctrl/Cmd+Shift+R).
Install from a local checkout
From the directory that contains this checkout:
npx -p @deepseek-ai/dsh dsh plugin --profile web add ./dsh-side-chat
pnpm links the checkout and dsh activates the bundle the same way.
Manual link
To manage the profile by hand, link the package and list it as a bundle in
~/.dsh/profiles/web/package.json (the bundle's own cordis.patch.yml supplies
the loader row, so no insert entry is needed):
{
"dependencies": {
"dsh-side-chat": "link:D:\\path\\to\\dsh-side-chat"
},
"dsh": {
"profile": {
"bundles": ["@deepseek-ai/dsh-base", "@deepseek-ai/dsh-web-app", "dsh-side-chat"]
}
}
}
(On POSIX systems use link:/path/to/dsh-side-chat.) Then run pnpm install
in the profile directory and restart dsh web.
Usage
- Select part of any message in the main conversation.
- A floating "Ask in side chat" button appears — click it.
- If a side chat already exists for this conversation, you'll also see "Continue active side chat".
- The right-side panel opens (or expands) with the selected text staged in the composer.
- Adjust model / effort and permission, and toggle "Look up workspace / parent when needed" as desired.
- Send. The reply streams back with markdown rendering and, where applicable, a "Think" row for the model's reasoning.
- Drag the panel's left edge to resize, or use the collapse/expand control.
Sending behavior
By default (sendImmediately on), selecting text sends it immediately and
appends your configured default prompt. Turn sendImmediately off in
settings to stage the selection as an attachment instead, so you can review and
edit before sending.
Bring replies back to the main conversation
Assistant replies in the side chat can be brought into the current main conversation (never sent):
- Bring a selection. Select part of an assistant reply in the side chat, then choose "Insert directly" (verbatim) or "Summarize & insert" (the side chat's inherited model summarizes it first) from the floating menu.
- Bring the whole reply. Each assistant reply has "Insert directly" and "Summarize & insert" buttons under its text, for inserting the full reply (or its summary) in one click.
- Per the bring-back target setting, the content is either appended to the main composer draft (edit before sending) or injected as a collapsed context row (source-tagged, not into the composer; the model sees it next turn).
Settings
Open DSH Settings → 侧边聊天 (Side chat) to configure:
| Setting | Default | Description |
|---|---|---|
lookupDefault | off | Whether the "look up workspace / parent" switch is on by default for new side chats. |
sendImmediately | on | Whether selecting text sends it immediately, or stages it as an attachment. |
defaultPrompt | (empty) | Extra prompt appended when the selection is sent immediately. |
bringMode | draft | Where brought-back content lands: draft into the composer, or context as a collapsed context row. |
Preferences are stored in the DSH settings namespace dsh-side-chat.
Project layout
src/
index.ts host plugin (routes, session/agent lifecycle, transcript folding)
wire.ts request/response helpers
trust-fence.ts loopback / trusted-API request guard
settings-shared.ts preference vocabulary shared by host and client
context-types.ts Cordis Context type augmentation
client/
index.tsx client plugin (panel, composer, settings section, floating buttons)
api.ts client↔host API types
locales.ts zh/en dictionaries
client.module.css panel/composer/settings styles
layout.css #root margin-right driven by panel width
cordis.patch.yml bundle patch layer (inserts the loader row; dsh.bundle.patch)
dsh.plugin.json external plugin manifest
tsdown.config.ts bundle config (client externals + CSS inlining)