DeepSHPlugins
dsh-session-drafts 项目预览
GITHUB / COMMUNITY PROJECT

dsh-session-drafts

会话与消息JavaScriptBSD-3-Clause

Cursor 风格的新会话:每次点击都新建一个空白草稿会话(首条消息前即持久化),不再复用工作区唯一的空会话;侧栏新增草稿切换器,可同时保留多个空会话。

3 Starsne-ilyxa 更新时间 2026-08-26
访问 GitHub 仓库
dsh-session-drafts 项目预览
dsh-session-drafts 界面截图dsh-session-drafts 界面截图

项目介绍

中文

Cursor 风格的新会话:每次点击都新建一个空白草稿会话(首条消息前即持久化),不再复用工作区唯一的空会话;侧栏新增草稿切换器,可同时保留多个空会话。

English

Cursor-style New Session: every click creates a fresh blank draft session (persisted before the first message) instead of reusing the workspace's single one, plus a sidebar Drafts switcher to keep several empty chats open at once.

项目信息与收录信号

快照 2026-09-11
作者 / 组织
ne-ilyxa
仓库
ne-ilyxa/dsh-session-drafts
GitHub Stars
3
Forks
0
开发语言
JavaScript
许可证
BSD-3-Clause
最近推送
2026-08-26
Manifest
数据中检测到声明

公开仓库不自动等于可商用;许可证与当前兼容性以原项目文档为准。Manifest 和数据评分不构成安装安全认证。

数据评分

57/ 100
维护活跃
90
文档与实用信息
74
生态关注度
17
安装便捷信号
100
项目声明信号
100

近 16 天仍在更新;关注度尚低(3);标准命令一键安装。

评分来自已有数据快照的五维模型,仅作浏览参考,不是实际使用评测或安全检测结论。

安装与使用

所有项目资料与许可均以对应 GitHub 仓库为准。

dsh plugin --profile web add @ne-ilyxa/dsh-session-drafts

复制命令不会自动执行。请先阅读仓库文档,确认环境要求与许可证。

项目截图

仓库 README

GitHub 原文

已保存的仓库文档快照;文档抓取时间未记录,可能与上方目录介绍处于不同版本。安装前请核对当前仓库说明。

dsh-session-drafts

CI

Cursor-style draft chats for DeepSeek Harness (DSH): New Session reuses the empty draft — and only mints a fresh one when every draft has unsent text — so empty placeholders never stack, exactly like Cursor's (or Telegram's) chat list. Every draft lives in the sidebar tree as an ordinary row: unsent-text preview title, creation time, a pencil mark and a gray tint, persistent across page reloads and host restarts. No popup, no drafts menu.

The stock web shell reuses a workspace's single blank session regardless of typed text (one empty chat per workspace, silently discarding your draft), and hides every other blank from the tree. This plugin replaces both behaviors.

