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

工作流编排器 gamelongtim-ux/dsh-workflow-runner

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

编写 JS 脚本并行调度多个 AI 代理与命令

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

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

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

状态速览

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

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

验证判据与等级说明 →

可信度证据

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

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

可执行外部命令读写/删除本地文件读取剪贴板或密钥环境变量发起外部网络请求
查看扫描证据(共 74 处,展示前 52 条)
  • 读取本地文件
    lib/plugin.js:128
    return readFile(target, 'utf8');
  • 读取本地文件
    lib/plugin.js:207
    SKILL_CONTENT = readFileSync(SKILL_PATH, 'utf8');
  • 读取本地文件
    lib/plugin.js:251
    return readFile(target, 'utf8');
  • 读取本地文件
    lib/plugin.js:510
    return await readFile(file, 'utf8');
  • 读取本地文件
    lib/plugin.js:1245
    const content = await readFile(target, 'utf8');
  • 读取本地文件
    lib/plugin.js:1270
    const content = await readFile(target, 'utf8');
  • 读取本地文件
    lib/runner-bootstrap.mjs:212
    try { stat = statSync(abs); } catch (err) { throw new Error('artifact.file: ' + err.message); }
  • 读取本地文件
    lib/runner-bootstrap.mjs:215
    try { text = readFileSync(abs, 'utf8'); }
  • 读取本地文件
    lib/standalone.js:144
    try { content = await readFile(full, 'utf8'); } catch (_) { continue; }
  • 读取本地文件
    lib/standalone.js:345
    sendJson(res, 200, { path: target, content: await readFile(target, 'utf8') });
  • 读取本地文件
    lib/standalone.js:360
    const content = await readFile(target, 'utf8');
  • 读取本地文件
    lib/standalone.js:447
    const content = await readFile(filePath, 'utf8');
  • 读取本地文件
    lib/standalone.js:553
    const body = await readFile(target);
  • 发起网络请求
    lib/client.js:24
    const r = await fetch(DSH_PATH + 'api/list');
  • 发起网络请求
    lib/client.js:31
    const det = await fetch(DSH_PATH + 'api/state?runId=' + encodeURIComponent(run.runId));
  • 读取本地文件
    lib/runtime.js:488
    .update(await readFile(originalScriptPath))
  • 执行外部命令来自配置/变量
    lib/runtime.js:566
    const child = spawn(this.nodeBin, [bootstrapAbs, childArgvPath], {
  • 读取本地文件
    lib/runtime.js:1171
    const st = await stat(abs).catch(() => null);
  • 读取本地文件
    lib/runtime.js:1176
    content = await readFile(abs, 'utf8');
  • 读取本地文件
    lib/runtime.js:1469
    const st = await stat(abs).catch(() => null);
  • 读取本地文件
    lib/runtime.js:1474
    body = await readFile(abs, 'utf8');
  • 读取本地文件
    lib/runtime.js:2265
    const facadeSrc = await readFile(resolvePath(fileURLToPath(import.meta.url), '..', 'facade.d.ts'), 'utf8');
  • 执行外部命令来自配置/变量
    lib/runtime.js:2333
    const child = spawn(this.nodeBin, args, {
  • 删除本地文件递归
    lib/runtime.js:2367
    try { await fsPromisesRm(tmpDir, { recursive: true, force: true }); }
  • 执行外部命令来自配置/变量
    lib/runtime.js:2471
    const child = spawn(this.nodeBin, args, {
  • 删除本地文件递归
    lib/runtime.js:2496
    fsPromisesRm(tmpDir, { recursive: true, force: true }).catch(() => { });
  • 执行外部命令来自配置/变量
    lib/runtime.js:3286
    child = spawn(cmd, args, {
  • 执行外部命令固定命令
    lib/runtime.js:3783
    child = spawn('git', args, {
  • 写入本地文件
    lib/runtime.js:4678
    await fsPromisesMkdir(dir, { recursive: true });
  • 写入本地文件
    lib/runtime.js:4683
    await writeFile(tmpPath, JSON.stringify(snap, null, 2), 'utf8');
  • 写入本地文件
    lib/runtime.js:4684
    await rename(tmpPath, filePath);
  • 删除本地文件
    lib/runtime.js:4687
    try { await unlink(tmpPath); } catch (_) { }
  • 读取密钥环境变量
    lib/llm.js:28
    if (process.env.DEEPSEEK_API_KEY) return process.env.DEEPSEEK_API_KEY.trim();
  • 发起网络请求
    lib/llm.js:102
    res = await fetch(endpoint.baseUrl + COMPLETIONS_PATH, {
  • 读取本地文件
    lib/dwf/durable-journal.js:107
    if (!existsSync(file)) return;
  • 读取本地文件
    lib/dwf/durable-journal.js:110
    raw = readFileSync(file, 'utf8');
  • 写入本地文件
    lib/dwf/durable-journal.js:187
    mkdirSync(this.dir, { recursive: true });
  • 写入本地文件
    lib/dwf/durable-journal.js:188
    writeFileSync(tmp, JSON.stringify(snap), 'utf8');
  • 写入本地文件
    lib/dwf/durable-journal.js:189
    renameSync(tmp, file);
  • 读取本地文件
    lib/dwf/durable-journal.js:193
    try { if (existsSync(tmp)) unlinkSync(tmp); } catch (_) { }
  • 删除本地文件
    lib/dwf/durable-journal.js:193
    try { if (existsSync(tmp)) unlinkSync(tmp); } catch (_) { }
  • 读取本地文件
    lib/dwf/durable-journal.js:330
    entries = readdirSync(this.dir, { withFileTypes: true });
  • 写入本地文件
    packages/dynamic-workflow-runtime/src/child-entry-file.ts:78
    mkdirSync(dir, { recursive: true });
  • 写入本地文件
    packages/dynamic-workflow-runtime/src/child-entry-file.ts:81
    writeFileSync(join(dir, ".gitignore"), "*\n", { encoding: "utf8", flag: "wx" });
  • 写入本地文件
    packages/dynamic-workflow-runtime/src/child-entry-file.ts:86
    writeFileSync(path, source, "utf8");
  • 执行外部命令来自配置/变量
    packages/dynamic-workflow-runtime/src/harness.ts:279
    child = spawn(
  • 发起网络请求
    public/editor.js:763
    const res = await fetch(api('/script-content'), {
  • 发起网络请求
    public/editor.js:782
    fetch(api('/samples')).then((r) => r.json()).then(({ samplesDir }) => {
  • 发起网络请求
    public/editor.js:801
    const res = await fetch(api('/extract-commands?scriptPath=' + encodeURIComponent(scriptPath)));
  • 发起网络请求
    public/editor.js:834
    const res = await fetch(api(endpoint), {
  • 发起网络请求
    public/editor.js:898
    await fetch(api('/stop'), {
  • 发起网络请求
    public/editor.js:907
    const r = await fetch(api('/state') + '?runId=' + currentRunId);
扫描于 2026/11/4(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

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

社区实装还没有人打卡 · 装过的第一个就是你
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

把 ZCode 风格的动态工作流语义带进 dsh(桌面版 v0.2.0-rc.2+):写 JS 工作流脚本,并行拉起 LLM 智能体和 shell 门禁,实时进度以浮层卡片流式显示在聊天界面。

README

由 DeepSeek 最新模型翻译生成
dsh-workflow-runner 🇬🇧 English · 🇨🇳 中文 把 ZCode 风格的 dynamic-workflows 语义搬进 [dsh][dsh] Web UI。 写一小段 JS workflow 脚本,使用顶层 await 友好的 facade (phase / log / report / agent(name).ask(prompt) / world.run(cmd, args)), 插件把它跑在隔离的 Node 子进程里,实时把进度广播到聊天输入区按钮、每轮尾巴卡片和浮动监控点上。 [dsh]: https://github.com/deepseek-ai/dsh 目标宿主:dsh 桌面版 profile,V0.2.0-rc.2 及以上版本。 与 [dsh-agent-teams][dteams] 完全独立 —— 不依赖它,不与之协作,卸了它本插件照常工作。
展开完整文档(README 剩余 1 节)
dsh-workflow-runner

🇬🇧 English · 🇨🇳 中文

把 ZCode 风格的 dynamic-workflows 语义搬进 [dsh][dsh] Web UI。
写一小段 JS workflow 脚本,使用顶层 await 友好的 facade (phase / log / report / agent(name).ask(prompt) / world.run(cmd, args)), 插件把它跑在隔离的 Node 子进程里,实时把进度广播到聊天输入区按钮、每轮尾巴卡片和浮动监控点上。

[dsh]: https://github.com/deepseek-ai/dsh

目标宿主:dsh 桌面版 profile,V0.2.0-rc.2 及以上版本。
与 [dsh-agent-teams][dteams] 完全独立 —— 不依赖它,不与之协作,卸了它本插件照常工作。
[dteams]: https://www.npmjs.com/package/@nanmicoder/dsh-agent-teams

你会拿到

- 三个 UI slot(通过 cordis 注册):
- conversation.composer.dock —— ▶ Workflow 按钮(点击在新窗口打开编辑器)
- conversation.chat.turnTail —— 每轮 assistant 尾巴下的被动监控卡
- shell.overlay —— 运行中时右上角的浮动小点

- standalone Web 应用(/workflow/ 路径),含:
- 脚本选择器(三个样本)、文件路径、源码预览
- ▶ Run / ◼ Stop 按钮
- 实时 phase 进度、子代理活动、报告列表、事件日志

- 服务端运行时:spawn 用户脚本为 Node 子进程,stdin/stdout 上跑 JSON-RPC,使用与 dsh balance 同样的 key 解析路径调 DeepSeek chat-completion,跑 shell 命令并有可控超时。

安装

把插件按 dsh bundle 标准装入。从 dsh 宿主(它跑在 WSL)执行,desktop profile:

git clone https://github.com/gamelongtim-ux/dsh-workflow-runner.git
cd dsh-workflow-runner
dsh plugin --profile desktop add file:"$PWD"

然后重启 dsh web。聊天输入区里能看到 ▶ Workflow 按钮。

📌 如果同版本 pnpm add file: 不重新拷贝(pnpm 12 的怪行为),改 package.json 里的 version,或者直接用 update.cmd。

把这个插件给其他 dsh 用户用

下游 dsh 用户在"添加插件"对话框里有三种装入路径,看你打算怎么分发来选:

| 路径 | 在 dsh "添加插件"对话框里粘贴 | 备注 |
| GitHub URL (当前在用) | https://github.com/gamelongtim-ux/dsh-workflow-runner | 永远可用;拉的是最新 main HEAD |
| 本地路径 | <本地 clone 的绝对路径> | 想跟你的本地编辑同步改;搭配 update.cmd |
| npm 包名 (暂未发到 npm) | dsh-workflow-runner | 国内走镜像源更快、可锁版本,但要先有维护者发到 npmjs.org |

dsh 桌面"添加插件"对话框里的"中国大陆镜像源"是读端加速;包本身还得能经 GitHub(或 npmjs.org)拿到。

独立运行(不需要 dsh)

测脚本很好用:

node lib/standalone.js # 监听 127.0.0.1:7910

浏览器开 <http://127.0.0.1:7910/>,选个样本即可。

写一个 workflow

脚本是 ES module (.mjs),默认导出 async function main():

'use strict';
const { agent, world, phase, log, report } = globalThis.__dsh;

export default async function main() {
phase('Plan');
const draft = await agent('planner', {
system: 'You are a senior algorithm textbook author.',
}).ask('用三段话解释匈牙利算法');

phase('Critique');
const issues = await agent('critic', {
system: '列出 3 个最关键遗漏,每个 ≤25 字。',
}).ask(draft);

phase('Gate');
const wc = await world.run('node', ['-e',
'process.stdout.write(String(arguments[0].split(/\\s+/).filter(Boolean).length))',
'--', draft,
], { timeoutMs: 5000 });
if (wc.exitCode !== 0) log('gate 警告 exit=' + wc.exitCode, 'warn');

report({ draft, issues, wordCount: Number(wc.stdout) }, 'final');
phase('Done');
return { ok: true };
}

Facade 参考

| 调用 | 返回 | 备注 |
| phase(name) | Promise<{ok:true}> | 标记一个 phase。所有已完成的 phase 都在 UI 列出 |
| log(message, level='info') | Promise<{ok:true}> | 流到事件日志。level ∈ info, warn, error, debug |
| report(item, tag=null) | Promise<{ok:true}> | 在 Reports 面板露出结构化项。item 可以是任意可 JSON 序列化的值 |
| agent(name, opts).ask(prompt) | Promise<{content, usage}> | 按名创建(或复用)子代理;同名复用保留历史。opts ∈ {system, model, temperature, maxTokens} |
| agent(name).close() | Promise<{closed:true}> | (可选)提示;历史随 run 结束释放 |
| world.run(cmd, args, opts) | Promise<{exitCode, signal, stdout, stderr, durationMs}> | spawn 本地 shell 命令。非零退出码是值,不抛异常。opts.cwd / env / timeoutMs 可配 |

第一个参数 agent(name, opts) 可只写 agent('planner');opts 可省。

样本

samples/ 里有三份:

| 文件 | 模式 |
| smoke.mjs | phase + log + world.run + report —— 不调 LLM,可无 key 跑通 |
| planner-critic.mjs | planner → critic → planner 同名复用带 critique 的修订 |
| fanout-summarize.mjs | 三个并行 summarizer-N,再 reducer 汇总成 cheatsheet |

架构

┌────────────────────┐ stdio 行分隔 JSON ┌──────────────────────────┐ │ 用户 .mjs 脚本 │◀──── RPC + notify ─────▶│ Node 子进程 │
│ (subprocess) │ │ runner-bootstrap.mjs │
└────────────────────┘ └──────────┬───────────────┘
│
▼
┌──────────────────────┐
│ WorkflowRuntime │
│ (cordis 宿主) │
│ │
│ - agent 状态表 │ │ - 通过 ctx 调 LLM │ │ - shell 调度 │ │ - SSE 广播 │ └──────┬───────┬────────┘ │ │ ┌──────────────────────────┘ └───────────────────────────┐ ▼ ▼ ┌──────────────────┐ ┌──────────────────┐ │ webServer 路由 │ │ dsh 聊天 UI │ │ /workflow/api/* │ ─ SSE 事件流 ──▶ ┌────────────┐ │ (三个 slot: │ │ /workflow/ │ │ iframe │ │ composer, turn- │ └──────────────────┘ │ editor + │ │ tail, overlay) │ │ viewer │ └──────────────────┘ └────────────┘

LLM 子代理直接打 DeepSeek /v1/chat/completions,优先通过 ctx.llm.resolveCallConfig(...) 取,
回退到与 [dsh-usage-dashboard 的 balance 模块][usage-dash-balance] 完全一致的
DEEPSEEK_API_KEY / $DSH_HOME/.credentials.yaml 解析路径。

[usage-dash-balance]: https://github.com/gamelongtim-ux/dsh-usage-dashboard

排错

"启用失败: dsh: warning: 1 entry did not activate dsh-workflow-runner (dsh-workflow-runner): failed to import"

在 v0.1.3 修复了——去掉了 @deepseek-ai/schemastery 这个 peer 依赖。dsh 的 cordis 加载器解析裸 import 时先在 bundle 自己的 node_modules 找,新装时 schemastery 提升到宿主 profile 不一定找得到。如果你装的是 v0.1.1 / v0.1.2,卸了重装 GitHub URL 那条,会拉到 v0.1.3,零三方依赖。

装完没看到 ▶ Workflow 按钮

按这个顺序排查:

1. 插件页里有 dsh-workflow-runner 且开关是开的
2. 拨完开关后重启 dsh(任务管理器 → DeepSeek Harness.exe → 结束任务 → 重开)。bundle 是在进程启动时加载,不是拨开关时。
3. 你在新会话里看(左下角 → 新会话),不是装插件之前打开的老会话
4. dsh 桌面版是 V0.2.0-rc.2 或以上——老版本可能没有 conversation.composer.dock 这个 slot

"Lockfile failed supply-chain policy check" / ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION

不是本插件本身的问题——dsh-workflow-runner 零三方运行时依赖。pnpm 验 lockfile 时整个 profile 的所有条目都过 minimumReleaseAge,刚发的包(默认窗口 24h)直接拒。错误信息里点名的那个包(比如 dsh-workbuddy-connect@0.7.5 was published at 2026-10-14T17:23Z)才是元凶。

两条路:

- 等那个包超过策略窗口(通常 1-3 天)再重试
- 绕过 pnpm 直接拷:

$D = "$env:USERPROFILE\.dsh\profiles\desktop\node_modules\dsh-workflow-runner"
$S = "D:\ZcodeStorage\.zcode\workspace\default\dsh-workflow-runner"
New-Item -ItemType Directory -Force -Path $D | Out-Null
Copy-Item "$S\lib","$S\public","$S\samples","$S\package.json","$S\cordis.patch.yml"
-Recurse -Force -Destination $D

拷完重启 dsh。如果"插件"页还是没出现,手填 ~/.dsh/profiles/desktop/cordis.patch.yml:

- insert:
- id: dsh-workflow-runner
name: dsh-workflow-runner
config: { path: /workflow }

显式不做

- TypeScript 类型检查 —— 只用 JS + JSDoc
- hole<T>() 运行中人工接管 —— 没有交互模式
- 缓存复用 amend —— 改脚本要重跑
- Settings → Plugins 上的 Plugin configuration 卡片
- 运行历史持久化 —— 仅内存保存,关 dsh 即丢

协议

MIT
预览分享卡片长什么样 ↓gamelongtim-ux/dsh-workflow-runner
分享 · DeepSeek Harness Hub
gamelongtim-ux/dsh-workflow-runner

编写 JS 脚本并行调度多个 AI 代理与命令

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