🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

会话续接 itchenshi/dsh-gui-last-session

DeepSeek Harness
itchenshi37 天前有提交已提供中文文档扫描:含敏感能力

重启后自动回到上次停留的会话

29.9/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/9/26 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add itchenshi/dsh-gui-last-session
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · chat
装得上吗
本站已真实安装成功
非静态推断
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 37 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件发起外部网络请求
查看扫描证据(共 7 处,展示前 7 条)
  • 读取本地文件
    lib/index.js:64
    raw = await readFile(lastSessionFile(home), 'utf8')
  • 写入本地文件
    lib/index.js:91
    await mkdir(dirname(file), { recursive: true })
  • 写入本地文件
    lib/index.js:97
    await writeFile(tmp, payload, 'utf8')
  • 写入本地文件
    lib/index.js:98
    await rename(tmp, file)
  • 发起网络请求
    client/client.js:75
    const res = await fetch(POINTER_PATH, { headers: { accept: 'application/json' } })
  • 发起网络请求
    client/client.js:93
    fetch(REPORT_PATH, {
  • 发起网络请求
    client/client.js:107
    await fetch(POINTER_PATH, {
扫描于 2026/10/31(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 重启恢复上次会话

DeepSeek Harness 插件:重启后重新打开你上次的会话,无需给引擎文件打补丁

README

由 DeepSeek 最新模型翻译生成
dsh-gui-last-session ! 这是 DSH Ready GUI 的组成部分之一 —— GUI 开箱内置四个插件,勾选即用。 也可单独装到任何 DSH 宿主里(见下方「装上就能用」)。 GUI:https://github.com/itchenshi/dsh-ready-gui 重启 DeepSeek Harness(DSH)之后,自动回到你上一次待着的那个会话 —— 不用再一层层翻历史。 装上就能用 - 用 DSH Ready GUI(推荐):插件随 GUI 内置,而且是默认开启的 —— 装好 GUI 就已经在用了。 要关掉就在设置窗口 → 第三方插件里取消勾选。 - 其它 DSH 宿主(dsh web / CLI)—— 两条路都行,任选一条: 推荐:直接从 GitHub 装(记进 profile,之后可跟着更新) dsh plugin --profile web add github:itchenshi/dsh-gui-last-session 备选:从本仓库 Release 的 tarball 装(网络受限连不上 github.com 时用这条)
展开完整文档(README 剩余 1 节)
dsh-gui-last-session

!

这是 DSH Ready GUI 的组成部分之一 —— GUI 开箱内置四个插件,勾选即用。
也可单独装到任何 DSH 宿主里(见下方「装上就能用」)。
GUI:https://github.com/itchenshi/dsh-ready-gui

重启 DeepSeek Harness(DSH)之后,自动回到你上一次待着的那个会话 —— 不用再一层层翻历史。

装上就能用

- 用 DSH Ready GUI(推荐):插件随 GUI 内置,而且是默认开启的 —— 装好 GUI 就已经在用了。
要关掉就在设置窗口 → 第三方插件里取消勾选。
- 其它 DSH 宿主(dsh web / CLI)—— 两条路都行,任选一条:

推荐:直接从 GitHub 装(记进 profile,之后可跟着更新)
dsh plugin --profile web add github:itchenshi/dsh-gui-last-session

备选:从本仓库 Release 的 tarball 装(网络受限连不上 github.com 时用这条)
dsh plugin --profile web add https://github.com/itchenshi/dsh-gui-last-session/releases/download/v0.1.2/dsh-gui-last-session-0.1.2.tgz

两条命令装到的都是这个仓库的完整内容(含 cordis.patch.yml),装完不需要额外配置。

npm 上暂时没有这个包:注册账号那一环走不通(www.npmjs.com 返回 Cloudflare 托管挑战),包发不
出去。所以现在只能按上面两种方式装。等注册通了会照常发布。

它替你解决什么

原来的实现直接改引擎文件:重写 node_modules/@deepseek-ai/dsh-client-ui-conversation/lib/client.js,靠匹配引擎源码文本找插入点,并用一个精确的引擎版本号做门禁。于是:

| 失效方式 | 原因 |
| 版本门禁 | 引擎版本不是它编写时针对的那一个,补丁就拒绝应用 |
| 锚点漂移 | 插入点靠匹配字面源码行找到,重新构建 / 改名 / 重新格式化都会让它失效 |
| 静默降级 | 失败时只记一行日志,功能就这么没了,界面上没有任何错误 |
| 重装即丢失 | 重装引擎会把补丁整个抹掉 |

现在它是一个插件:住在自己的包里,通过引擎公开的服务契约(ctx.sessions)对话,所以引擎更新不再会删掉这个功能;契约真的变了,引擎会大声报错,而不是悄悄关掉它。

行为细节

有两处很关键,都有测试覆盖:

1. 引擎启动时的空白会话永远不会被记录。 页面加载时引擎自己会导航到一个工作区,并可能创建/选中一个空会话;要是记下它,下次启动就会去续接一个空对话。两道防线:
- 记录在「续接尝试落定(或 4 秒兜底定时器触发)」之前一直未启用,所以引擎启动导航发生时插件还没开始监听;
- 即便已启用,标记 blank: true 的行也永远不记。

2. 续接会等目标变成可寻址的。 会话列表是页面挂载之后才从网络到的;对未知 id 调 open() 会失败,所以插件每 150ms 轮询一次列表快照(上限约 30 秒),等那一行出现再选中它。

尽力而为:如果记住的会话已被删除,插件安静放弃,把引擎自己的启动行为留在原地。

配置(cordis.patch.yml 的行 config,全部可选)

- insert:
- id: gui-last-session
name: dsh-gui-last-session
config:
enabled: true # 总开关 quiet: false # true = 激活时不记任何日志

想在不改包的前提下覆盖某个 profile 的配置,就在该 profile 自己的 cordis.patch.yml 里加一条 id 相同的行(它会整体替换 config,所以每个键都要写全)。

权限与边界(给会静态扫描的商城看的)

- 运行依赖:无。 只用 Node 内建模块(node:fs/promises、node:crypto、node:path、node:os)。
- 文件:恰好一个。 宿主半边在 /last-session.json 维护一份很小的指针文档,原子写入(唯一临时名 + rename),所以崩溃不会留下半个文件。它只记一个 session id,别的什么都不记。
- 本机路由:一条。 宿主注册唯一一条面向页面的路由,页面半边用它读写指针;它走引擎的信任围栏(Host 白名单 + 浏览器会话 cookie),围栏拿不到时失败即关闭。
- 对外网络:没有。 唯一的 fetch 是发往上面那条本地路由的同源请求。
- 凭据 / 命令 / 原生制品 / 生命周期脚本:无。
- 失败边界: 指针缺失、读不出来或损坏,都按「没有可续接的东西」处理 —— 记一条日志,启动照常落在普通界面上。绝不阻断引擎启动;卸载即恢复原生行为,除了那一个文件之外不留残留状态。

HTTP 接口

GET /gui-last-session -> { sessionId: string | null, updatedAt?: number }
POST /gui-last-session -> { ok: true, sessionId, updatedAt }
body: { "sessionId": "session-..." }

两个方向都用 /^session-[A-Za-z0-9_-]{4,200}$/ 校验 id;POST 带了别的内容会被 400 拒绝,文件保持原样。这条路由受信任围栏保护,所以裸 curl 会得到 401 —— 要手工调用,先用 dsh web 打印的 URL 打开一次拿到会话 cookie,再带上:

curl -X POST http://127.0.0.1:/gui-last-session \
-H 'content-type: application/json' \
-H 'cookie: ' \
-d '{"sessionId":"session-..."}'

两部分构成

| 部分 | 文件 | 运行在 | 职责 |
| 宿主 | lib/index.js | Node | 把指针原子写进 $DSH_HOME/last-session.json,并提供一条很小的 JSON 路由 |
| 页面 | client/client.js | 浏览器 | 记录当前会话;加载时重新打开已存下的那一个 |

页面半边是手写的、无依赖的 bundle,没有构建步骤也没有打包器。引擎的客户端模块系统不接受普通 ESM:bundle 必须注册一个惰性的 CJS 工厂(window.__ModuleLoader__.load({ id, factory }),id 必须等于包名),所有副作用都放在工厂闭包里、物化时才运行。两套 inject 别搞混:package.json 的 dsh.client.inject 写的是包名(决定浏览器模块图的加载顺序),bundle 工厂导出的 inject 写的是
服务名(如 ['sessions'])。两者都必需 —— 漏掉导出的 inject,页面一加载 apply() 里取
ctx.sessions 就会抛 cannot get property "sessions" without inject。

tests/test.mjs 正是按这个契约加载 bundle 的,所以「退回普通 ESM」或「漏了导出的 inject」都会让测试失败,而不是留到浏览器里才炸。

开发

node --check lib/index.js
npm test # 本地行为测试(不联网、不需要引擎)

兼容性:插件依赖的是公开服务契约,不是引擎版本号,所以有意不做版本门禁(版本区间在这里也不合适:npm semver 会把预发布版排除在 >=0.1.2-0 <0.2.0 这类区间之外,反而误杀 0.1.5-rc.1)。
已在 dsh 0.1.5-rc.1 上端到端验证:装上后引擎能启动、GET /gui-last-session 返回已存下的指针、 dsh-gui-last-session/client.js 随启动载荷下发(HTTP 200)。

本包是零依赖的普通 JavaScript。

许可

MIT
预览分享卡片长什么样 ↓itchenshi/dsh-gui-last-session
分享 · DeepSeek Harness Hub
itchenshi/dsh-gui-last-session

重启后自动回到上次停留的会话

回到顶部