What it does

  1. Never stack empty drafts — on every mint path. connectWorkspace is the funnel the stock runtime uses for all of them (stock startSession, the boot initial selection, the hero workspace picker), so that is the seat the rule patches: connect first jumps to the workspace's existing EMPTY draft (a blank session whose composer carries no unsent text) and only mints a fresh durable session (session.create persists the Session entity host-side) when every draft is occupied. The mint path deliberately stays the stock method — its per-workspace in-flight dedupe collapses a rapid double-click into ONE mint. Typed drafts stay put as their own chats; empty placeholders never multiply — from the button, the folder +, Ctrl+Alt+N, the picker, and the boot alike. The stock target policy is preserved: explicit workspace → current session's workspace → recent workspace; no workspace at all still clears into the pure New Session view. (The stock method, by contrast, reused the workspace's blank session regardless of typed text — one empty chat per workspace, silently discarding the draft you were writing.)
  2. Drafts as tree rows (the v0.2 model). The stock tree hides blank sessions other than the current one, so the plugin overlays the data instead of the renderer: sessions.list.getSnapshot is shadowed on the live store object (identity-stable, HMR-safe) to project every blank non-subagent session with blank: false and a draft title. The stock tree then renders each draft as a first-class row under its workspace — creation time in the trailing cell, click to open. The first sent message flips blank on the host and the row becomes an ordinary chat (full ⋯ menu included), untouched by the overlay. The same overlay also neutralizes connectWorkspace's internal blank-reuse scan (it reads the same list), which is what keeps the stock mint path from resurrecting an old blank when the patched connect decides a mint is due — the picker, the boot selection, and the button all follow the same empty-draft rule (see 1).
  3. One affordance: ×. A draft is a placeholder, not a chat — Rename/Fork/Archive are chat verbs, so the stock ⋯ menu is muted on draft rows. The only trailing control is a × in the ⋯'s own hover cell: hidden until the row is hovered, gray, 16px like the ⋯, and one click discards the draft (workspace archive — the row disappears, the session log remains). After the first sent message the row graduates into an ordinary chat and gets its full ⋯ menu back.
  4. Live preview titles. A draft's row title is its unsent composer text (Telegram-style, whitespace-collapsed, 60 chars), read live through conversation.input and mirrored to localStorage so previews survive reloads; an empty composer shows the localized *New Session*.
  5. Visual draft identity. Draft rows get a gray title (theme-aware design token — gray-next-to-white in dark, muted-next-to-black in light) and a pencil icon in the row's empty status slot, painted by a MutationObserver marker that identifies rows by their session id (resolved through the row's React fiber — never by text, which can collide with a graduated chat's title); a text-prefix match remains only as the fallback for runtime shapes without a reachable fiber. Purely cosmetic and self-healing: if the DOM shape drifts, the rows keep working and only lose the tint (in the flat "In one list" view the slot is absent, so flat rows keep the gray tint without the icon).
  6. Zero core edits. Instance-level property shadowing guarded by Symbol.for markers (idempotent across HMR), restored on plugin unload, falling back to the stock behavior on any synchronous failure. No harness files are modified — install the plugin and it works.

Install

dsh plugin --profile web add link:/path/to/dsh-session-drafts
# or from a published copy:
dsh plugin --profile web add @ne-ilyxa/dsh-session-drafts

Then restart the DSH web host (a profile boot composes the client bundle into the boot graph; hot activation is not attempted by this plugin).

Release channels

  • npm — @ne-ilyxa/dsh-session-drafts; published manually by the maintainer (npm login && npm publish --access public — prepack builds the package). CI never touches the registry.
  • Prebuilt tarball — pushing a v* tag runs release.yml: checks → pnpm pack → dsh-session-drafts.tgz attached to the GitHub Release. Installable without npm and without pnpm's allowBuilds build approval; this is the artifact storefronts prefer.

Keyboard shortcuts

ShortcutAction
Ctrl+Alt+NNew Session from anywhere — same rule as the button: jump to the empty draft, mint only when all are occupied (layout-independent — matches the physical KeyN, Russian layouts included)

(The v0.1 Ctrl+Alt+D popover toggle died with the popover.)

Verify it works

  1. With an empty draft under the workspace, click New Session — you land on that empty draft; nothing new is created (empty placeholders never stack).
  2. Type something in it and click New Session again — now a fresh draft is minted and selected; the typed one stays in the tree, retitled to your unsent text. Refresh the page — everything is still there.
  3. Hover a draft row — a gray × appears where other rows have ⋯; click it to discard the draft. Send a message in one and it graduates into an ordinary chat row (⋯ menu back).
  4. Host truth: a mint happens only when it should — sessions survive a page refresh and the host restart.

Screenshots

The plugin in the DSH web UI — drafts living in the sidebar tree:

Drafts in the DSH sidebar

Working with drafts

Development

pnpm install
pnpm run check     # typecheck + build + node --test tests/*.test.mjs
pnpm run build     # host no-op + browser bundle (lib/client.js, module-loader wrapped)
pnpm test:e2e      # full UI flow on an isolated DSH host (needs a harness checkout + Chrome)
node scripts/capture-screens.mjs   # re-shoot assets/drafts-*.png against a live isolated host

The E2E smoke boots a throwaway DSH web host (its own DSH_HOME scratch profile with this checkout installed), drives the real UI in headless Chrome, and asserts host-side session truth plus the tree DOM. It skips with exit 0 when the environment is missing — configure via E2E_DSH_ROOT (harness checkout, default /home/ilya/deepseek-harness) and CHROME_PATH (default /usr/bin/google-chrome).

Layout:

  • src/index.ts — host half, a deliberate no-op (the package must be a loadable Profile Bundle; all behavior is browser-side).
  • src/client/index.tsx — browser half: the startSession patch, the sessions.list draft projection (projectDraftList), the live preview mirror, the DOM row marker, the hotkey, zh/en dictionaries. No React, no slots — the stock tree renders the drafts.
  • tests/ — pure-logic tests over the built bundle (VM-loaded) + package-layout guards; tests/e2e/ — the isolated-host UI smoke.

Compatibility

  • DSH client runtime 0.1.0-rc.8-era service shapes (workspaces.startSession, sessions.list, sessions.create, conversation.input).
  • The patches degrade loudly-but-safely: if the runtime shape ever drifts, a console warning fires and the corresponding piece stays stock.

License

BSD-3-Clause © ne-ilyxa

使用前核对

安装步骤、兼容版本与授权范围以原项目当前文档为准。Stars 和评分是快照中的导航信号。

安装与排错 · 项目问题反馈

同类项目