Workflow One
August 29, 2026 · View on GitHub
7 个默认 Cordis 插件把 AI 对话自动创建的物业智能体编排(可视化 DAG + 节点级真实 agent)装进任何 DeepSeek Harness (dsh);brand 保留为独立可选插件:
| 包 | 安装方式 | 职责 |
|---|---|---|
dsh-ccpg-tools | 默认 | feishu_doc_read / feishu_doc_write 注册 ctx.tools |
dsh-ccpg-orchestrator | 默认 | DAG 编排 + 节点级 ctx.agents 进程内 agent + QuickJS 脚本节点 + /wf1/api/* HTTP/SSE |
dsh-ccpg-web | 默认 | 画布静态托管 /wf1/ |
dsh-ccpg-canvasui | 默认 | 官方 dsh Web UI 输入框工作流按钮 + /workflow-one 触发源(对话里弹工作流库直达运行/打开)+ better-sidebar「工作流」画布(iframe 载 /wf1/,软依赖) |
dsh-ccpg-document-preview | 默认 | PDF/DOCX/XLS(X)/PPTX 本地全屏预览(pdfjs/docx-preview/sheetjs/@file-viewer/pptx,inline workers、无第三方上传);旧 DOC/PPT 走下载 |
dsh-ccpg-larkauth | 默认 | 飞书账号扫码登录(lark-cli Device Flow);启动自举安装 lark-cli、user token 后台续约、feishu-cli 技能种子 |
dsh-ccpg-llm-guard | 默认 | 拦截模型返回的空 id/name/arguments 工具调用,自动重试且不污染会话 |
dsh-ccpg-brand | 独立可选 | 品牌定制(CCPG logo + 聊天 hero 标题);默认安装与聚合包均不包含 |
安装与使用
普通 dsh 有 release/源码两种路径,前提是 Node ≥ 22.15.0(dsh 本体需要 node:zlib 的 zstd API)、npm i -g @deepseek-ai/dsh。Harness Desktop 自带运行时,走下面的原生插件命令。
Harness Desktop
从 Desktop 托盘打开 Open DSH Terminal;该终端已绑定当前 profile:
dsh plugin add dsh-harness-one
安装后重启 Desktop,让新 bundle 进入 Loader 组合。compatibility 与 advanced 模式都继续使用普通 DSH Web Client;画布、同源 /wf1/api/*、侧栏和预览无需 Desktop 专用注册。飞书账号页首次点击「自动安装」时,插件通过公开 desktopPnpm service 把固定版本 lark-cli 安装到当前 profile,并在 profile 切换或退出时取消仍在运行的操作。
Desktop 不要运行 setup.sh:它用于普通 dsh,会创建/修改 profile、依赖系统全局 dsh/npm 并写固定 Web 端口;Desktop 自己管理这些内容,默认随机 loopback 端口应保留。
安装细节、环境差异表、常见问题(扫码无反应 / 找不到 better-sidebar / 页面空白)与开发兼容契约,见 DESKTOP.md。
A. 普通用户 · release 包(推荐,无需本仓库源码)
# 1. 下载 release 包(GitHub Releases 页拿最新 tag 的 asset)
curl -LO https://github.com/chumingjun/dsh-harness-one/releases/download/<tag>/dsh-harness-one-plugins-<tag>.tar.gz
tar -xzf dsh-harness-one-plugins-<tag>.tar.gz # 解出 dsh-plugins/ 目录(自带全部构建产物 + vendor 件)
# 2. 一键安装(聚合模式:一个包装齐 7 插件 + better-sidebar,并建好独立 profile)
cd dsh-plugins
sh setup.sh --one wf1 4021 # profile 名/端口可自定义
# 3. 启动
sh start.sh wf1
浏览器打开 http://127.0.0.1:4021/ 即用:
- 右下/设置进入**「模型」页**选模型、保存 key(dsh 官方配置面,存于 dsh 用户级 credentials)
- 点聊天输入框左侧工作流图标 → 右侧栏展开画布;拖节点或直接在聊天里说"帮我建一个××工作流"
- 建图/运行过程在消息流以卡片呈现(操作摘要、完成度 x/y、点击卡片跳画布)
- 独立全屏画布:新标签页开
http://127.0.0.1:4021/wf1/
飞书消息通知节点
「消息通知」是运行级观察器,可接在线路中作为透传节点,也可不连线独立放置。当前内置飞书 provider,调度层使用渠道无关事件模型,后续接入钉钉或企业微信无需修改工作流运行逻辑。
配置步骤:
- 在画布「设置」添加飞书自建应用 App ID / App Secret,并在飞书开发者后台开通机器人发消息权限。
- 添加消息通知节点,选择飞书渠道及凭据。
- 推送群聊时选择「群聊」并填写
oc_开头的chat_id,同时确保机器人已在群内。 - 推送私聊时选择「私聊」并填写
ou_开头的用户open_id;应用可用范围需包含该用户,且机器人与用户需具备可发消息关系。 - 选择「仅运行结束」或「每个节点完成」。后者会发送业务节点成功/失败进度,并在整次运行结束时再发送结果卡。
结束卡优先摘要输出节点结果;无输出节点时回退到最后一个成功业务节点。卡片还包含进度、节点状态统计、耗时、起止时间、失败详情或取消原因。通知节点会对摘要做长度限制和常见密钥脱敏;发送失败只写入该节点的 notification.sent/failed/lastError,不改变业务运行状态。
适合定时巡检群播报、长流程进度同步、异常值班告警,以及向流程负责人私聊发送结果。飞书扫码登录由 dsh-ccpg-larkauth / lark-cli 管理用户身份;消息通知节点使用的是画布中保存的自建应用凭据,两者不要混用。
release 包特性:拿到即装(画布/依赖/聚合壳全带);better-sidebar 的钉版本 tgz 在 vendor/(断网/上游下架也能装);装完的 dsh-plugins/ 目录保留着,后续升级见下方「升级」。
升级
入口在 dsh 官方设置面板 → Workflow One → 一键升级(版本中心),按安装来源自动分流:
| 安装来源 | 升级动作 |
|---|---|
源码 link(目录上方有 .git) | 拒绝脏工作树 → git pull --ff-only → 画布/canvasui 双构建重建 → orchestrator 依赖兜底 |
离线包解包(link、无 .git) | 提示下载新版 tarball 原地解包覆盖该目录,完成后回到面板再点一次收尾重链 |
| npm 安装(纯版本号依赖) | 复用已装聚合包自带安装器 remove→add 最新版;pnpm 放行预写内含,无需源码在场 |
npm 渠道等价命令行(无需源码):老版(dsh-ccpg-one)在设置面板「Workflow One → 检查更新」一键迁移到 dsh-harness-one;此后重跑一次 npx dsh-harness-one <profile> 即为升级。
数据安全边界:工作流与运行记录(工作区 .workflow-one/ SQLite)、定时触发配置(state/triggers.json)、飞书凭据(dsh 用户级/lark-cli)全部在升级触达面之外——升级与重装都不需要迁移数据。
升级执行带单飞锁与二次确认;改完必须彻底重启 dsh 才生效(HMR 缓存模块)。检查更新会访问 npm registry,离线时仅该按钮不可用。
B. 开发者 · 源码(本仓库)
git clone https://github.com/chumingjun/dsh-harness-one.git
cd harness-one/dsh-plugins
npm test # (可选)先跑全量单测
sh build-web.sh # 构建画布——产物不入库,源码安装必跑
sh setup.sh --one dev 4021 # 安装(或逐插件:sh setup.sh dev 4021)
sh start.sh dev
开发循环:
- 改画布前端(
web/)→sh build-web.sh→ 刷新页面 - 改 canvasui 官方 UI 侧(
dsh-ccpg-canvasui/src/client.js)→sh build-canvasui.sh→ 彻底重启 dsh(HMR 缓存模块,pkill dsh再起) - 改引擎(
dsh-ccpg-orchestrator/lib/)→ 对应面测试(cd dsh-ccpg-orchestrator && for t in test/*.test.mjs; do node "$t"; done)→ 重启 - 发版:
npm run publish:dry-run验证 npm 包;sh dsh-plugins/publish-npm.sh按子包→聚合包顺序发布;Git tag 仍由 release.yml 生成 tarball + boot-smoke asset
可选件开关(--one 模式)
启动前 export(源码/setup.sh --one 渠道可写进工作区 .env;npm 渠道的 sidebar 开关在安装时生效,见下表注):
| 开关 | 效果 | 生效位置 |
|---|---|---|
CCPG_NO_LARK=1 | 不加载 larkauth(飞书扫码登录) | 运行时(bundle patch) |
CCPG_NO_PREVIEW=1 | 不加载 document-preview(预览退化为下载) | 运行时(bundle patch) |
CCPG_NO_GUARD=1 | 不加载 llm-guard(不建议关) | 运行时(bundle patch) |
CCPG_NO_SIDEBAR=1 | 不装 better-sidebar(官方 UI 内工作流侧栏宿主不可用,独立 /wf1/ 入口不受影响) | 安装时(npm 渠道:npx dsh-harness-one 检测到即 dsh plugin remove dsh-better-sidebar;源码渠道:setup.sh 未装它即无) |
CCPG_ONLY_CORE=1 | 一键只留核心:tools/orchestrator/web/canvasui(+ 移除 sidebar) | 运行时 + 安装时 |
better-sidebar 的挂载由它自己的
dsh.bundle.patch提供(聚合层不再 insert——双 insert 会 duplicate route)。因此关闭 sidebar 无法在运行时做,npm 渠道由安装器移除依赖实现。
dsh-ccpg-brand不属于聚合包,需要时必须单独安装(dsh plugin --profile <name> add <repo>/dsh-plugins/dsh-ccpg-brand)。聚合模式不要再单独 add 其余 7 个子插件或手写 insert 行——双层挂载 = duplicate prefix route。dsh plugin --profile <name> remove dsh-harness-one一次卸掉全部默认插件(单包形态)。
模型完全交给 dsh 自带配置:agent 走 dsh 默认模型栈(
deepseek-official),key 与选型在官方 UI「模型」页配置;setup.sh 的 patch 只写端口覆盖,不写任何 provider。要加自定义 provider,按 dsh 原生方式改 profilecordis.patch.yml或~/.dsh/settings.yaml。
远程访问(局域网/Tailscale):把 profile
cordis.patch.yml里 webserver 的host改为0.0.0.0。dsh agent 有 bash 能力,仅在可信网络开放。
画布:http://127.0.0.1:4021/wf1/
setup.sh 做了什么
- 校验 7 个默认插件的分发目录完整(package name 逐一核对 +
dsh.bundle.patch声明在场)+ 画布产物存在性(web-dist 缺失即提示先跑 build-web.sh) - 装 orchestrator 真依赖(ajv/cron-parser/QuickJS WASM)并跑 QuickJS smoke
- canvasui bundle 校验(
build-canvasui.sh --check,不一致则重建——lib/client.js由src/client.js生成,不入库) - 装 lark-cli(飞书官方 CLI,
~/.local/npm-global)并固定默认身份 user - 建
~/.dsh/profiles/<name>(dsh-base bundle) dsh plugin add7 个默认插件——各插件自带dsh.bundle.patch(包内cordis.patch.yml),add 一步完成安装+进 bundles 层+挂载(与 dsh-better-sidebar 的 npm 分发同一机制;失败即中止,不留半成品 profile)- 依赖引导:dsh SDK 是 dsh 包内层 bundled deps,registry 版本滞后且插件解析路径够不到——
bootstrap-deps.sh软链进插件源码目录(npm 安装渠道则无需此步:插件实体落在 profile 内,dsh 启动时的~/.dsh/profiles/node_modules扁平兜底自动接通运行实例的 SDK) - 写
cordis.patch.yml——只写 webserver 端口覆盖(模型 provider 走 dsh 自带体系,不在此写) - 装 dsh-better-sidebar(npm 包,自带 bundle patch 一步挂载):官方 UI 右侧工作台侧边栏——canvasui 往它注册「工作流」tab。版本由
dsh-harness-one精确依赖统一;release 包携带同版本 vendor tgz
双挂载警告:插件挂载行已由各包
dsh.bundle.patch提供,profile 的cordis.patch.yml里不要再手写同名- insert行——两层都生效会重复注册路由,boot 时 duplicate prefix route 报错。
npm 直装
聚合包和 7 个默认插件均为带 dsh.bundle.patch 的自描述包。pnpm 11 环境推荐(见下):
npx dsh-harness-one myprofile # 预写 pnpm 11 放行(node-pty/koffi 构建许可)再一步装齐
也可直接用官方命令:
dsh plugin --profile myprofile add dsh-harness-one
pnpm 11 注意(issue #24):
dsh plugin add是 profile 目录里裸跑 pnpm,聚合依赖链里的node-pty(dsh-better-sidebar 传递依赖,原生模块)会被 strict-dep-builds 拦下:安装非零退出、且 pnpm 往 profile 的pnpm-workspace.yaml写非法占位符node-pty: set this to true or false,把pnpm approve-builds与重跑 install 一起堵死——重试无效。0.5.0 起用npx dsh-harness-one安装即可(它先把放行写对再装,幂等,可反复重跑);已中招的 profile 也能用它自愈。
需要 CCPG 品牌外观时,再显式安装独立插件:
dsh plugin --profile myprofile add <repo>/dsh-plugins/dsh-ccpg-brand # brand 不在 npm,用源码/离线包路径装
模型:dsh 默认模型栈(deepseek-official)开箱即用,key 在官方 UI「模型」页保存;自定义 provider 走 dsh 原生配置(profile cordis.patch.yml 的 llm-pi-ai.providers,key 由 apiKeyEnv 声明走环境变量)。插件自身不存任何 key。
数据位置
- 技能目录:dsh 原生
~/.dsh/skills/~/.agents/skills(ctx.skills发现;feishu-cli 技能由 larkauth 启动时自动种子到~/.dsh/skills) - Workflow One 数据:当前 dsh 会话工作目录下的
.workflow-one/;工作流与运行记录存于workflow-one.sqlite,state/attachments/runtime 继续使用文件系统(整体 gitignore) - 节点执行:agent 以真实工作区根为 cwd,可读取项目文件;交付物写入
.workflow-one/runtime/<workflow>/<run>/nodes/<node>/workspace/,成果快照只扫描该节点目录 - 旧版
~/.dsh/plugin-data/dsh-ccpg-orchestrator与插件包data/:首次进入工作区时只导入一次,之后不再写入 - agent 会话:
~/.dsh/sessions/(dsh 持久化,zstd JSONL) - 飞书 token:由 lark-cli 自管(
~/.larkcli/),插件零落盘
打包发布
pack.sh <tag>:7 个默认插件 + 独立可选 brand 清单校验 → 画布双构建 → orchestrator 依赖 → canvasui bundle 重建并 --check → rsync 组装(清运行时数据)→ dist-release/dsh-harness-one-plugins-<tag>.tar.gz。通用发布归档仍携带 brand 源包供显式安装,但 setup.sh 和单包 dsh-harness-one 都不会自动安装它。CI(release.yml)同源执行并作为 release asset 上传。
sh publish-npm.sh --dry-run 会装配并验证单包 dsh-harness-one(assemble-one.sh 把 7 个插件合并为一个 npm 包:单 loader entry + 合并 client bundle)——这是唯一上 npm 的包;brand 不上 npm,仅随 GitHub Release 离线包分发。老 8 包(dsh-ccpg-one + 7 子包)已停更,发布时统一 deprecate 指向新包。安装冒烟会校验「无 @deepseek-ai SDK 泄漏」(peer 自动安装会遮蔽 dsh 全局版本导致官方 UI 400)。去掉 --dry-run 才上传官方 npm registry;tag 必须与聚合包版本一致。GitHub release.yml 先上传 release 资产,再使用仓库 Actions Secret NPM_TOKEN 按子包→聚合包顺序发布,失败后可安全重跑(已存在版本会自动跳过)。
已知边界
- SDK 软链指向本机 dsh 安装——换机器重跑
setup.sh自动重链 - npm 首次发布需要仓库所有者配置具备
dsh-harness-one发布权限的 granular token 为 Actions SecretNPM_TOKEN(brand 不上 npm,仅随 Release 离线包);代码与包内容不保存 token