分阶段预热并守护记忆进程,避免启动超时
30/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/1 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
自动兼容检查有告警:未发布到 npm registry,仅可从源码安装。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add Nesarf/volcano-separator该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:待复验
是什么
dsh 原生插件 · tool
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 31 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查⚠ 装前注意未发布到 npm registry,仅可从源码安装
展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✗npm 包volcano-separator(未发布到 npm,仅可源码安装)
✓Node 引擎要求 >=20.12 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/8 09:41:36
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 188 处,展示前 139 条)
- 读取本地文件lib/core.mjs:134
for (const p of paths) if (p && existsSync(p)) return p - 读取本地文件lib/core.mjs:146
if (statSync(p).isFile()) return p - 读取本地文件lib/core.mjs:187
if (uvCacheDir && existsSync(uvCacheDir)) { - 读取本地文件lib/mcp.mjs:57
const pkg = JSON.parse(readFileSync(join(dirname(fileURLToPath(import.meta.url)), '..', 'package.json'), 'utf8')) - 读取本地文件lib/platform.mjs:38
const raw = readFileSync(file, 'utf8') - 执行外部命令来自配置/变量lib/platform.mjs:100
child = spawn(cmd, args, { env, cwd, windowsHide: true }) - 写入本地文件lib/platform.mjs:115
appendFileSync(logFile, chunk) - 写入本地文件lib/platform.mjs:124
mkdirSync(join(logFile, '..'), { recursive: true }) - 读取本地文件lib/activity.mjs:35
list = readdirSync(dir) - 读取本地文件lib/activity.mjs:37
.map((f) => ({ f, t: statSync(join(dir, f)).mtimeMs })) - 读取本地文件lib/activity.mjs:59
text = readFileSync(join(dir, entry.f), 'utf8') - 读取本地文件lib/activity.mjs:155
if (!existsSync(file)) { - 读取本地文件lib/activity.mjs:160
raw = JSON.parse(readFileSync(file, 'utf8').replace(/^ FEFF/, '')) - 读取本地文件lib/activity.mjs:271
if (!existsSync(watch)) return { ok: false, detail: `watcher not found: ${watch}` } - 写入本地文件lib/activity.mjs:302
writeFileSync(vbs, script, 'utf8') - 写入本地文件lib/activity.mjs:407
mkdirSync(dir, { recursive: true }) - 写入本地文件lib/activity.mjs:413
appendFileSync(file, JSON.stringify(event) + '\n', 'utf8') - 读取本地文件lib/live.mjs:57
files = readdirSync(dir) - 读取本地文件lib/live.mjs:59
.map((f) => ({ f, t: statSync(join(dir, f)).mtimeMs, size: statSync(join(dir, f)).size })) - 读取本地文件lib/live.mjs:67
text = readFileSync(join(dir, entry.f), 'utf8') - 读取本地文件lib/live.mjs:81
if (existsSync(hb)) { - 读取本地文件lib/live.mjs:84
text = readFileSync(hb, 'utf8') - 读取本地文件lib/live.mjs:105
if (!existsSync(script)) return { ok: false, detail: `reveal script missing: ${script}` } - 读取本地文件lib/service.mjs:312
if (configFile && existsSync(configFile)) { - 读取本地文件lib/redline.mjs:55
if (!existsSync(area.dir)) continue - 读取本地文件lib/redline.mjs:72
entries = readdirSync(dir, { withFileTypes: true }) - 读取本地文件lib/redline.mjs:85
size = statSync(full).size - 读取本地文件lib/redline.mjs:130
for (const line of readFileSync(file, 'utf8').split(String.fromCharCode(10))) { - 写入本地文件lib/redline.mjs:147
appendFileSync(file, JSON.stringify({ - 读取本地文件lib/rules.mjs:109
return readFileSync(RULES_DOC, 'utf8') - 读取本地文件lib/entity.mjs:194
pathExists: exe ? existsSync(exe) : null, - 读取本地文件lib/entity.mjs:228
snapshot.push({ surface: 'filesystem', what: 'the path itself', value: { exists: existsSync(path) } }) - 读取本地文件lib/entity.mjs:363
pathExists: exe ? existsSync(exe) : null, - 写入本地文件lib/supervisor.mjs:63
mkdirSync(dir, { recursive: true }) - 读取本地文件lib/supervisor.mjs:68
const files = readdirSync(dir) - 读取本地文件lib/supervisor.mjs:70
.map((f) => ({ f, t: statSync(join(dir, f)).mtimeMs })) - 删除本地文件lib/supervisor.mjs:74
rmSync(join(dir, old.f), { force: true }) - 读取本地文件lib/supervisor.mjs:96
for (let n = 2; existsSync(file) && n < 100; n++) { - 读取本地文件lib/supervisor.mjs:130
names = readdirSync(base) - 读取本地文件lib/supervisor.mjs:137
if (existsSync(p)) out.push(p) - 发起网络请求lib/supervisor.mjs:210
res = await fetch(`${base}${spec.path}`, { signal: ctl.signal }).catch(() => null) - 读取本地文件lib/supervisor.mjs:301
return { dataDir: resolve(ctx.pgDataDir), deployment: 'declared', exists: existsSync(resolve(ctx.pgDataDir)), why: 'ctx.pgDataDir' } - 写入本地文件lib/supervisor.mjs:1148
mkdirSync(dirname(logFile), { recursive: true }) - 写入本地文件lib/supervisor.mjs:1149
const log = (line) => appendFileSync(logFile, `${new Date().toISOString()} ${line}\r\n`) - 写入本地文件lib/supervisor.mjs:1394
mkdirSync(join(projectDir, 'bin'), { recursive: true }) - 写入本地文件lib/supervisor.mjs:1395
writeFileSync(scriptPath, script, 'utf8') - 读取本地文件lib/signals.mjs:174
if (exe && !systemRoot && !existsSync(exe)) { - 读取本地文件lib/signals.mjs:305
for (const line of readFileSync(file, 'utf8').split(String.fromCharCode(10))) { - 写入本地文件lib/signals.mjs:344
appendFileSync(file, line + String.fromCharCode(10)) - 读取本地文件lib/signals.mjs:392
existing = readFileSync(file, 'utf8') - 写入本地文件lib/signals.mjs:451
mkdirSync(dir, { recursive: true }) - 写入本地文件lib/signals.mjs:452
writeFileSync(file, kept.concat(line).join(String.fromCharCode(10)) + String.fromCharCode(10)) - 读取本地文件lib/signals.mjs:615
return readFileSync(file, 'utf8') - 读取本地文件lib/custody.mjs:60
files = readdirSync(dir).filter((f) => /^activity-\d{4}-\d{2}-\d{2}\.ndjson$/.test(f)) - 读取本地文件lib/custody.mjs:67
text = readFileSync(join(dir, f), 'utf8') - 读取本地文件lib/custody.mjs:95
files = readdirSync(dir).filter((f) => /^detain-\d+\.json$/.test(f)) - 读取本地文件lib/custody.mjs:202
files = readdirSync(dir).filter((f) => /^activity-\d{4}-\d{2}-\d{2}\.ndjson$/.test(f)).sort() - 读取本地文件lib/custody.mjs:212
text = readFileSync(join(dir, f), 'utf8') - 读取本地文件lib/custody.mjs:281
files = readdirSync(dir).filter((x) => x.startsWith('detain-') && x.endsWith('.json')) - 删除本地文件lib/custody.mjs:692
rmSync(summaryFile, { force: true }) - 读取本地文件lib/policy.mjs:66
let integrity = existsSync(file) ? 'ok' : 'absent' - 读取本地文件lib/policy.mjs:70
raw = JSON.parse(readFileSync(file, 'utf8')) - 写入本地文件lib/policy.mjs:99
mkdirSync(dirname(file), { recursive: true }) - 写入本地文件lib/policy.mjs:105
writeFileSync(tmp, JSON.stringify(policy, null, 2) + '\n', 'utf8') - 写入本地文件lib/policy.mjs:106
renameSync(tmp, file) - 删除本地文件lib/policy.mjs:110
rmSync(tmp, { force: true }) - 读取本地文件lib/uvcache.mjs:54
entries = readdirSync(d, { withFileTypes: true }) - 读取本地文件lib/uvcache.mjs:64
total += statSync(full).size - 读取本地文件lib/uvcache.mjs:99
if (!root || !existsSync(root)) { - 读取本地文件lib/uvcache.mjs:103
if (!existsSync(archiveDir)) { - 读取本地文件lib/uvcache.mjs:109
for (const sub of readdirSync(root)) { - 读取本地文件lib/uvcache.mjs:112
if (!statSync(p).isDirectory()) continue - 写入本地文件lib/uvcache.mjs:269
mkdirSync(dir, { recursive: true }) - 写入本地文件lib/uvcache.mjs:272
writeFileSync(tmp, JSON.stringify(plan, null, 2) + NL, 'utf8') - 写入本地文件lib/uvcache.mjs:274
renameSync(tmp, file) - 删除本地文件lib/uvcache.mjs:279
try { unlinkSync(tmp) } catch { } - 删除本地文件lib/uvcache.mjs:282
try { unlinkSync(tmp) } catch { } - 删除本地文件lib/uvcache.mjs:290
unlinkSync(old.file) - 删除本地文件递归lib/uvcache.mjs:392
rmSync(trash, { recursive: true, force: true }) - 写入本地文件lib/uvcache.mjs:396
mkdirSync(trash, { recursive: true }) - 写入本地文件lib/uvcache.mjs:432
renameSync(t.dir, staged) - 删除本地文件递归lib/uvcache.mjs:440
rmSync(staged, { recursive: true, force: true }) - 读取本地文件lib/enforce.mjs:61
if (!existsSync(script)) return { ok: false, detail: `isolation script missing: ${script}` } - 读取本地文件lib/enforce.mjs:112
if (!existsSync(dir)) return { ok: true, dir, entries: [] } - 读取本地文件lib/enforce.mjs:114
for (const f of readdirSync(dir).filter((n) => n.endsWith('.json')).sort()) { - 读取本地文件lib/enforce.mjs:127
backupExists: spec.backupFile ? existsSync(spec.backupFile) : false, - 读取本地文件lib/enforce.mjs:166
if (!existsSync(script)) return {} - 写入本地文件lib/enforce.mjs:169
writeFileSync(listFile, list.join(String.fromCharCode(10))) - 写入本地文件lib/crypt.mjs:100
mkdirSync(dirname(file), { recursive: true }) - 读取本地文件lib/crypt.mjs:104
if (!existsSync(script)) return { ok: false, detail: `keyprotect script missing: ${script}` } - 读取本地文件lib/crypt.mjs:106
if (existsSync(file)) { - 读取本地文件lib/crypt.mjs:111
const raw = Buffer.from(readFileSync(plain, 'utf8').trim(), 'base64') - 删除本地文件lib/crypt.mjs:115
rmSync(plain, { force: true }) - 写入本地文件lib/crypt.mjs:121
writeFileSync(plain, raw.toString('base64'), { encoding: 'ascii' }) - 删除本地文件lib/crypt.mjs:126
rmSync(plain, { force: true }) - 读取本地文件lib/crypt.mjs:184
return { ok: true, size: statSync(path).size } - 读取本地文件lib/crypt.mjs:203
if (!existsSync(path)) return { ok: false, detail: `no such file: ${path}` } - 读取本地文件lib/crypt.mjs:207
st = statSync(path) - 写入本地文件lib/crypt.mjs:239
mkdirSync(jdir, { recursive: true }) - 写入本地文件lib/crypt.mjs:262
writeFileSync(journal, JSON.stringify(spec, null, 2)) - 写入本地文件lib/crypt.mjs:268
writeFileSync(tmp, blob) - 删除本地文件lib/crypt.mjs:270
rmSync(tmp, { force: true }) - 写入本地文件lib/crypt.mjs:278
writeFileSync(stray, back) - 删除本地文件lib/crypt.mjs:283
rmSync(stray, { force: true }) - 删除本地文件lib/crypt.mjs:286
rmSync(tmp, { force: true }) - 删除本地文件lib/crypt.mjs:293
rmSync(tmp, { force: true }) - 写入本地文件lib/vault.mjs:80
mkdirSync(dirname(file), { recursive: true }) - 读取本地文件lib/vault.mjs:84
if (!existsSync(script)) return { ok: false, detail: `keyprotect script missing: ${script}` } - 读取本地文件lib/vault.mjs:86
if (existsSync(file)) { - 读取本地文件lib/vault.mjs:93
if (!existsSync(plain)) return { ok: false, detail: r.error ?? 'unprotect produced no key' } - 读取本地文件lib/vault.mjs:94
const raw = Buffer.from(readFileSync(plain, 'utf8').trim(), 'base64') - 删除本地文件lib/vault.mjs:98
rmSync(plain, { force: true }) - 写入本地文件lib/vault.mjs:104
writeFileSync(plain, raw.toString('base64'), { encoding: 'ascii' }) - 删除本地文件lib/vault.mjs:109
rmSync(plain, { force: true }) - 读取本地文件lib/vault.mjs:110
if (!existsSync(file)) return { ok: false, detail: r.error ?? 'could not protect the new key' } - 读取本地文件lib/vault.mjs:139
h.update(readFileSync(file)) - 写入本地文件lib/vault.mjs:208
mkdirSync(entryDir, { recursive: true }) - 写入本地文件lib/vault.mjs:209
copyFileSync(src, vaultPath) - 删除本地文件递归lib/vault.mjs:211
rmSync(entryDir, { recursive: true, force: true }) - 删除本地文件递归lib/vault.mjs:220
rmSync(entryDir, { recursive: true, force: true }) - 写入本地文件lib/vault.mjs:240
writeFileSync(join(entryDir, MANIFEST), JSON.stringify(spec, null, 1) + String.fromCharCode(10), 'utf8') - 删除本地文件递归lib/vault.mjs:242
rmSync(entryDir, { recursive: true, force: true }) - 删除本地文件lib/vault.mjs:254
rmSync(src, { force: true }) - 写入本地文件lib/vault.mjs:297
mkdirSync(dirname(file), { recursive: true }) - 读取本地文件lib/chamber.mjs:49
if (!existsSync(script)) return { ok: false, pid: target, detail: `process probe script missing: ${script}` } - 删除本地文件lib/chamber.mjs:54
rmSync(outFile, { force: true }) - 删除本地文件lib/chamber.mjs:65
rmSync(outFile, { force: true }) - 读取本地文件lib/chamber.mjs:169
if (!existsSync(script)) return { ok: false, detail: `the chamber window script is missing: ${script}` } - 写入本地文件lib/chamber.mjs:178
writeFileSync(profile, JSON.stringify(p, null, 1), 'utf8') - 读取本地文件lib/chamber.mjs:204
return existsSync(chamberScript()) - 读取本地文件lib/lock.mjs:45
if (!existsSync(file)) return null - 写入本地文件lib/lock.mjs:97
mkdirSync(dirname(file), { recursive: true }) - 写入本地文件lib/lock.mjs:100
writeFileSync(file, JSON.stringify(me, null, 2)) - 删除本地文件lib/lock.mjs:117
rmSync(file, { force: true }) - 读取本地文件lib/database.mjs:42
if (!existsSync(root)) continue - 读取本地文件lib/database.mjs:44
const versions = readdirSync(root).sort((a, b) => b.localeCompare(a, undefined, { numeric: true })) - 读取本地文件lib/database.mjs:47
if (existsSync(join(bin, 'psql.exe'))) return bin - 读取本地文件lib/database.mjs:65
if (!existsSync(file)) return null - 读取本地文件lib/database.mjs:67
for (const line of readFileSync(file, 'utf8').split(String.fromCharCode(10))) {
扫描于 2026/11/1(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- 分阶段预热记忆进程
- 心跳监控守护进程
- 解耦脆弱启动链路
将 uv、Hindsight 守护进程及其数据从一条脆弱的链路中解耦:无看门狗预热,数秒内提供服务,按心跳监控。
README
由 DeepSeek 最新模型翻译生成Volcano Separator
CI
将三样被焊死在一起的东西分开。
volcano-separator 是 Hindsight 记忆守护进程的监管器。它修复的不是一个 bug——它修复的是一种结构性脆弱:
uvx(包安装器) └─ uv 缓存中的一个临时环境 ← 守护进程自身的代码就在这里 └─ hindsight 守护进程 ← 由宿主插件按需启动, └─ Postgres (pg0) 仅在会话开始时 / 在 retain 时 ← 数据就在这里
一个包安装器的状态决定了服务能否启动,而服务的生命周期又由宿主的会话时序决定。当任何一环感冒时,记忆就会消失——悄无声息地。
它实际治疗的是什么
在提取出本工具的机器上测得(volcano-separator doctor):
12 次启动尝试,7 次因超时失败,1 次成功
每一条失败日志都在启动路径上显示 Downloaded botocore / Built claude-agent-sdk==0.2.16x。
一次构建和一个看门狗在互相竞速——插件的看门狗允许约 180 秒,而在机械硬盘上冷缓存的 uvx 运行需要的时间远不止于此。它每次都输。
展开完整文档(README 剩余 1 节)
Volcano Separator
CI
将三样被焊死在一起的东西分开。
volcano-separator 是 Hindsight 记忆守护进程的监管器。它修复的不是一个 bug——它修复的是一种结构性脆弱:
uvx(包安装器) └─ uv 缓存中的一个临时环境 ← 守护进程自身的代码就在这里 └─ hindsight 守护进程 ← 由宿主插件按需启动, └─ Postgres (pg0) 仅在会话开始时 / 在 retain 时 ← 数据就在这里
一个包安装器的状态决定了服务能否启动,而服务的生命周期又由宿主的会话时序决定。当任何一环感冒时,记忆就会消失——悄无声息地。
它实际治疗的是什么
在提取出本工具的机器上测得(volcano-separator doctor):
12 次启动尝试,7 次因超时失败,1 次成功
每一条失败日志都在启动路径上显示 Downloaded botocore / Built claude-agent-sdk==0.2.16x。
一次构建和一个看门狗在互相竞速——插件的看门狗允许约 180 秒,而在机械硬盘上冷缓存的 uvx 运行需要的时间远不止于此。它每次都输。
修复方案:将工作分阶段,使任何看门狗都不会与构建竞速
| 阶段 | 它做什么 | 看门狗 |
| warm | 确保 uv 环境完整(幂等) | 无——它可能需要数分钟;它会运行至完成 |
| serve | 仅在环境已热时启动守护进程 | 有,但此时只需数秒——它永远不会触发 |
| watch | 按需进行健康探测与修复 | 心跳,健康时成本近乎为零 |
让这一切奏效的特性是:heal 在健康时耗时约 0.9 秒(一次 TCP 探测)。因此它可以每隔几分钟被调用一次,而无需保留一个常驻的监管进程——调度即监视。
修复的另一半在本工具的上游:将 UV_CACHE_DIR 指向一块 SSD,并把旧路径做成 junction,这样即使是冷启动也很快。
安装
git clone https://github.com//volcano-separator.git
cd volcano-separator
node bin/cli.mjs status # 无需安装步骤:零依赖
可选地将其加入 PATH:
npm link # 提供 volcano-separator 和 vsep
用法
volcano-separator status # 全链路检查(uv / 环境热度 / 守护进程 / pg / 守护进程日志错误 / 看门狗) volcano-separator heal # 智能修复:warm -> serve -> watch volcano-separator warm [--force] # 仅预热环境(无看门狗) volcano-separator serve # 仅启动服务 volcano-separator stop | restart volcano-separator doctor # 从插件日志统计历史启动失败次数 volcano-separator guard clean # 检查此刻执行 uv 缓存操作是否安全 volcano-separator install-service # 注册看门狗任务(登录时 + 每 N 分钟) volcano-separator service # 看门狗任务状态
选项:--profile (默认 coding-agent)、--port (默认 9077)、--json、--quiet、--force、--dry-run。
三种接口
| 形式 | 入口点 | 适用对象 |
| CLI | bin/cli.mjs | 人类、脚本、计划任务 |
| MCP | lib/mcp.mjs | 任何 harness —— volcano_status / volcano_heal / volcano_doctor |
| 库 | lib/core.mjs | 其他工具(纯 Node,零依赖) |
MCP 客户端配置: json {
"mcpServers": {
"volcano-separator": { "command": "node", "args": ["/path/to/volcano-separator/lib/mcp.mjs"] }
}
}
它为你处理的三个真实陷阱
1. 守护进程的代码位于 uv 缓存内部。
因此 uv cache clean / prune 会被正在运行的守护进程的占用锁阻止,而 --force 会在守护进程运行时删除它自己的文件。更糟的是,当它还活着时,缓存目录甚至无法被重命名(访问被拒绝)。
volcano-separator guard 会先检查并打印安全顺序:stop -> uv cache -> heal。
2. 由宿主插件启动的守护进程不被 embed 管理器识别。
hindsight-embed daemon stop 跟踪自己的 PID;宿主插件自己启动的守护进程不在该记录中,因此:
WARNING - Could not find PID for port 9077
WARNING - Port 9077 is bound but no hindsight daemon could be identified on it
Failed to stop daemon
因此 stop 有两个层级:先走官方路径,然后找到端口占用者并收集其进程树(仅限 uv/uvx/python/hindsight 进程——绝不包括其他任何东西)。没有这一层,一个由插件启动的守护进程会让监督程序永远无法停止它。
3. “端口有响应”不等于“它能工作”。
守护进程可以让 /health 保持绿色,却无法连接到它的数据库。在实际环境中观察到:磁盘饱和(一次后台文件清理)导致守护进程的 Postgres 连接握手超时 48 次,端口从未闪烁,而每次记忆写入都毫无可见原因地停滞。这就是为什么 status 还会探测 Postgres 并扫描守护进程自己的日志以查找错误——也是为什么它使用两个时间窗口:最近 5 分钟内的错误意味着它现在正在失败,而更早的任何内容都作为上下文(recovered)报告,这样过去的事件就不会让链条永远被标记为不健康。
设计边界
- 它不修补宿主插件。 插件的 ensureDaemon() 以 if (await isServerHealthy(...)) return; 开头——一旦服务已经健康,它会立即返回,那条脆弱的路径永远不会被进入。那是“不再被遍历”,而不是“被修补”。
- 没有额外的常驻进程。 监视被委托给操作系统调度器。
- 它只读取日志;它从不触碰 hindsight 自己的数据。
移植一切皆靠发现,而非硬编码:uvx 来自 PATH,缓存目录来自 UV_CACHE_DIR(并将 junction 解析为其真实目标),嵌入版本来自宿主配置。
在 lib/core.mjs 顶部的 DEFAULTS 中调整行为: js profile: 'coding-agent', port: 9077,
withPackages: ['pg0-embedded'],
warmProbeMs: 15000, // 一次干跑慢于此值意味着环境是冷的 warmBudgetMs: 15 * 60 * 1000, serveBudgetMs: 5 * 60 * 1000, taskName: 'Volcano-Separator', taskIntervalMinutes: 5,
平台说明:计划任务集成目前仅限 Windows(schtasks / New-ScheduledTask)。暂存模型本身是可移植的——在 macOS/Linux 上,将 installService() 替换为 launchd plist 或 systemd timer。
要求
Node >= 20.12。零第三方依赖。
测试 bash
node test/smoke.mjs # 或:npm test
冒烟测试刻意保持离线:无网络、无 uv、无运行中的守护进程。它断言对监督器至关重要的属性——模块能加载,每个探针在其依赖缺失时降级而非抛出异常,缓存护栏在没有任何运行中的进程时报告“安全”,以及 CLI 的退出码行为正常。CI 在 Node 20 和 22 上运行它,覆盖 Linux 和 Windows。
许可证
MIT预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
Nesarf/volcano-separator
分阶段预热并守护记忆进程,避免启动超时
相关插件 · 工具 / 效率
破甲管控台kingcharleslzy-ai/dsh-purge
dsh-purge Community · DeepSeek Harness 社区维护版:宿主兼容、状态诊断、提示词管理、更新与本机备份回滚。基于小杨 / YuJunZhiXue 的 dsh-purge。
★ 3,801已汉化DeepSeek 客户端
74.5
网文长卷lingfengQAQ/webnovel-writer
基于 Claude Code 的长篇网文辅助创作系统,解决 AI 写作中的「遗忘」和「幻觉」问题,支持 200…
★ 7,636已汉化DSH
72.2
多智能体协作HKUDS/AutoSwarm
AutoSwarm: Unify Your Agents. Unify Your Context (Codex · Claude Code · DeepSeek Harness · Muse · Grok · WorkBuddy· nanobot · and more)
★ 2,082已汉化DSH
71.7
Vox 拼贴视频生成Alisa0808/vox-director
🎬 Vox Director拼贴动效导演
★ 2,129已汉化DSH
71.4
Agent 演化引擎Q00/ouroboros
智能体 OS:智能体自己变聪明,我们只守住底线:面试准入、分阶段评估、带预算的进化循环。MCP 服务器,14 种运行时:Claude Code、Codex CLI、Gemini CLI、OpenCode、Copilot、Kiro 等。
★ 6,292已汉化DSH
71.3
智能体运行框架路由HarnessRouter/harnessrouter
智能体运行框架的统一接口。
★ 3,800已汉化DSH
71.2