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

会话唤醒桥 Asheep233/dsh-session-wake

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

从外部进程即时唤醒运行中的会话并投递新一轮任务

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

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

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

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:仅索引
是什么
dsh 原生插件 · other
装得上吗
本站尚未做安装检查
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 14 天前
档位由哪些信号合成

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

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

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

读写/删除本地文件
查看扫描证据(共 15 处,展示前 11 条)
  • 写入本地文件
    lib/index.js:133
    try { appendFileSync(cfg.logFile, line + '\n') } catch { }
  • 写入本地文件
    lib/index.js:255
    renameSync(src, claimed)
  • 读取本地文件
    lib/index.js:260
    const raw = readFileSync(claimed, 'utf8')
  • 写入本地文件
    lib/index.js:270
    mkdirSync(doneDir, { recursive: true })
  • 写入本地文件
    lib/index.js:271
    renameSync(claimed, join(doneDir, `${Date.now()}-${basename(fileName).replace(/ (req|json)$/, '')}`))
  • 删除本地文件
    lib/index.js:273
    unlinkSync(claimed)
  • 写入本地文件
    lib/index.js:280
    mkdirSync(failedDir, { recursive: true })
  • 写入本地文件
    lib/index.js:281
    renameSync(claimed, join(failedDir, `${basename(fileName)}.${Date.now()}.err`))
  • 删除本地文件
    lib/index.js:283
    try { unlinkSync(claimed) } catch { }
  • 读取本地文件
    lib/index.js:293
    if (!existsSync(cfg.queueDir)) mkdirSync(cfg.queueDir, { recursive: true })
  • 读取本地文件
    lib/index.js:294
    names = readdirSync(cfg.queueDir)
扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

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

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

运行中的 DSH 会话即时唤醒——用官方 sessionController.prompt() API(HTTP + 文件队列)搭的宿主层桥接。无头模式为何做不到。

README

由 DeepSeek 最新模型翻译生成
dsh-session-wake 从外部进程即时唤醒一个正在运行/已持久化的 DSH 会话,让它在几毫秒内接受一轮新 turn。 支持 standard、ptc、minimal 等任意 agent preset,冷会话/忙碌中的会话都行——这是 dsh --profile headless 做不到的。 外部进程 ──HTTP POST /wake──┐ └──写文件队列───────┤ dsh web 进程内(host 插件) └─▶ ctx.sessionController.prompt() ──▶ 目标会话新 turn(GUI 里直接可见) - ✅ 不重启 DSH、不换 preset、不动会话历史 - ✅ 忙时排队不打断(mode:"queue")、冷会话自动 resume - ✅ 两条触发通道:HTTP(毫秒级)与文件队列(dsh 挂了请求积压、起来补投) - ✅ 零运行时依赖(只用 node: 内置模块),单文件 lib/index.js 为什么需要它(以及为什么 headless 不行) DSH 官方唯一「脚本唤醒会话」入口是 headless: dsh --profile headless --session-id <id> "继续干活" 但它只能驱动「从未记录过 agent preset」的裸 core 会话。
展开完整文档(README 剩余 1 节)
dsh-session-wake

从外部进程即时唤醒一个正在运行/已持久化的 DSH 会话,让它在几毫秒内接受一轮新 turn。
支持 standard、ptc、minimal 等任意 agent preset,冷会话/忙碌中的会话都行——这是 dsh --profile headless 做不到的。

外部进程 ──HTTP POST /wake──┐ └──写文件队列───────┤ dsh web 进程内(host 插件) └─▶ ctx.sessionController.prompt() ──▶ 目标会话新 turn(GUI 里直接可见)

- ✅ 不重启 DSH、不换 preset、不动会话历史
- ✅ 忙时排队不打断(mode:"queue")、冷会话自动 resume
- ✅ 两条触发通道:HTTP(毫秒级)与文件队列(dsh 挂了请求积压、起来补投)
- ✅ 零运行时依赖(只用 node: 内置模块),单文件 lib/index.js

为什么需要它(以及为什么 headless 不行)

DSH 官方唯一「脚本唤醒会话」入口是 headless:

dsh --profile headless --session-id <id> "继续干活"

但它只能驱动「从未记录过 agent preset」的裸 core 会话。只要会话记录过 preset(Web GUI 创建的会话都记录),就报:

dsh: session "session-..." runs under agent preset "standard",
which the one-shot runner does not compose

根因不是 profile 组合不全,而是 @deepseek-ai/dsh-headless/lib/index.js 里的硬判断:

function assertAdoptable(header, events, sessionId, cwd) {
const preset = currentPreset(header, events, sessionId);
if (preset !== void 0) throw new Error(... does not compose); // ← 无条件拒绝
...
}

补 bundle、写 --patch 都不会改变这个判断(0.2.0-rc.2 读源码确认)。

正确入口是浏览器客户端发消息所用的同一个官方 Host 服务 —— ctx.sessionController.prompt():

Admit one prompt after explicitly resuming its Session.

它按会话记录的 preset resume/组合 Agent,所以冷会话、standard 会话都能被它拉起来。本插件就是把这个能力包成外部可触发的桥。

