DSH 插件:上下文到阈值时生成交接包并切到新会话。已弃用 2026-10-17:换会话整条退役——续航交给 DSH…
33.6/100
综合分
5
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/17 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
自动兼容检查未通过:仓库 package.json 标记 private,未发布到 npm,需从源码安装。以下命令仍可尝试,但可能失败。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add S3K926/dsh-auto-handoff该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:需留意
是什么
dsh 原生插件 · chat
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 15 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
⚠︎ 实装验证未通过(unknown · 2026/10/26) ——可能是验证环境差异,装前建议到 GitHub 仓库确认最近更新与 issue。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查需源码安装仓库 package.json 标记 private,未发布到 npm,需从源码安装
展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✓npm 包dsh-auto-handoff @ 0.2.0
✓Node 引擎未声明 engines.node
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
源码安装时若 pnpm 拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑。
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/28 20:42:58
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
读写/删除本地文件发起外部网络请求
查看扫描证据(共 120 处,展示前 92 条)
- 发起网络请求index.js:340
const response = await fetch(url, { - 写入本地文件index.js:357
mkdirSync(dir, { recursive: true }); - 写入本地文件index.js:358
writeFileSync(join(dir, 'pending.json'), `${JSON.stringify({ - 读取本地文件index.js:545
const data = JSON.parse(readFileSync(join(stateDir, BOOT_TASK_FILE), 'utf8')); - 写入本地文件index.js:556
mkdirSync(stateDir, { recursive: true }); - 删除本地文件index.js:559
try { rmSync(join(stateDir, BOOT_TASK_FILE), { force: true }); } catch { } - 写入本地文件index.js:562
writeFileSync(join(stateDir, BOOT_TASK_FILE), - 读取本地文件index.js:920
if (!existsSync(file)) return false; - 删除本地文件index.js:922
rmSync(file, { force: true }); - 发起网络请求client.js:102
const response = await fetch(ROUTE_PENDING, { headers: { accept: 'application/json' } }); - 发起网络请求client.js:167
await fetch(ROUTE_ACK, { - 发起网络请求client.js:330
await fetch(ROUTE_DRAFT_REPORT, { - 发起网络请求client.js:347
const response = await fetch(ROUTE_PENDING, { headers: { accept: 'application/json' } }); - 发起网络请求client.js:354
await fetch(ROUTE_FIRE_ACK, { method: 'POST' }).catch(() => {}); - 读取本地文件handoff-core.js:88
if (typeof dir !== 'string' || dir.trim() === '' || !existsSync(dir)) return false; - 读取本地文件handoff-core.js:90
if (!statSync(dir).isDirectory()) return false; - 读取本地文件handoff-core.js:94
return ROOT_MARKERS.every((marker) => existsSync(resolve(join(dir, marker)))); - 读取本地文件handoff-core.js:146
return readFileSync(file, 'utf8').replace(/^ FEFF/, ''); - 读取本地文件handoff-core.js:152
const read = (file) => (existsSync(file) ? readText(file) : null); - 写入本地文件handoff-core.js:339
mkdirSync(dirname(file), { recursive: true }); - 写入本地文件handoff-core.js:342
writeFileSync(tmp, toCRLF(text), 'utf8'); - 写入本地文件handoff-core.js:343
renameSync(tmp, file); - 删除本地文件handoff-core.js:345
try { rmSync(tmp, { force: true }); } catch { } - 读取本地文件handoff-core.js:355
if (!existsSync(file)) return null; - 写入本地文件handoff-core.js:358
mkdirSync(dirname(target), { recursive: true }); - 写入本地文件handoff-core.js:359
writeFileSync(target, readFileSync(file)); - 写入本地文件handoff-state.js:98
mkdirSync(tmpdir(), { recursive: true }); - 写入本地文件handoff-state.js:99
writeFileSync(LOG_FILE, `${text}\n`, { encoding: 'utf8', flag: 'a' }); - 读取本地文件handoff-plan.js:38
const data = JSON.parse(readFileSync(join(stateDir, PRINT_FILE), 'utf8')); - 写入本地文件handoff-plan.js:49
mkdirSync(stateDir, { recursive: true }); - 写入本地文件handoff-plan.js:51
writeFileSync(join(stateDir, PRINT_FILE), `${JSON.stringify({ at: new Date().toISOString(), prints }, null, 2)}\n`, 'utf8'); - 写入本地文件switch-store.js:55
mkdirSync(dir === undefined || dir === null ? pendingDir() : dir, { recursive: true }); - 写入本地文件switch-store.js:56
appendFileSync(logPath(dir), `[${new Date().toISOString()}] ${line}\n`, 'utf8'); - 写入本地文件switch-store.js:79
writeFileSync(tmp, text, 'utf8'); - 写入本地文件switch-store.js:81
renameSync(tmp, file); - 删除本地文件switch-store.js:84
rmSync(tmp, { force: true }); - 读取本地文件switch-store.js:139
const raw = readFileSync(budgetFile(dir), 'utf8'); - 读取本地文件switch-store.js:233
raw = readFileSync(file, 'utf8'); - 写入本地文件switch-store.js:266
mkdirSync(dir === undefined || dir === null ? pendingDir() : dir, { recursive: true }); - 写入本地文件switch-session-selftest.js:158
writeFileSync(file, '{ 这不是 JSON', 'utf8'); - 读取本地文件switch-session-selftest.js:160
const logText1 = readFileSync(logFile, 'utf8'); - 读取本地文件switch-session-selftest.js:167
const logText2 = readFileSync(logFile, 'utf8'); - 删除本地文件switch-session-selftest.js:221
rmSync(budgetFile(dir), { force: true }); - 删除本地文件switch-session-selftest.js:242
rmSync(budgetFile(dir), { force: true }); - 写入本地文件switch-session-selftest.js:274
writeFileSync(budgetFile(dir), '{ 这不是 JSON', 'utf8'); - 写入本地文件switch-session-selftest.js:277
writeFileSync(budgetFile(dir), JSON.stringify({ records: [{ at: Date.now() - 10 * 24 * 60 * 60 * 1000, sourceSession: 'session-old', seq: 1, handoffCh - 删除本地文件switch-session-selftest.js:285
rmSync(budgetFile(dir), { force: true }); - 删除本地文件switch-session-selftest.js:289
rmSync(budgetFile(dir), { force: true }); - 删除本地文件switch-session-selftest.js:315
rmSync(budgetFile(dir), { force: true }); - 删除本地文件switch-session-selftest.js:327
rmSync(budgetFile(dir), { force: true }); - 写入本地文件test-archive-off.mjs:46
mkdirSync(join(root, '生长'), { recursive: true }); - 写入本地文件test-archive-off.mjs:47
writeFileSync(join(root, '日记.md'), DIARY, 'utf8'); - 写入本地文件test-archive-off.mjs:48
writeFileSync(join(root, '生长', '状态.md'), STATE, 'utf8'); - 写入本地文件test-archive-off.mjs:49
writeFileSync(join(root, '生长', '生长记录.md'), GROWTH, 'utf8'); - 读取本地文件test-archive-off.mjs:53
diary: readFileSync(join(root, '日记.md'), 'utf8'), - 读取本地文件test-archive-off.mjs:54
state: readFileSync(join(root, '生长', '状态.md'), 'utf8'), - 读取本地文件test-archive-off.mjs:55
growth: readFileSync(join(root, '生长', '生长记录.md'), 'utf8'), - 删除本地文件递归test-archive-off.mjs:97
rmSync(root1, { recursive: true, force: true }); - 删除本地文件递归test-archive-off.mjs:98
rmSync(root2, { recursive: true, force: true }); - 读取本地文件test-boot-tasks.mjs:34
ok('文件真的落地了', existsSync(file)); - 读取本地文件test-boot-tasks.mjs:36
ok('传空数组会清掉文件', writeBootTasks(dir, []) === true && !existsSync(file)); - 读取本地文件test-boot-tasks.mjs:51
ok('消费后队列文件也被清掉', !existsSync(file)); - 读取本地文件test-boot-tasks.mjs:64
const raw = readFileSync(file, 'utf8'); - 删除本地文件递归test-boot-tasks.mjs:66
rmSync(dir, { recursive: true, force: true }); - 写入本地文件test-fire-now.mjs:49
writeFileSync(file, ''); - 读取本地文件test-fire-now.mjs:52
ok('文件被删掉(不会被下一轮重复举手)', existsSync(file) === false); - 写入本地文件test-fire-now.mjs:56
writeFileSync(file, ''); - 写入本地文件test-fire-now.mjs:58
writeFileSync(file, ''); - 写入本地文件test-fire-now.mjs:61
writeFileSync(file, ''); - 读取本地文件test-fire-now.mjs:64
ok('被挡住时文件照样清掉(避免卡成死循环)', existsSync(file) === false); - 删除本地文件递归test-fire-now.mjs:73
rmSync(dir, { recursive: true, force: true }); - 读取本地文件test-handoff-sandbox.mjs:27
const bytes = (file) => (existsSync(file) ? statSync(file).size : -1); - 读取本地文件test-handoff-sandbox.mjs:27
const bytes = (file) => (existsSync(file) ? statSync(file).size : -1); - 读取本地文件test-handoff-sandbox.mjs:28
const hashOf = (file) => (existsSync(file) ? sha(readFileSync(file, 'utf8')) : '(缺)'); - 读取本地文件test-handoff-sandbox.mjs:28
const hashOf = (file) => (existsSync(file) ? sha(readFileSync(file, 'utf8')) : '(缺)'); - 写入本地文件test-handoff-sandbox.mjs:32
mkdirSync(join(root, '生长'), { recursive: true }); - 写入本地文件test-handoff-sandbox.mjs:33
writeFileSync(join(root, '身份.md'), crlf('# 身份(沙盘假件)\n\n这份档案只活在临时目录里,跑完就删。\n'), 'utf8'); - 写入本地文件test-handoff-sandbox.mjs:34
writeFileSync(join(root, '日记.md'), crlf(DIARY_FIXTURE), 'utf8'); - 写入本地文件test-handoff-sandbox.mjs:35
writeFileSync(join(root, '生长', '状态.md'), crlf(STATE_FIXTURE), 'utf8'); - 写入本地文件test-handoff-sandbox.mjs:36
writeFileSync(join(root, '生长', '生长记录.md'), crlf(GROWTH_FIXTURE), 'utf8'); - 写入本地文件test-handoff-sandbox.mjs:200
mkdirSync(outside, { recursive: true }); - 读取本地文件test-handoff-sandbox.mjs:210
const before = Object.fromEntries(Object.entries(paths).filter(([k]) => k !== 'backups').map(([k, f]) => [k, readFileSync(f, 'utf8')])); - 读取本地文件test-handoff-sandbox.mjs:230
const afterDry = Object.fromEntries(Object.keys(before).map((k) => [k, sha(readFileSync(paths[k], 'utf8'))])); - 请求外部主机sandboxtest-handoff-sandbox.mjs:390
const healthBody = host ? await (await host.routes.get('/api/handoff/health').fetch(new Request('http://sandbox/api/handoff/health'))).json() : {}; - 发起网络请求test-handoff-sandbox.mjs:390
const healthBody = host ? await (await host.routes.get('/api/handoff/health').fetch(new Request('http://sandbox/api/handoff/health'))).json() : {}; - 请求外部主机sandboxtest-handoff-sandbox.mjs:393
const pendingBody = host ? await (await host.routes.get('/api/handoff/pending').fetch(new Request('http://sandbox/api/handoff/pending'))).json() : {}; - 发起网络请求test-handoff-sandbox.mjs:393
const pendingBody = host ? await (await host.routes.get('/api/handoff/pending').fetch(new Request('http://sandbox/api/handoff/pending'))).json() : {}; - 请求外部主机sandboxtest-handoff-sandbox.mjs:395
const ackNoPending = host ? await host.routes.get('/api/handoff/ack').fetch(new Request('http://sandbox/api/handoff/ack', { method: 'POST', body: '{}' - 发起网络请求test-handoff-sandbox.mjs:395
const ackNoPending = host ? await host.routes.get('/api/handoff/ack').fetch(new Request('http://sandbox/api/handoff/ack', { method: 'POST', body: '{}' - 删除本地文件递归test-handoff-sandbox.mjs:476
rmSync(base, { recursive: true, force: true }); - 读取本地文件test-summary-options.mjs:9
const before = (() => { try { return statSync(LOG).size; } catch { return 0; } })(); - 写入本地文件test-summary-options.mjs:51
try { if (before > 0) truncateSync(LOG, before); } catch { }
扫描于 2026/11/1(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
涉及外部主机:sandbox
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- 上下文达阈值自动写档案
- 生成交接包
- 多智能体协作
DeepSeek Harness 插件:多智能体协作(主控/子代理/技能)+ 会话管理 + 会话切换(含 dsh-session-switch 命令)
README
由 DeepSeek 最新模型翻译生成⚠ 2026-09-28 合并记录:本插件现在也管「会话那一摊」
起因是一次「合插件」的需求 ——dsh-session-switch(建新会话、发交接包、写 pending、供界面切过去)整个搬进了本包,作为 switch-session.js 与 switch-store.js 两个模块:
* 内部握手改成直调(runSwitchDirect()),不再是 POST http://127.0.0.1:3080/api/session/switch 那条网络往返;
* 那四条 HTTP 路由照旧注册(/api/session/switch|pending|ack|health),自检、手工 curl、老调用方都还认;
* 状态目录不变:~/.dsh/session-switch/(DSH_SESSION_SWITCH_DIR 可覆盖);
* 会话那一摊要的七个宿主服务改成运行时注入:缺谁只让这一摊缺席,档案那一摊照常(合并前是「整包卡 pending」);
* 自检多了一个口:DSH_SESSION_SWITCH_DIR=/tmp/ss node index.js --switch-selftest(原样 19 项)。
撤下前的完整副本在 plugin-src/归档-合并前-20260927-232845/。
展开完整文档(README 剩余 1 节)
⚠ 2026-09-28 合并记录:本插件现在也管「会话那一摊」 起因是一次「合插件」的需求 ——dsh-session-switch(建新会话、发交接包、写 pending、供界面切过去)整个搬进了本包,作为 switch-session.js 与 switch-store.js 两个模块: * 内部握手改成直调(runSwitchDirect()),不再是 POST http://127.0.0.1:3080/api/session/switch 那条网络往返; * 那四条 HTTP 路由照旧注册(/api/session/switch|pending|ack|health),自检、手工 curl、老调用方都还认; * 状态目录不变:~/.dsh/session-switch/(DSH_SESSION_SWITCH_DIR 可覆盖); * 会话那一摊要的七个宿主服务改成运行时注入:缺谁只让这一摊缺席,档案那一摊照常(合并前是「整包卡 pending」); * 自检多了一个口:DSH_SESSION_SWITCH_DIR=/tmp/ss node index.js --switch-selftest(原样 19 项)。 撤下前的完整副本在 plugin-src/归档-合并前-20260927-232845/。 dsh-auto-handoff DSH(DeepSeek Harness)插件:上下文占用到阈值时自动交接。 到阈值那一刻,它做这两件事: 1. 拼一份限长的交接包(默认 1200 字,只有它进新会话),请会话那一摊(2026-09-28 已并入本包的 switch-session.js)开新会话、把交接包当第一条消息送进去; 2. 记一笔幂等指纹到自己状态目录下的 handoff-fingerprints.json(跨重启有效,封顶 50 条)。 ⚠️ 2026-10-16 起:默认 不写档案 以前它每交接一次就往日记里塞一条「上下文到阈值,插件自动做了一次交接」的流水账(外加状态一节、生长记录一行),一天能塞好几条、删了又长;接手那边还会被提示「再补一条」。现在默认 archiveOnHandoff: false: * 交接只交接 —— 一个档案字节都不碰; * 幂等指纹不再寄生在日记条目上,改落 ~/.dsh/session-switch/handoff-fingerprints.json; * 日记/状态/生长记录只在人点「日记」或跑「收尾」时才更新; * 想回到旧行为(写日记 + 状态一节 + 生长记录一行)就把 archiveOnHandoff 设成 true。 到阈值时的默认动作也变了:autoTrigger: true 时它不自己切会话,而是给 AI 塞一条【自动收尾提示】(先做收尾,做完写 fire-now 举手换会话)—— 免得在人正看着屏幕的时候把对话切走。 本插件不自己建会话。 建会话、切界面、归档原会话都是会话那一摊(已并入本包的 switch-session.js)的活;两者只靠一个 HTTP 调用握手,叫不动就走降级(把完整待接写到约定位置,由浏览器那半边自己切)。 它管什么 / 不管什么 | | 本插件 | dsh-session-switch | | 管什么 | 交接包 + 待接记录(archiveOnHandoff: true 时才写日记 / 状态 / 生长记录) | 会话:建、切、归档 | | 触发 | 上下文到阈值自动;或手动打演练关键词 | 收到 /api/session/switch 才动 | 记忆的看 / 编 / 导入 / 导出是另一个插件(记忆面板)的事,本插件不碰。 安装 1. 把这个目录放进你的 DSH 插件源目录(本机示例:~/.dsh/plugin-src/dsh-auto-handoff)。 2. 把 cordis.patch.example.yml 里那一条按你的情况改好,插进 profile 的 cordis.patch.yml;或者用 Plugin Manager 的 install_bundle 把它当 bundle 装进 profile。 3. 重启宿主。实测:装 bundle、改 bundle 内代码、改 config 都认重启(HMR 不可靠)。 唯一的必填项是档案根:留空则依次尝试 config.root → 环境变量 DSH_MEMORY_ROOT → ~/.dsh/memory → 从当前目录逐级向上找 认根靠特征文件:身份.md + 日记.md + 生长\状态.md 三者齐备才算一份档案; 认不到就不动作(绝不拿一个猜出来的根去写真档案)。 配置 | 键 | 默认 | 说明 | | root | '' | 档案根;留空按上面的顺序找 | | triggerRatio | 0.65 | 占用到这个比例触发交接 | | minTurns | 3 | 会话太短不触发 | | cooldownMs | 180000 | 冷却 3 分钟;过了冷却还能再交一次(不是「一会话一次」) | | handoffMaxChars | 1200 | 交接包上限 | | dryRun | true | 首启只算不写:把「本来会写什么」记日志,一个字节都不落盘 | | archiveOnHandoff | false | 交接要不要写档案:false = 只出交接包(默认、推荐);true = 还写日记一条 + 状态一节 + 生长记录一行 | | autoTrigger | false | true = 到阈值不自己切会话,而是给 AI 塞一条「该收尾了」的提示(见上文 2026-10-16 说明) | | device | 【PC】 | 日记标题与状态节里的设备标签(archiveOnHandoff: true 时才用得上) | | drillKeyword | #交接演练 | 手动演练关键词(只在用户消息里整句匹配) | | gatewayBase | http://127.0.0.1:3080 | dsh-session-switch 的地址 | | legacyDevice / legacyBoundary | '' | 旧条目设备归属判据;没配就完全不推断 | 占用率的取数口径:优先会话投影 contextPressure(跟页面上那个百分比同源),拿不到再退回 ctx.tokenMeter.measure() ÷ request/context().contextWindow; 两个都拿不到就返回「不动作」 —— 不许瞎猜分母。 手动演练 在对话里整句打 #交接演练: - 只写演练副本根(sandboxRoot),真档案一个字节不碰; - 没配 sandboxRoot 就只做一次干跑,日志里能看到「本来会写什么」; - sandboxRoot 落在真档案根里面时硬拒(那样「演练」就是真写)。 Host 侧路由 前缀 /api/handoff/,五条各自注册一次(requestBody 只能是 buffered,写别的会静默失败)。 | 路由 | 方法 | 用途 | | pending | GET | 给客户端轮询的待接(完整交接包 + sourceSession + newSessionId) | | take | GET/POST | 与 pending 同义(取一份待接) | | ack | POST | 客户端切完回报,标记「已处理」 | | health | GET | 一眼看配置与管道:阈值 / 冷却 / 上限 / 档案根 / gateway | | status | GET | 最近 20 行诊断日志 + 上次判定 | | draft-report | POST | 客户端上报输入框草稿状态(「别打断正在打字的人」用) | | fire | POST | AI 举手请求换会话(只认「收尾」口令 + 每小时 ≤2/每天 ≤8) | | fire-ack | POST | 客户端替用户打完「换会话」后回来清标志 | 客户端半边(client.js)只做「轮询 + 调导航/归档」:不注册 slot、不写 DOM,出错只 console,绝不抛 —— 客户端入口抛错的代价是「整个页面打不开」。 「收尾后自动换会话」怎么举手(文件信令) POST /api/handoff/fire 那条路要过宿主鉴权(实测在本机回 401,本机 curl 也一样),所以 AI 举手改用写一个文件: : > ~/.dsh/session-switch/fire-now # 路径 = <状态目录>/fire-now,内容随便 - 插件每 1 秒看一次这个文件 → 删掉 → 设 fireRequested; - 客户端本来就在轮询 /pending,看到 fire 就替用户打一条「换会话」,于是走既有那条触发路径(建新会话、送交接包、切界面),打完回 fire-ack 清标志; - 闸没松:仍然受 每小时 ≤2/每天 ≤8 限制;fire 那条 HTTP 路由还额外要求「最近一条用户消息就是『收尾』」。 - 典型用法:AI 跑完收尾(日记 → 备份 → 体检)写一下这个文件,人就自动被带到新会话。 写档案的护栏(只在 archiveOnHandoff: true 时用得上) 默认不写档案(见上文),所以这一节只在把 archiveOnHandoff 打开时生效。写盘一律四条: 1. 改前备份(整份复制到 <根>\归档-旧版本与记录\写入备份\,.bak-YYYYMMDD-HHMMSS); 2. 只改定位处(序号 +1、total_count +1、last_updated、unfinished,别的一字不动); 3. 写完复核(读回来逐字比对 + 「旧内容只能是新内容的前缀/只差一处」的形状复核); 4. 外部改动拒写(指纹比对:我们读过之后被改过 → 拒写)。 外加: - 幂等:同一份交接重复跑不追加第二条 —— archiveOnHandoff: false 时指纹写在 <状态目录>/handoff-fingerprints.json,true 时写在日记条目里的注释标记; - 写临时文件再 rename,不赌覆盖式写入; - 行尾/编码:全文件 CRLF、UTF-8 无 BOM。 自检 node index.js --selftest # 在临时目录造假档案,跑全套回归(每项打实际输出) node test-handoff-sandbox.mjs # 同一套,只打结论 node test-handoff-sandbox.mjs --verbose 自检口在模块层(不是 apply 里)—— 独立跑 node index.js 时 cordis 不会调 apply,写在里面会一声不吭。 已知边界 - 它不保证「交接的内容是这一轮的全文」:交接包是压缩后的接手起点,不是复制品—— 新会话一开就吃满上下文等于把坑搬过去。 - 日记正文里的 event_description 由「最近说过的话 + 动过的工具」拼成;没给 userMood 时那一栏会照实留白,不替你编心情。 - 跨设备没做:手机侧没有同一套 Web 客户端,切会话要另想办法。 - legacyDevice / legacyBoundary 只是判据:本插件不会去改写任何旧条目。 License MIT
预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
S3K926/dsh-auto-handoff
DSH 插件:上下文到阈值时生成交接包并切到新会话。已弃用 2026-10-17:换会话整条退役——续航交给 DSH…
相关插件 · 对话 / 记忆
上下文中枢oceanbase/powercontext
上下文跟着工作走 —— 跨会话、跨智能体、跨人。
★ 1,462已汉化DSH
73
智能体记忆库plastic-labs/honcho
Honcho 是记忆基础设施,用来构建有状态的智能体。这些智能体能理解不断变化的人、智能体、群组、项目和想法。
★ 7,848已汉化DSH
71.7
长程智能体控制面loopx-project/loopx
给 Agent 一个目标,让工作持续向前。
★ 6,358已汉化DSH
71.3
智能体上下文数据库volcengine/OpenViking
给 AI 智能体用的上下文数据库
★ 41,246已汉化DSH
71.3
长效机器人团队Fei2411/DS-Bot
DS Bot 是一个基于 DeepSeek Harness简称 dsh的 bot 插件,插件将 dsh 改造为 bot…
★ 4,717已汉化DSH
71.1
可携带记忆层EverMind-AI/EverOS
为什么选择 EverOS
★ 13,711已汉化DSH
71.1