dsh-session-manager 0.1.2 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,129 +1,131 @@
1
- # dsh-session-manager — conversation manager (delete + archive)
1
+ # dsh-session-manager — conversation manager for DeepSeek Harness
2
2
 
3
- [中文](README.zh.md) | English
3
+ English | [中文](README.zh.md)
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/dsh-session-manager)](https://www.npmjs.com/package/dsh-session-manager)
6
- [![GitHub](https://img.shields.io/badge/GitHub-repo-blue)](https://github.com/hkkz9522/dsh-session-manager)
6
+ [![GitHub](https://img.shields.io/badge/GitHub-repository-blue)](https://github.com/hkkz9522/dsh-session-manager)
7
7
  [![CI](https://github.com/hkkz9522/dsh-session-manager/actions/workflows/ci.yml/badge.svg)](https://github.com/hkkz9522/dsh-session-manager/actions/workflows/ci.yml)
8
8
 
9
- Adds two capabilities that are missing from DeepSeek Harness Web:
10
-
11
- 1. **Delete conversations** (with an explicit confirmation dialog): physically deletes a
12
- session — stops and disposes its agent, detaches the session store entry (every tab
13
- drops the row), removes the JSONL directory from disk, and cleans up workspace
14
- accounting and the archive set.
15
- 2. **Archive management**: archive (`workspace.archiveSession`, built in) and
16
- **unarchive** (missing in rc.6 — this plugin implements it on the host side through
17
- the workspace registry's own persistence queue, with
18
- `host/archived-sessions-changed` frames keeping every client in sync).
9
+ A DeepSeek Harness (DSH) plugin for managing conversations safely from the Web UI.
10
+ It adds archive management, permanent deletion, cross-workspace moves, and
11
+ per-conversation Agent preset migration.
19
12
 
20
13
  ## Features
21
14
 
22
- - 🗑 **Delete sessions**: a "Delete session…" button in the conversation header plus a
23
- per-row delete in the manager panel — every path requires confirmation.
24
- - 📦 **Archive / unarchive**: header button + per-row actions in the panel.
25
- - 📋 **Session manager panel** (sidebar footer entry): filter by All / Active / Archived
26
- (archived sessions are invisible in the sidebar — the panel is where you find them
27
- again), with per-row Open / Archive / Unarchive / Delete.
28
- - 🏷 Status badges: archived / running / current; relative time and workspace directory.
29
- - ⚠️ The delete dialog shows the session title and an "irreversible" warning; for a
30
- running session it warns that deletion will interrupt it immediately.
31
-
32
- ## Where the UI lives
33
-
34
- | Location | Content |
35
- |---|---|
36
- | Conversation header (next to the session title) | "Archive / Unarchive" and "Delete session…" (red, confirmation dialog) buttons |
37
- | Sidebar footer | "会话管理" button that opens the full manager panel |
15
+ - **Archive and unarchive** conversations.
16
+ - **Delete conversations** with an explicit irreversible-action confirmation.
17
+ - **Move to workspace** while preserving conversation history, title, archive state,
18
+ and derived-session relationships. The session's working directory is updated to
19
+ the target workspace.
20
+ - **Migrate Agent preset for one conversation at a time.** This repairs a conversation
21
+ when its original preset was renamed or removed.
22
+ - **Session manager** in the sidebar for browsing active and archived conversations,
23
+ with per-row Open, Archive/Unarchive, Move, Delete, and Migrate preset actions.
24
+ - Header actions for the current conversation: Archive/Unarchive, Move to workspace,
25
+ and a red Delete conversation action.
26
+
27
+ ## Where to find the UI
28
+
29
+ - **Conversation header:** archive/unarchive, move to workspace, and delete.
30
+ - **Sidebar footer → Session manager:** browse all conversations, including archived
31
+ ones, and perform actions for an individual conversation.
32
+ - **Session manager row → Migrate preset:** change the Agent preset for that one
33
+ conversation only. There is no bulk migration action.
34
+
35
+ ## Agent preset migration
36
+
37
+ Use this when a conversation can no longer resume because its original preset no
38
+ longer exists, for example after removing a custom preset such as
39
+ `router-standard`.
40
+
41
+ 1. Open **Session manager**.
42
+ 2. Locate the conversation and select **Migrate preset**.
43
+ 3. Choose one of the currently available target presets and confirm.
44
+
45
+ The plugin determines the conversation's effective preset from its latest
46
+ `agent-preset/selected` event when present; otherwise it uses the session header.
47
+ It safely updates the relevant stored value, releases any live persistence owner,
48
+ and refreshes the session list. If the migrated conversation is open, reopen it
49
+ before continuing the chat.
50
+
51
+ > A preset migration changes conversation metadata only. It does not alter message
52
+ > history, files, or the selected workspace.
38
53
 
39
54
  ## Install
40
55
 
41
- ### From npm (recommended)
56
+ ### From npm
42
57
 
43
58
  ```powershell
44
- dsh plugin --profile web add dsh-session-manager
59
+ dsh plugin --profile web add npm:dsh-session-manager
45
60
  ```
46
61
 
47
- Restart the web app to activate (profile bundle auto-assembles; `lib/` is the runtime
48
- artifact, no build step).
49
-
50
- ### From GitHub (alternative)
62
+ ### From GitHub
51
63
 
52
64
  ```powershell
53
65
  dsh plugin --profile web add github:hkkz9522/dsh-session-manager
54
66
  ```
55
67
 
68
+ Restart DSH Web after installation. If a browser still has an older client bundle,
69
+ perform a hard refresh (`Ctrl+Shift+R`).
70
+
56
71
  ### Local development / runtime injection
57
72
 
58
- After cloning, inject in a web session that has
59
- [dsh-super-injector](https://github.com/yjh051108/dsh-super-injector) resident
60
- (activates immediately, no restart):
73
+ ```text
74
+ dev_inject_plugin {"dir": "<absolute path to this repository>"}
75
+ ```
76
+
77
+ ## HTTP API
78
+
79
+ The Web UI uses the following local endpoints. They are primarily useful for
80
+ integration and diagnostics.
81
+
82
+ ```text
83
+ POST /session-manager/api/delete { sessionId }
84
+ POST /session-manager/api/unarchive { sessionId }
85
+ GET /session-manager/api/workspaces
86
+ POST /session-manager/api/move { sessionId, targetWorkspaceId }
87
+ GET /session-manager/api/preset-scan?sessionId=<sessionId>
88
+ POST /session-manager/api/preset-migrate { sessionId, toPreset }
89
+ ```
90
+
91
+ Example: migrate one conversation to `standard`.
61
92
 
93
+ ```bash
94
+ curl -s -X POST http://127.0.0.1:3080/session-manager/api/preset-migrate \
95
+ -H 'content-type: application/json' \
96
+ -d '{"sessionId":"session-...","toPreset":"standard"}'
62
97
  ```
63
- dev_inject_plugin {"dir": "<absolute path to the repo>"}
98
+
99
+ ## Safety and behavior
100
+
101
+ - **Deletion is permanent.** The confirmation dialog is intentional.
102
+ - Moving a running conversation interrupts and closes it first, then refreshes the
103
+ sidebar automatically. Open it from the target workspace to continue.
104
+ - Moving a conversation changes its stored `cwd`; subsequent tool calls run in the
105
+ target workspace.
106
+ - Subagent and transient blank-session placeholders are excluded from destructive
107
+ or migration operations.
108
+ - File rewrites use temporary files and atomic replacement where supported to avoid
109
+ partial session artifacts.
110
+
111
+ ## Compatibility and development
112
+
113
+ - The plugin is a Cordis plugin and declares `cordis >=4.0.0-rc <5` as a peer
114
+ dependency.
115
+ - `lib/index.js` is the host-side ESM plugin and `lib/client.js` is the Web client
116
+ bundle. There is no build step.
117
+ - Before submitting changes, run:
118
+
119
+ ```powershell
120
+ node --check lib/client.js
121
+ node --check lib/index.js
122
+ git diff --check
123
+ node scripts/smoke-test.mjs
124
+ npm pack --dry-run
64
125
  ```
65
126
 
66
- ## Uninstall
67
-
68
- - Installed via `dsh plugin add`: remove the entry from `dsh.profile.bundles` and
69
- `dependencies` in `~/.dsh/profiles/web/package.json`, then restart.
70
- - Installed via runtime injection: `dev_uninject_plugin {"name": "dsh-session-manager"}`
71
-
72
- ## Compatibility (DSH upgrades)
73
-
74
- - **Client UI** uses only the official plugin surface (slot contracts
75
- `conversation.session.header.actions` / `sidebar.footer.action`, the standard toolkit
76
- `useSessions` / `useWorkspaces` / `t`, locale, client bundle format) — upgrades are
77
- very likely seamless.
78
- - **Host side** imports no `@deepseek-ai` package (only Node built-ins), so it never
79
- fails at load time after an upgrade. Delete/unarchive rely on a few internals that
80
- rc.6 does not expose publicly (accessed defensively); if a future version refactors
81
- them, you get a runtime error rather than a crash — adapt per the error message.
82
- - `peerDependencies` declares only the `cordis` range; no hard-coded DSH version.
83
- - After an upgrade, self-check once: create a blank session and delete it (end-to-end,
84
- 30 s), or run `node scripts/smoke-test.mjs` (read-only smoke checks of the two host
85
- endpoints; touches no real session).
86
-
87
- ## Development & maintenance
88
-
89
- - **No build step**: `lib/` is the runtime artifact (host is ESM; client is a hand-written
90
- loader-factory bundle).
91
- - **Smoke test**: `node scripts/smoke-test.mjs [baseUrl]` (needs a running dsh web).
92
- - **CI** (`.github/workflows/ci.yml`): `node --check` on both files + `npm pack --dry-run`
93
- content assertion.
94
- - Changes are tracked in [CHANGELOG.md](./CHANGELOG.md).
95
-
96
- ## Implementation notes
97
-
98
- - **Host** (`lib/index.js`): a cordis plugin injecting
99
- `webServer / workspaceRegistry / sessions / agents / sessionPersistence`, exposing two
100
- HTTP endpoints:
101
- - `POST /session-manager/api/delete { sessionId }`
102
- - `POST /session-manager/api/unarchive { sessionId }`
103
- - **Client** (`lib/client.js`): a loader-factory bundle registering two slots:
104
- - `conversation.session.header.actions` (per-session actions + delete confirmation)
105
- - `sidebar.footer.action` (manager panel entry)
106
-
107
- Delete of a live session: `agent.cancel` (interrupt) → `agent.scope.dispose` (quietly
108
- dispose the agent fiber, 3 s cap) → drop the zombie entry from the agents registry →
109
- `sessions.flush` → detach the session store entry (`session/disposed` → all clients
110
- remove the row) → workspace accounting cleanup → archive-set cleanup → remove the on-disk
111
- directory.
112
-
113
- ## Risks & limitations
114
-
115
- - Deletion is irreversible (physical file removal); the UI always asks for confirmation.
116
- - Deleting a live session touches host internals (session store / agent registry
117
- instance fields); a future DSH refactor may require adapting the plugin (all access is
118
- defensive).
119
- - An archived session whose files were removed externally will just reappear in the list
120
- on unarchive (the row may not display).
127
+ See [CHANGELOG.md](CHANGELOG.md) for release history.
121
128
 
122
129
  ## License
123
130
 
124
- [MIT](./LICENSE)
125
-
126
- Free to use, modify, copy, and distribute (including commercially) as long as the
127
- copyright notice and this license text are retained. The project is provided "as is",
128
- without warranty of any kind, express or implied. See [LICENSE](./LICENSE) for the full
129
- terms.
131
+ [MIT](LICENSE)
package/README.zh.md CHANGED
@@ -1,115 +1,117 @@
1
- # dsh-session-manager — 会话管理器(删除 + 归档管理)
1
+ # dsh-session-manager — DeepSeek Harness 会话管理器
2
2
 
3
3
  [English](README.md) | 中文
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/dsh-session-manager)](https://www.npmjs.com/package/dsh-session-manager)
6
- [![GitHub](https://img.shields.io/badge/GitHub-repo-blue)](https://github.com/hkkz9522/dsh-session-manager)
6
+ [![GitHub](https://img.shields.io/badge/GitHub-仓库-blue)](https://github.com/hkkz9522/dsh-session-manager)
7
7
  [![CI](https://github.com/hkkz9522/dsh-session-manager/actions/workflows/ci.yml/badge.svg)](https://github.com/hkkz9522/dsh-session-manager/actions/workflows/ci.yml)
8
8
 
9
- 为 DeepSeek Harness Web 增加两件官方缺失的能力:
9
+ 用于管理 DeepSeek Harness(DSH)Web 对话的插件。它提供归档管理、永久删除、
10
+ 跨工作区移动,以及按单条对话迁移 Agent 预设的能力。
10
11
 
11
- 1. **删除对话**(删除前二次确认):物理删除会话 —— 停止并销毁对应 agent、清空
12
- 会话存储条目(所有标签页同步移除该行)、删除磁盘上的 JSONL 会话目录、
13
- 清理工作区记账与归档集合。
14
- 2. **归档管理**:移入归档(官方已有 `workspace.archiveSession`)与 **移出归档**
15
- (官方 rc.6 没有 unarchive API,本插件在 host 端补齐,走 workspace registry
16
- 自己的持久化队列,`host/archived-sessions-changed` 帧自动同步所有客户端)。
12
+ ## 功能
17
13
 
18
- ## 特性
19
-
20
- - 🗑 **删除会话**:会话头部「删除会话…」按钮 + 管理面板每行删除,全部带二次确认
21
- - 📦 **归档 / 移出归档**:会话头部按钮 + 管理面板逐行操作
22
- - 📋 **会话管理面板**(侧边栏底部入口):全部 / 未归档 / 已归档 过滤(已归档会话
23
- 侧边栏默认不可见,只有这里能找回),每行「打开 / 归档 / 移出归档 / 删除」
24
- - 🏷 状态徽标:已归档 / 运行中 / 当前会话;相对时间与工作区目录
25
- - ⚠️ 删除确认弹窗展示会话标题与“不可撤销”警告;会话运行中会提示“删除将立即中断它”
14
+ - **归档 / 移出归档**对话。
15
+ - **删除会话**:带不可逆操作的二次确认。
16
+ - **移动至工作区**:保留历史、标题、归档状态和派生会话关系,同时把会话的
17
+ 工作目录更新为目标工作区。
18
+ - **单条对话迁移 Agent 预设**:当原预设被改名或删除,导致会话无法恢复时,可
19
+ 单独修复该对话。
20
+ - **会话管理窗口**:在侧边栏中浏览未归档和已归档会话,并对每一行执行打开、
21
+ 归档 / 移出归档、移动、删除、迁移预设。
22
+ - 当前对话标题区域提供归档 / 移出归档、移动至工作区和红色的删除会话按钮。
26
23
 
27
24
  ## UI 入口
28
25
 
29
- | 位置 | 内容 |
30
- |---|---|
31
- | 会话头部(当前会话标题旁) | 「归档 / 移出归档」与「删除会话…」(红色,二次确认弹窗)两个文字按钮 |
32
- | 侧边栏底部 | 「会话管理」按钮:打开完整管理面板 |
26
+ - **对话标题右侧**:归档 / 移出归档、移动至工作区、删除会话。
27
+ - **侧边栏底部 → 会话管理**:查看全部会话(含归档会话)并操作每一条会话。
28
+ - **会话管理的会话行 → 迁移预设**:只迁移当前这一条会话;不再提供批量迁移。
29
+
30
+ ## Agent 预设迁移
31
+
32
+ 当对话无法恢复,且报错表明原 Agent 预设不存在时(例如删掉了
33
+ `router-standard`),可以使用单条迁移功能。
34
+
35
+ 1. 打开**会话管理**。
36
+ 2. 找到目标对话,点击**迁移预设**。
37
+ 3. 从当前可用的预设中选择目标预设并确认。
38
+
39
+ 插件会优先读取最后一条 `agent-preset/selected` 事件中的有效预设;若不存在该
40
+ 事件,则读取会话 header 中的预设。迁移时会安全改写对应的持久化记录、释放可能残留
41
+ 的 live persistence owner,并刷新会话列表。若该会话当前打开,请在迁移后重新打开
42
+ 再继续对话。
43
+
44
+ > 迁移预设只会修改会话元数据,不会改写历史消息、文件或当前工作区。
33
45
 
34
46
  ## 安装
35
47
 
36
- ### 从 npm 安装(推荐)
48
+ ### 从 npm 安装
37
49
 
38
50
  ```powershell
39
- dsh plugin --profile web add dsh-session-manager
51
+ dsh plugin --profile web add npm:dsh-session-manager
40
52
  ```
41
53
 
42
- 重启 web 后生效(profile bundle 自动装配,`lib/` 即运行时产物,无需构建)。
43
-
44
- ### 从 GitHub 安装(备用)
54
+ ### 从 GitHub 安装
45
55
 
46
56
  ```powershell
47
57
  dsh plugin --profile web add github:hkkz9522/dsh-session-manager
48
58
  ```
49
59
 
50
- ### 本地开发 / 运行时注入
60
+ 安装后重启 DSH Web。若浏览器仍加载旧的客户端代码,请使用 `Ctrl+Shift+R` 强制刷新。
51
61
 
52
- 克隆本仓库后,在已常驻 [dsh-super-injector](https://github.com/yjh051108/dsh-super-injector)
53
- 的 web 会话中注入(注入即生效,免重启):
62
+ ### 本地开发 / 运行时注入
54
63
 
55
- ```
56
- dev_inject_plugin {"dir": "<仓库目录绝对路径>"}
64
+ ```text
65
+ dev_inject_plugin {"dir": "<本仓库的绝对路径>"}
57
66
  ```
58
67
 
59
- ## 卸载
68
+ ## HTTP API
60
69
 
61
- - 若通过 `dsh plugin add` 装配:从 `~/.dsh/profiles/web/package.json` 的
62
- `dependencies` 与 `dsh.profile.bundles` 中移除对应条目,重启。
63
- - 若通过运行时注入安装:`dev_uninject_plugin {"name": "dsh-session-manager"}`
70
+ 以下本地接口供 Web UI 使用,也可用于集成和排查:
64
71
 
65
- ## 兼容性(升级 DSH 后)
72
+ ```text
73
+ POST /session-manager/api/delete { sessionId }
74
+ POST /session-manager/api/unarchive { sessionId }
75
+ GET /session-manager/api/workspaces
76
+ POST /session-manager/api/move { sessionId, targetWorkspaceId }
77
+ GET /session-manager/api/preset-scan?sessionId=<sessionId>
78
+ POST /session-manager/api/preset-migrate { sessionId, toPreset }
79
+ ```
66
80
 
67
- - **客户端 UI** 只使用官方插件面(slot 契约 `conversation.session.header.actions` /
68
- `sidebar.footer.action`、标准工具包 `useSessions` / `useWorkspaces` / `t`、locale、
69
- client bundle 格式),升级大概率无缝。
70
- - **host 端** 不 import 任何 `@deepseek-ai` 包(仅 node 内置模块),升级不会在
71
- 加载期失败;删除 / 移出归档用到了少数 rc.6 未公开的内部结构(已做防御性访问),
72
- 若未来版本重构这些内部实现,会表现为运行时操作报错而非崩溃,按报错适配即可。
73
- - `peerDependencies` 仅声明 `cordis` 范围,不硬编码 DSH 版本。
74
- - 建议升级后自检一次:新建空白会话并删除(端到端 30 秒),或运行
75
- `node scripts/smoke-test.mjs`(对两个 host 端点的只读冒烟检查,不触碰真实会话)。
81
+ 示例:将一条对话迁移到 `standard` 预设。
76
82
 
77
- ## 开发与维护
83
+ ```bash
84
+ curl -s -X POST http://127.0.0.1:3080/session-manager/api/preset-migrate \
85
+ -H 'content-type: application/json' \
86
+ -d '{"sessionId":"session-...","toPreset":"standard"}'
87
+ ```
78
88
 
79
- - **无构建步骤**:`lib/` 即运行时产物(host 为 ESM,client 为 loader factory 格式手写 bundle)。
80
- - **冒烟测试**:`node scripts/smoke-test.mjs [baseUrl]`(需运行中的 dsh web)。
81
- - **CI**(`.github/workflows/ci.yml`):`node --check` 两个文件 + `npm pack --dry-run`
82
- 校验发布包内容。
83
- - 变更记录见 [CHANGELOG.md](./CHANGELOG.md)。
89
+ ## 安全与行为说明
84
90
 
85
- ## 实现说明
91
+ - **删除不可恢复**,因此界面始终要求确认。
92
+ - 移动正在运行的对话时,插件会先中断并关闭该会话,然后自动刷新侧边栏;请在
93
+ 目标工作区重新打开会话后继续。
94
+ - 移动会改写会话保存的 `cwd`,之后的工具调用将在目标工作区执行。
95
+ - subagent 会话和临时空白会话占位不会参与删除、移动或预设迁移。
96
+ - 文件改写使用临时文件和原子替换(环境支持时),避免产生部分写入的会话工件。
86
97
 
87
- - **host 端**(`lib/index.js`):cordis 插件,注入
88
- `webServer / workspaceRegistry / sessions / agents / sessionPersistence`,
89
- 注册两条 HTTP 端点:
90
- - `POST /session-manager/api/delete { sessionId }`
91
- - `POST /session-manager/api/unarchive { sessionId }`
92
- - **client 端**(`lib/client.js`):loader factory 格式手写 bundle(无构建步骤),
93
- 注册两个 slot:
94
- - `conversation.session.header.actions`(每会话操作 + 删除确认)
95
- - `sidebar.footer.action`(会话管理面板入口)
98
+ ## 兼容性与开发
96
99
 
97
- 删除 live 会话的顺序:`agent.cancel`(中断运行)→ `agent.scope.dispose`(安静销毁
98
- agent fiber,3s 上限)→ 从 agents 注册表移除僵尸条目 → `sessions.flush` → 会话
99
- store 条目 detach(触发 `session/disposed` → 各端移除行)→ 工作区记账清理 →
100
- 归档集合清理 → 删除磁盘目录。
100
+ - 本插件是 Cordis 插件,声明的 peer dependency 为 `cordis >=4.0.0-rc <5`。
101
+ - `lib/index.js` 是 host 端 ESM 插件,`lib/client.js` 是 Web 客户端 bundle,
102
+ 无需构建步骤。
103
+ - 提交修改前请运行:
101
104
 
102
- ## 风险与边界
105
+ ```powershell
106
+ node --check lib/client.js
107
+ node --check lib/index.js
108
+ git diff --check
109
+ node scripts/smoke-test.mjs
110
+ npm pack --dry-run
111
+ ```
103
112
 
104
- - 删除是不可逆操作(文件物理删除),UI 已做二次确认。
105
- - live 会话删除依赖 host 内部结构(会话 store / agent registry 的实例字段),
106
- 未来 DSH 版本若重构这些内部实现可能需要同步适配(代码均做了防御性访问)。
107
- - 已归档会话若其磁盘文件已被外部删除,移出归档只会把它放回列表(行可能不显示)。
113
+ 发布记录见 [CHANGELOG.md](CHANGELOG.md)。
108
114
 
109
115
  ## 开源许可
110
116
 
111
- 本项目基于 [MIT License](./LICENSE) 开源。
112
-
113
- 你可以自由地使用、修改、复制、分发本项目(包括商业用途),但需保留版权声明与
114
- 本许可文本;项目按“现状”提供,作者不对其适用性、可靠性或特定用途的适配性作任何
115
- 明示或默示的担保。完整条款见 [LICENSE](./LICENSE)。
117
+ [MIT](LICENSE)