# DSH-pipeline-kernel

> DSH 多 Agent 管线管理内核：定义管线、推送任务、自动路由、台账三振、巡检自愈、面板归档与打包复用，与具体业务无关。

## Metadata

- Author: [@not-big-dog](https://github.com/not-big-dog)
- Repo: <https://github.com/not-big-dog/DSH-pipeline-kernel.git>
- GitHub: [not-big-dog/DSH-pipeline-kernel](https://github.com/not-big-dog/DSH-pipeline-kernel)
- Stars: 28
- Language: TypeScript
- License: [MIT](https://spdx.org/licenses/MIT.html)
- Topics: `agent`, `cordis`, `dsh`, `dsh-plugin`, `multi-agent`, `pipeline`
- Forks: 0
- Open Issues: 0
- Last push: 2026-08-20T16:51:50.000Z
- Added: 2026-08-16T00:00:00.000Z

## Install

```bash
dsh plugin --profile web add github:not-big-dog/DSH-pipeline-kernel
```

## Wiki

## 一句话定位
DSH 多 Agent 协作的"管线管理内核"——把 supervisor → designer → prompter → reviewer 这类单向任务链抽象成可定义、可部署、可巡检的"管线"（pipelines 表里的一行配置），提供任务板、台账、注册表、自动路由、巡检自愈、控制面板与打包复用能力，但内核本身不绑定任何具体业务。

## 核心能力
- 管线一等公民与归档：定义/部署/反定义管线（`pipeline_define`/`pipeline_deploy`/`pipeline_undefine`），归档（`pipeline_archive`/`pipeline_unarchive`/`pipeline_purge`）只打标记、可恢复
- 任务板与自动路由：推送/领取/完成/取消/查询（`pipeline_push`/`pipeline_claim`/`pipeline_done`/`pipeline_cancel`/`pipeline_list`），完成时按 `route:<角色|UID>` 标记自动路由下一环
- 角色注册与播种：`pipeline_seed` 给未注册角色建会话并写注册表，节点目录按 chain 自动编号（节点0=主管，节点1..N=业务角色）
- 台账与三振：`pipeline_ledger_write`/`pipeline_ledger_list` 记录交付物变更；`pipeline_strike` 累计 rework 次数达到阈值自动给任务打 blocked
- 巡检自愈与 Web 面板：watchdog 默认 5 分钟扫一次唤醒空闲目标并自愈僵尸任务；Web 右下角胶囊展开右侧全高边栏（活动/管线/新建/归档四标签，1 秒轮询快照）
- 打包复用与斜杠命令：`pipeline_pack` 把整条管线打成 JSON+MD，配合 `pipeline-create` 的 `fromPack` 一键恢复定义并播种；`/pipeline gate|status|pack` 三子命令

## 技术实现
- **语言**: TypeScript（src/）+ Node.js ESM（编译产物在 lib/）
- **关键依赖**: `@deepseek-ai/cordis`（4.x 插件框架）、`@deepseek-ai/dsh-storage-domain`（域表 JSON 后端）、`@deepseek-ai/dsh-tools`（defineTool 工具定义）、`@deepseek-ai/dsh-agent` + `@deepseek-ai/dsh-llm`（会话运行时，封装在 `lib/agent-runtime.js` 窄适配层里）
- **架构模式**: Cordis 双面插件；node 端走标准 Cordis 规范 `name + Config (zod Schemastery) + inject + apply`，注册 20 个 `pipeline_*` 工具 + 1 个 `/pipeline` 斜杠命令 + 6 个 Web 端点；client 端用 `ctx.locale.register` 注册中英词典并挂载 React 控制面板到 body portal
- **入口文件**: `lib/index.js`（node 端 Cordis apply）+ `src/client/index.tsx`（浏览器端挂载入口）

## 适用场景
需要在 DSH 上编排多 Agent 单向任务链（典型如：supervisor 收集需求 → designer 出方案 → prompter 写提示词 → reviewer 审 → 生成交付物），希望统一看任务进度、管交付清单、跨会话自动路由与提醒的场景。普通"单 Agent + 单次问答"用不到这个插件；超过两个会话、且彼此需要按角色接力的项目最适合装。

## 前置依赖与兼容性
| 依赖 | 最低版本 | 说明 |
|---|---|---|
| DSH（deepseek-harness） | `0.1.0-rc.8` | `package.json` peerDependencies 锁 `^0.1.0-rc.8`，rc.8 之前会因 `@deepseek-ai/cordis 4.x`、`webServer`/`workspaceRegistry`/`agentDefaultModel` 等服务名变化而装不上 |
| Node.js | `^22.19.0 \|\| >=24.0.0` | `package.json#engines.node`；低于 22.19 会因 zod 4 与内置 fetch 行为差异导致工具校验失败 |
| 平台 | macOS / Windows / Linux | `lib/web.js:317-334` 的 `openFolder` 在三平台分别调 `open` / `explorer` / `xdg-open`；其余逻辑纯 ESM + node:fs/node:path，无平台相关代码 |
| 原生模块 | 无 | 不引入 node-pty / better-sqlite3 等原生模块；只用 `node:fs` `node:path` `node:os` `node:child_process` `node:crypto` `node:url` 等内置模块 |

## 安装方式
```bash
dsh plugin --profile web add github:not-big-dog/DSH-pipeline-kernel
```

## 配置项
所有配置走 `cordis.patch.yml` 的 `pipeline-kernel` 节点（默认写在 `~/.dsh/profiles/web/cordis.patch.yml`），重启 dsh web 生效。

| 配置 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| `projectRoot` | 字符串 | 全局工作区根（管线 `projectRoot` 缺省时回退到这里），所有 inboxDir/产物/打包路径都必须在它之内 | `process.cwd()` |
| `inboxDir` | 字符串 | 角色收件箱根目录（相对工作区），`pipeline_push` 落盘任务单到这里 | `exchange/收件箱` |
| `defaultPipeline` | 字符串 | 任务 tags 没标 `pipeline:<id>` 时归属到的默认管线 id（注意：只是默认值，没有自动建定义） | `default` |
| `watchdogEnabled` | 布尔 | 是否开启无人值守巡检（自愈 + 唤醒 + 静止汇报） | `true` |
| `watchdogIntervalMs` | 数字（毫秒） | 巡检 tick 间隔 | `300000`（5 分钟） |
| `watchdogStallMs` | 数字（毫秒） | 全链静止多长时间视为"卡住"开始汇报主管 | `1800000`（30 分钟） |
| `watchdogWakeCooldownMs` | 数字（毫秒） | 同一任务被补唤醒的最短冷却 | `600000`（10 分钟） |
| `watchdogReportCooldownMs` | 数字（毫秒） | 同一管线汇报主管的最短冷却 | `1800000`（30 分钟） |
| `strikeOut` | 数字 | rework 计数阈值；超过此数任务被打 `blocked` 并建议人工介入 | `3` |

## 常见问题

**Q: 安装之后已有的会话里怎么没有 `pipeline_*` 工具？**

A: 老会话的工具目录在会话创建时就被冻结了，重启 dsh web 只对新会话生效。需要把现有会话关掉、重开一个新会话，让它从更新后的 host 拿工具清单。

**Q: 我用 `pipeline_define` 报 `BAD_INPUT` 非法管线 id，是什么规则？**

A: 管线 id 必须匹配 `^[A-Za-z0-9_-]{1,64}$`（见 `lib/deploy.js:38`）。不能包含 `/`、`\`、空格、中文、空字符串；带点或 `..` 也会被拒，因为 id 同时会被当作注册表 key 和路径片段，禁止路径穿越。

**Q: 控制面板里看到"未注册"的角色，能直接跑任务吗？**

A: 不能。"未注册"指 `registry` 表里 `pipeline/role → sessionId` 这一行缺失；任务会被投递，但收件箱里的任务单没人处理、watchdog 也唤不醒。必须先 `pipeline_seed`（角色定义里带 `preset`）或手动 `pipeline_register`。

**Q: 角色会话是 supervisor 常驻还是 supervisor 按需创建？**

A: 按定义。每个角色（包括 supervisor）由 `pipeline_seed` 调用宿主 `agents.create` + `agentPresets.mount` 各创建一个会话；不常驻、不复用。seed 会校验已注册会话的 cwd 与当前管线工作区是否一致，不一致视为撞车残留会清掉重播。

**Q: 三振机制怎么算一次"重做"？**

A: 看任务 tags 里的 `attempt:<n>`，n 越大代表该任务被打回重做越多。`pipeline_strike {taskId}` 读到 n ≥ `strikeOut`（管线定义里可覆写，回退全局 config）就把 status 改成 `blocked` 并返回"建议升级人工或换方向"提示。`attempt` 不需要手工维护，路由回退或 rework 流程里加上即可。

**Q: 打包出来的 `*.pack.json` / `*.pack.md` 是干嘛的？**

A: `pipeline_pack` 跑的产物——`*.pack.json` 是机器可读的全节点管线定义（含 roles/chain/gates/skill 清单/文档模板清单），`*.pack.md` 是人读的"绿色可复用全节点管线文档"。把这两个文件拿到别的项目，用 Web 路由 `POST /plugins/pipeline-kernel/pipeline-create`、body 带 `fromPack: "<路径>"`，就能一键恢复定义、播种会话并建齐节点目录（见 `lib/web.js:106-173`）。

**Q: 面板点"打开文件夹"不工作？**

A: 路径白名单校验。看面板给的路径是不是工作区内的——`lib/workspace.js:77-87` 用 `isWithin` 强制要求路径在任意已知管线工作区内，绝对路径或 `..` 都会被 `BAD_INPUT` 拒。如果文件夹路径明明合法却仍然失败，可能是 `explorer`/`open`/`xdg-open` 命令在系统上不存在（headless Linux 服务器常见）。

**Q: 内核数据存在哪里？能跨设备同步吗？**

A: 数据走宿主 `ctx.storageDomain`（JSON 后端，4 张表：pipelines / registry / tasks / ledger）。落盘路径由 DSH 宿主决定，DSH rc.8 通常在 `~/.dsh/profiles/web/domains/pipeline_kernel/`。能拷目录就能跨设备，但不要两个设备同时启同一个 profile 写——内核没有跨进程锁。

## 上手难度
进阶 — 用户必须理解 DSH 的 agent/session 模型、preset 体系和多会话协作语义，并自己用 `pipeline_define` 写第一份管线定义（roles/chain/gates），否则装上也只是面板里一直"暂无管线"。

## 已知问题与限制
- 路径硬约束：`artifactRoot` 与 `inboxDir` 必须是工作区下相对路径且不能逃出 `projectRoot`（`lib/workspace.js:18-30`），否则 `pipeline_define` 会抛 `BAD_INPUT`
- 管线 id 与角色名硬约束：必须匹配 `^[A-Za-z0-9_-]{1,64}$`（`lib/deploy.js:38`、`lib/pipeline.js:17-22`），含中文/点号/空格的 id 会被拒
- 域版本号固定：`kernelDomain` 写死 `version: 1`（`lib/domain.js:90`），添加新字段不 bump 版本；如果未来 bump 了版本，旧数据会因为 JSON 后端的 unit 头校验被拒打开，需要做迁移
- Web 控制面板只读 `?archived=1` 才显示归档管线：`lib/web.js:48` 与 `lib/snapshot.js:19`，主视图不包含归档箱
- 巡检不感知 host 重启：watchdog 跑在 DSH 进程内，进程崩溃后再启动时 watchdog 状态丢失，`pipeline_reconcile` 可手动兜底（`lib/tools.js:561-584`）
- 节点目录在打包复用时一次性建齐、新建管线只建主管目录（节点1..N 由主管写完文档后调 `pipeline_mkdirs` 或首次 `pipeline_push` 触发），不会主动催主管补建

---

This document is auto-generated by [deepseek-plugin.org](https://deepseek-plugin.org). HTML page: [DSH-pipeline-kernel](https://deepseek-plugin.org/plugins/not-big-dog/DSH-pipeline-kernel)
Wiki generated by AI (model: `MiniMax-M3`)
