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

事件触发器 lychee888/galvanize-dsh

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

文件邮件或 git 事件发生时自动唤醒新会话

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

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

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

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:需留意
是什么[目录]—
dsh 原生插件 · market
暂无时间戳·判据 →
装得上吗[实装验证]!
实装验证未通过(unknown),装前请到仓库确认最近更新与 issue
L4 · 真实安装等级说明 →
数据截至 2026/10/07·判据 →
安全吗[自动扫描]—
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
数据截至 2026/11/05·判据 →
还在维护吗[仓库]—
更新放缓:最近一次提交在 35 天前
暂无时间戳·判据 →
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成

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

验证判据与等级说明 →

可信度证据

⚠︎ 实装验证未通过(unknown · 2026/10/7) ——可能是验证环境差异,装前建议到 GitHub 仓库确认最近更新与 issue。
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

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

可执行外部命令读写/删除本地文件读取剪贴板或密钥环境变量发起外部网络请求
查看扫描证据(共 49 处,展示前 40 条)
  • 读取本地文件
    src/cli.ts:46
    if (existsSync(join(root, 'cordis.patch.yml')) && existsSync(join(root, 'package.json'))) {
  • 删除本地文件递归
    src/cli.ts:73
    rmSync(workDir, { recursive: true, force: true })
  • 读取本地文件
    src/cli.ts:83
    const pkg = JSON.parse(readFileSync(pj, 'utf8')) as { scripts?: Record<string, string> }
  • 写入本地文件
    src/cli.ts:88
    writeFileSync(pj, JSON.stringify(pkg, null, 2) + '\n')
  • 执行外部命令固定命令
    src/cli.ts:91
    const r = spawnSync('npm', ['pack', '--pack-destination', outDir, src], {
  • 删除本地文件递归
    src/cli.ts:96
    rmSync(workDir, { recursive: true, force: true })
  • 读取本地文件
    src/cli.ts:100
    return p && existsSync(p) ? p : null
  • 读取本地文件
    src/cli.ts:125
    if (envBin && existsSync(envBin)) return { cmd: process.execPath, args: [envBin], note: `$DSH_BIN=${envBin}` }
  • 执行外部命令固定命令
    src/cli.ts:132
    const probe = spawnSync('dsh', ['--version'], { shell: process.platform === 'win32', timeout: 15_000, encoding: 'utf8' })
  • 读取本地文件
    src/cli.ts:143
    if (!existsSync(root)) continue
  • 读取本地文件
    src/cli.ts:145
    for (const dir of readdirSync(root)) {
  • 执行外部命令来自配置/变量
    src/cli.ts:157
    const r = spawnSync(dsh.cmd, [...dsh.args, ...argv], {
  • 执行外部命令固定命令
    src/cli.ts:274
    const npm = spawnSync('npm', ['install', '--no-audit', '--no-fund', '--save-exact', ...npmSpecs], {
  • 写入本地文件
    src/cli.ts:296
    writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n')
  • 写入本地文件
    src/cli.ts:406
    writeFileSync(surfacesPath(), JSON.stringify({ ...existing, dsh: 'plugin' }, null, 2))
  • 写入本地文件
    src/cli.ts:451
    writeFileSync(surfacesPath(), JSON.stringify(existing, null, 2))
  • 执行外部命令固定命令
    src/cli.ts:482
    const r = spawnSync('npm', ['install', '-g', '@deepseek-ai/dsh', '--no-audit', '--no-fund'], {
  • 读取本地文件
    src/core-client.ts:55
    const raw = JSON.parse(readFileSync(serveInfoPath(), 'utf8')) as Record<string, unknown>
  • 读取本地文件
    src/core-client.ts:65
    const tok = readFileSync(serveTokenPath(), 'utf8').trim()
  • 发起网络请求
    src/core-client.ts:78
    const res = await fetch(`http://127.0.0.1:${port}/version`, { signal: AbortSignal.timeout(timeoutMs) })
  • 发起网络请求
    src/core-client.ts:121
    const res = await fetch(`http://127.0.0.1:${info.port}/manage/${encodeURIComponent(op)}`, {
  • 读取本地文件
    src/dsh-bin.ts:12
    if (existsSync(entry)) return entry
  • 删除本地文件
    src/heartbeat.ts:37
    try { unlinkSync(join(heartbeatDirectory(profile), `${process.pid}-${sessionToken}.json`)) } catch { }
  • 写入本地文件
    src/heartbeat.ts:54
    mkdirSync(dir, { recursive: true })
  • 写入本地文件
    src/heartbeat.ts:56
    writeFileSync(`${path}.tmp`, JSON.stringify(beat), { mode: 0o600 })
  • 写入本地文件
    src/heartbeat.ts:57
    renameSync(`${path}.tmp`, path)
  • 写入本地文件
    src/heartbeat.ts:59
    writeFileSync(heartbeatPath(), JSON.stringify(beat), { mode: 0o600 })
  • 读取本地文件
    src/heartbeat.ts:71
    for (const name of readdirSync(dir).filter(n => n.endsWith('.json'))) {
  • 读取本地文件
    src/heartbeat.ts:73
    const raw = JSON.parse(readFileSync(join(dir, name), 'utf8')) as Heartbeat
  • 读取密钥环境变量
    src/index.ts:231
    const sessionToken = process.env.GALVANIZE_PROBE_TOKEN || randomUUID()
  • 写入本地文件
    src/index.ts:256
    writeFileSync(surfacesPath(), JSON.stringify({ ...readSurfaces(), dsh: 'plugin' }, null, 2))
  • 读取本地文件
    src/index.ts:266
    const parsed = JSON.parse(readFileSync(surfacesPath(), 'utf8'))
  • 执行外部命令来自配置/变量
    src/probe.ts:10
    const child = spawn(dsh.cmd, [...dsh.args, '--profile', profile, ...(task ? ['Reply with exactly: GALVANIZE_PROBE'] : [])], {
  • 读取本地文件
    src/profile-config.ts:20
    const doc: Document = parseDocument(existsSync(path) ? readFileSync(path, 'utf8') : '[]\n')
  • 读取本地文件
    src/profile-config.ts:20
    const doc: Document = parseDocument(existsSync(path) ? readFileSync(path, 'utf8') : '[]\n')
  • 写入本地文件
    src/profile-config.ts:36
    writeFileSync(temporary, String(doc), 'utf8')
  • 写入本地文件
    src/profile-config.ts:37
    renameSync(temporary, path)
  • 读取本地文件
    src/profile-config.ts:43
    if (!existsSync(path)) return
  • 读取本地文件
    src/profile-config.ts:44
    const doc: Document = parseDocument(readFileSync(path, 'utf8'))
  • 写入本地文件
    src/profile-config.ts:49
    if (doc.contents.items.length !== items.length) writeFileSync(path, String(doc), 'utf8')
扫描于 2026/11/5(0 天前) · 范围 全包扫描(包内未声明入口) · 来源 GitHub 仓库

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

社区实装还没有人打卡 · 装过的第一个就是你
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-tools
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 文件事件触发会话
  • 邮件事件触发会话
  • git事件触发会话

DSH 智能体里的触发器:文件、邮件、webhook 或 git 事件一发生,就唤起全新 DeepSeek Harness 会话。原生 Cordis 包,安装经心跳验证。

README

由 DeepSeek 最新模型翻译生成
galvanize-dsh:在你的 DSH 智能体内部触发 给你的 DeepSeek Harness 智能体一种自我唤醒的方式。 装好这个包之后,你的 DSH 智能体会自己注册事件触发器:文件落进某个文件夹、邮件到达、webhook 触发、git push。事件一发生,galvanize 核心就会带着你的提示词和事件数据,启动一个全新的无头 DSH 会话——所以「简历出现在我的下载文件夹里就叫我」是真正的推送触发,不是轮询任务。插件本身是个轻量、经过验证的客户端:智能体 schema 里有五个 trigger_ 工具,每个应答都由核心的本地 API 代理返回。安装的最后一步是证明插件已加载——实时探测配置档,并完成带认证的核心访问——因为坏掉的 DSH 插件会静默失效,而「应该没问题」是这个安装器唯一不肯给的答案。 安装 支持 Windows、macOS 和 Linux(Node ^22.19 || >=24——DSH 自己的版本范围)。
展开完整文档(README 剩余 1 节)
galvanize-dsh:在你的 DSH 智能体内部触发

给你的 DeepSeek Harness 智能体一种自我唤醒的方式。 装好这个包之后,你的 DSH 智能体会自己注册事件触发器:文件落进某个文件夹、邮件到达、webhook 触发、git push。事件一发生,galvanize 核心就会带着你的提示词和事件数据,启动一个全新的无头 DSH 会话——所以「简历出现在我的下载文件夹里就叫我」是真正的推送触发,不是轮询任务。插件本身是个轻量、经过验证的客户端:智能体 schema 里有五个 trigger_ 工具,每个应答都由核心的本地 API 代理返回。安装的最后一步是证明插件已加载——实时探测配置档,并完成带认证的核心访问——因为坏掉的 DSH 插件会静默失效,而「应该没问题」是这个安装器唯一不肯给的答案。

安装

支持 Windows、macOS 和 Linux(Node ^22.19 || >=24——DSH 自己的版本范围)。不用克隆,一条命令直接从 GitHub 跑:

npx github:lychee888/galvanize-dsh install
or global: npm install -g github:lychee888/galvanize-dsh
from a clone: npm ci && node lib/cli.js install

install 要求机器上先有两样东西:

1. the galvanize core (same family; daemon + autostart included):
pipx install "git+https://github.com/lychee888/galvanize.git"
galvanize init

2. DeepSeek Harness with its CLI on PATH:
npm install -g @deepseek-ai/dsh

然后那条 npx github:… 命令会把包挂载进你的 DSH web 配置档(用 --profile 换一个),初始化无头唤醒配置档,探测这两个配置档,只有拿到实时插件证明和可用的核心访问才报告成功。验证运行中的配置档会打印四项检查:

✔ core /version handshake core 0.2.0, api 1
✔ authenticated core access read-only trigger list succeeded
✔ patch row 'galvanize/tools' row present, package resolvable
✔ plugin heartbeat plugin 0.1.6, core_api_ok=true, 3s ago
LOADED: all four checks green.

galvanize-dsh verify --profile <name> 会在该配置档运行时重跑这些检查;galvanize-dsh uninstall 会撤销一切。

用 --wake-profile <name> 选择 headless 之外的配置档。安装器会把这一选择写进每个已安装配置档的 cordis.patch.yml,保留原有设置,这样后续 trigger_add 调用用的就是安装探测验证过的同一个配置档。卸载会移除安装器创建的覆盖项,保留用户自己写的行。

卸载自定义安装时,请使用相同的 --profile 和 --wake-profile 选项。

安装会用各自独立的随机会话 token 探测目标配置档和唤醒配置档。证明必须来自那个确切的配置档和 token、已安装的插件版本、存活的 PID、兼容的核心握手,以及带认证的只读核心访问。凭据缺失或无效会让验证失败,即使最近一次心跳看起来健康时,才算通过。再跑另一个配置档,也无法让失败的探测通过。会话记录存放在 ~/.galvanize/dsh-heartbeats/<profile>/ 下;旧版 dsh-heartbeat.json 只是诊断用途,验证时永远不会接受它。已停止、过期、不健康或旧版本的会话,都不能证明 LOADED。升级后请重新运行安装器,为已有配置补上配置档身份。

安装器还会更新核心共享的 dsh_wake_profile 设置,让 galvanize add --wake dsh 选中的配置档与插件创建的触发器一致。请把核心和这个插件一起升级;如果核心无法持久化这个设置,安装会报错。这只影响新建的触发器。

第一个触发器

galvanize add folder ~/inbox --name triage --wake dsh \
--prompt 'Read {file} and write a triage summary to ~/inbox-out/{file}.md'

echo hello > ~/inbox/demo.txt # a minute later: ~/inbox-out/demo.txt.md

也可以跳过命令行,直接在 DSH 聊天里告诉你的智能体: “wake me when a lab report lands in my inbox”* —— 它会自己调用 trigger_add,先试触发一次让你看着它跑通,然后安静等待,直到事件真正发生。

智能体能拿到什么

| 工具 | 作用 |
| trigger_add | 注册触发器(folder / webhook / emit / imap)—— 轮询任务的「事件形态」替代方案 |
| trigger_list | 当前在监听什么,附带设置 |
| trigger_test | 走真实分发路径触发一次合成事件 |
| trigger_status | 如实反映健康状况:守护进程、上次触发、今日触发次数、上次错误 |
| trigger_remove | 移除一个触发器(连带清理路由) |

event ── galvanize core ── wake ──▶ dsh --profile headless "<your prompt>"
(folder/ (dedupe, cooldown, │
mail/webhook/ routes, delivery) ▼
git/emit) fresh DSH session

- 瘦客户端: JS 里没有唤醒或触发逻辑——一切都代理到核心的 loopback API(GET /version、POST /manage/<op>、bearer token),所以行为和核心给 Hermes / Claude Code / Codex 的插件一致。
- 单一入口: 插件和 galvanize mcp 从不共存;活跃的那个会占用 ~/.galvanize/surfaces.json,核心的 doctor 会标记重复挂载。
- 唤醒预设: 核心按事件启动 dsh --profile <wakeProfile> "<prompt>";配置档、命令和心跳节奏都是 bundle 行上的配置。

开发

对于 kind=webhook 且唤醒方式为 DSH 或 shell 的情况,trigger_add 要求提供 relay_url,并接受 relay_token(即 worker 的 RELAY_TOKEN)。部署 galvanize relay 时使用单独的 INGEST_TOKEN,让发送方在返回的 /ingest/<name> URL 上使用 Authorization: Bearer <INGEST_TOKEN>。缺少 relay 时,会在创建触发器之前报错。参见核心的 relay 设置。

npm ci && npm run build && npx vitest run && npx publint
src/index.ts(工具)· src/core-client.ts(serve 客户端)· src/cli.ts(安装器 / 校验 / 卸载)· test/(单元测试与集成测试)。
把后续的 galvanize core 克隆到当前 checkout 旁边,或者把 GALVANIZE_CORE_SOURCE 设为它的路径,然后安装它的 Python 依赖。
GALVANIZE_CORE_PYTHON 可选,用来指定解释器。集成测试会启动真实的 Python core,对比命令行与插件创建的结果,并在隔离的最小配置档里启动官方 DSH 运行时,接入真实工具服务。
这些测试不调用任何模型或服务商,也不会改动你本机的 DSH 安装。
fixture 锁定 DSH 0.1.1-rc.2 和 HMR 1.0.16,因为 HMR 1.0.19 移除了这个 DSH 版本要调用的 registerConfig API。CI 在 Windows、Linux、macOS 上跑全部测试;由服务商支撑的无头会话仍单独做实时检查。

License

MIT
预览分享卡片长什么样 ↓lychee888/galvanize-dsh
分享 · DeepSeek Harness Hub
lychee888/galvanize-dsh

文件邮件或 git 事件发生时自动唤醒新会话

这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。
认领条目 →
回到顶部