安装

要求:DSH ≥ 0.2.0-rc.2(更低版本未验证);dsh web profile(host 平面插件,不需要 client 半边)。

方式 A:运行时注入(有 dsh-super-injector 时,免重启)

dev_inject_plugin /path/to/dsh-session-wake

方式 B:持久装配(官方 profile 机制,推荐)

git clone https://github.com/Asheep233/dsh-session-wake ~/.dsh/plugins/dsh-session-wake
bash ~/.dsh/plugins/dsh-session-wake/scripts/install-into-profile.sh # 默认 web profile 然后重启 dsh web

install-into-profile.sh 做三件幂等的事(先备份 package.json):写 dependencies(link:)、追加 dsh.profile.bundles、建 node_modules 链接。注意:dsh plugin add 只装包、不会加进 bundles(bundle 插件必须出现在 dsh.profile.bundles 才会被组合),所以别漏这一步。

方式 C:手动装配(知道自己在做什么)

1. 把本包装到 ~/.dsh/profiles/<profile>/node_modules/dsh-session-wake(symlink 到源码目录即可)
2. ~/.dsh/profiles/<profile>/package.json:

{
"dependencies": { "dsh-session-wake": "link:/path/to/dsh-session-wake" },
"dsh": { "profile": { "bundles": ["... 现有 bundles ...", "dsh-session-wake"] } }
}

3. 重启 dsh web

用法

HTTP(推荐:即时、有返回)

唤醒:给会话投一条 user message
curl -s -X POST http://127.0.0.1:3080/wake \
-H 'content-type: application/json' \
-d '{"sessionId":"session-1173e241-25f1-4a25-96f5-b48db0a3026c","text":"磁盘告警,请处理"}'
→ {"ok":true,"accepted":true,"sessionId":"...","requestId":"...","ms":37}

状态:桥版本、心跳、处理计数、依赖的 Host API 形状
curl -s http://127.0.0.1:3080/wake

自检:只解析会话、不跑模型(dryRun)
curl -s -X POST http://127.0.0.1:3080/wake \
-H 'content-type: application/json' \
-d '{"sessionId":"session-...","dryRun":true}'
→ {"dryRun":true,"sessionId":"...","found":true,"preset":"standard","cwd":"/path","events":4920,"live":true}

请求字段:

| 字段 | 必填 | 说明 |
| sessionId | 是* | 完整 session-<uuid>(可省略 session- 前缀);省略时用配置的 defaultSessionId |
| text | 否 | prompt 文本;省略时用配置的 defaultPrompt |
| mode | 否 | "queue"(默认,忙时排队)/ "steer"(插进当前 turn) |
| requestId | 否 | 幂等键:同一个 id 重试不会重复插入消息 |
| dryRun | 否 | true 时只 inspect() 会话,不投递、不跑模型 |

路由由插件 ctx.webServer.register() 自注册,不经过 /api/ 的 browser-trust 围栏,因此外部进程可以直接调;dsh web 默认只监听 127.0.0.1。

文件队列(dsh 挂了也不丢,起来补投)

默认目录 $DSH_HOME/wake-inbox(可配置 queueDir):

.req:第一行 session id(省略则用 defaultSessionId),其余为 prompt printf 'session-1173e241-25f1-4a25-96f5-b48db0a3026c\n磁盘告警,请处理\n' > "$DSH_HOME/wake-inbox/a.req"

或 .json
echo '{"sessionId":"session-1173e241-...","text":"构建完成,继续"}' > "$DSH_HOME/wake-inbox/b.json"

- 成功即删;失败移到 failed/<name>.<ts>.err;心跳写在 wake-inbox/bridge.json
- 轮询间隔 pollMs(默认 1500ms)——dsh 启动时会立即补投积压请求
- .json 兼容 BOM / CRLF(PowerShell Set-Content -Encoding UTF8 的产物直接可用)

触发场景示例

- 构建/测试完成 → 唤醒智能体继续下一步
- 磁盘/服务告警 → 唤醒会话处置(本项目来源场景)
- CI 状态变化、文件出现、进程退出码、定时器(替代/补充 schedule)
- 任意语言/任意进程,只要能发 HTTP 或写文件

配置

cordis.patch.yml 的 config(或运行时注入时传 config),全部有默认值:

| 键 | 默认 | 说明 |
| queueDir | null → $DSH_HOME/wake-inbox | 文件队列目录(null = 运行时解析) |
| pollMs | 1500 | 队列轮询间隔 |
| heartbeatMs | 10000 | bridge.json 心跳间隔 |
| logFile | /tmp/dsh-session-wake.log | 审计日志(追加) |
| defaultSessionId | '' | 请求缺 sessionId 时的默认目标 |
| defaultPrompt | 「外部唤醒:请检查最新状态与待办事项,并继续处理。」 | 请求缺 text 时的默认文本 |
| http | true | 是否注册 HTTP 入口 |
| httpPath | /wake | HTTP 路由路径(exact) |
| httpToken | '' | 非空时要求 x-wake-token 头或 ?token= |
| maxBodyBytes | 65536 | HTTP body 上限 |
| archiveDone | false | 成功后是否留档到 done/ |

示例:

- insert:
- id: dsh-session-wake
name: dsh-session-wake
config:
http: true
httpPath: /wake
httpToken: 'change-me'
defaultSessionId: session-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

语义与实测

| 场景 | 行为 | 实测(DSH 0.2.0-rc.2) |
| 热会话(web 进程内有 Agent) | 直接投递,起新 turn | accepted 39ms |
| 冷会话(仅持久化) | 按记录 preset 自动 resume,再起 turn | accepted 123ms,turn/start 正常 |
| 忙碌会话(正在跑 turn) | queue 模式排队,不打断,当前 turn 结束后处理 | 忙时投递 1ms 接受,结束后新 turn 处理 |
| 会话不存在 | HTTP 500 / 文件落 failed/ | {"error":"session \"...\" not found"} |

设计约束:

- 不写任何会话自定义事件:第三方插件 session.append() 自定义类型会让会话永久无法 resume
(Session.append() 无法设置 ignorable,reader 见到未知类型必须拒绝重建)。本插件只走官方 prompt 收件箱。
- 单写者:同一个会话同时被两个进程驱动会 SessionAlreadyOwnedError / session/writer-held。
如果该会话正在被 headless 驱动,别再用本桥;反之亦然。
- 冷会话沿用记录的模型:若会话记录的 provider/model 已下线,turn 会以 NO_ADAPTER 结束(机制本身正常)。

安全

- 服务默认只监听 127.0.0.1;HTTP 入口等价于「本机用户可发消息」,与 Web GUI 同级。
- 需要更强约束:配置 httpToken,请求带 x-wake-token: <token> 或 ?token=<token>。
- 不要把 dsh web 绑到公网再开这个入口(dsh web --host 0.0.0.0)——那等于开放任意 prompt 注入。
- 文件队列目录权限按需收紧(默认在 $DSH_HOME 下)。

兼容性与升级

依赖面刻意压到最小(零 npm 依赖、只 contact 两个 Host 服务):

| 依赖 | 风险 | 说明 |
| profile dependencies + dsh.profile.bundles + cordis.patch.yml | 低 | 官方装配机制 |
| inject: ['sessionController','webServer'] | 中 | 服务改名会让插件停在 pending(可观测:无心跳) |
| ctx.sessionController.prompt(request, signal) | 低-中 | @Remote("prompt"),与浏览器客户端同一 RPC 契约 |
| ctx.webServer.register({kind,path,handler}) | 低-中 | 官方 webserver 路由 API |

升级后一条命令自检:

bash scripts/post-upgrade-check.sh
7 项:dsh 版本 / web 监听 / 路由 / API 形状 / dryRun 解析目标会话(不花 token)/ 心跳 / 事件循环

GET /wake 的 api 字段会带出 {sessionController, prompt, promptArity, inspect, webServer, register};探测不到会打 ERROR 日志。若只是 API 形状变了,改 lib/index.js 的 deliver() / installHttp() 即可。

故障排查

| 现象 | 原因 / 处理 |
| curl /wake 404 | 插件没加载:确认 dsh.profile.bundles 含 dsh-session-wake,重启 dsh web;看 /tmp/dsh-session-wake.log |
| 日志 sessionController.prompt 不可用 | DSH 升级改了 Host API → 改 deliver();GET /wake 的 api 字段定位 |
| session/writer-held | 该会话正被另一个进程(如 headless)驱动 → 换目标或停掉另一写者 |
| 文件请求不处理 | queueDir 与写入目录不一致(看 GET /wake 的 queueDir);failed/ 里有错误文件 |
| 心跳过期 | 插件卡死/未 apply;tail /tmp/dsh-session-wake.log |

卸载

1. 从 ~/.dsh/profiles/<profile>/package.json 的 dependencies、dsh.profile.bundles 里删掉 dsh-session-wake
2. 删 node_modules/dsh-session-wake 链接
3. 重启 dsh web

(有注入器时也可 dev_uninject_plugin dsh-session-wake 立即卸载运行时实例。)

目录结构

dsh-session-wake/
├── package.json # dsh.bundle.patch 指向 cordis.patch.yml(官方 bundle 插件格式) ├── cordis.patch.yml # insert 本插件行(bundle 层) ├── lib/index.js # 全部实现(零依赖,单文件) ├── scripts/ │ ├── install-into-profile.sh # 持久装配(deps + bundles + link,幂等带备份) │ └── post-upgrade-check.sh # 升级自检(7 项) └── examples/ ├── curl-wake.sh # HTTP 触发示例 └── file-queue-wake.sh # 文件队列触发示例

实现要点:所有资源注册挂 ctx.effect(热重载/卸载自动清理);投递串行化避免并发抢同一会话;文件按 rename 原子认领;同文件重试用内容 hash 做 requestId 幂等去重。

License

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

从外部进程即时唤醒运行中的会话并投递新一轮任务

这是你的仓库?认领条目

回到顶部