# 任务看板（dsh-task-board）

[English](README.en.md) | 中文

[![npm](https://img.shields.io/npm/v/@firetruck666/dsh-task-board)](https://www.npmjs.com/package/@firetruck666/dsh-task-board)
[![license](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
[![Node](https://img.shields.io/badge/Node-%5E22.19.0%20%7C%7C%20%3E%3D24.0.0-339933)](README.md#环境要求)

DeepSeek Harness 的任务看板插件。它在 Web 界面的侧边栏加一个「任务看板」入口，用五列看板管理任务；任务交给 DSH 自己的会话真实执行，状态自动回写到卡片上。

插件不修改 DSH 源码，卸载后界面恢复原状。看板数据保存在 DSH 主进程（host）一侧，电脑和手机打开同一个部署看到的是同一块板，改动经 SSE 实时同步；窄屏自动进入紧凑布局。

## 目录

<!-- toc:start -->

- [环境要求](#环境要求)
- [安装](#安装)
- [主要能力](#主要能力)
- [数据保存在哪里](#数据保存在哪里)
- [更新](#更新)
- [从源码构建](#从源码构建)
- [贡献指南](#贡献指南)
- [常见问题](#常见问题)
- [命名约定](#命名约定)
- [许可证](#许可证)

<!-- toc:end -->

## 环境要求

- DeepSeek Harness `0.1.6-alpha.2` 或更高。`0.1.6-alpha.2` 是**已验证的最低版本**：这个版本上确认可用。更高的版本会跟随更新，但没有逐一验证过，所以不保证。加载失败时先按「常见问题」里的说明处理。
- Node.js `^22.19.0` 或 `>= 24.0.0`
- pnpm 10 或更高
- DSH 的 `web` profile

本插件只运行在 Web 图形界面上。

## 安装

三种方式，选一种。三条命令都在你自己的终端里执行。

### 从 npm 安装

```sh
dsh plugin --profile web add @firetruck666/dsh-task-board
```

适合日常使用。拿到的是最近一次正式发布的版本。

### 从 GitHub 安装

```sh
dsh plugin --profile web add github:FiretrUCK666/dsh-task-board
```

拿到的是仓库 `main` 分支的最新代码。它和 npm 装出来的一样是可直接使用的安装包，不是开发环境（没有测试、没有构建工具，改不了代码）。适合想第一时间用上还没发版改动的人；稳定性取决于仓库当时的状态。

### 本地开发安装

把仓库下载到本地后，在这个仓库目录里执行：

```sh
pnpm install
pnpm build
dsh plugin --profile web add .
```

这条路径用于改代码。详见下面的「从源码构建」。

本地安装是指向工作目录的链接（不是复制），所以挂载一次即可：改完代码只需 `pnpm build` 再重启 `dsh web`，不必重跑上面的安装命令。改 client 半区刷新页面即可，改 host 半区才需要重启——见「常见问题」里的「改了代码没生效」。

### 三种方式的区别

前两种是安装：拿到的都是可以直接使用的包，只包含发布清单里的文件（运行代码、源码、挂载声明、说明文档）。第三种是开发：拿到的是完整仓库，能改代码、能运行测试。

| | 从 npm | 从 GitHub | 本地 |
| --- | --- | --- | --- |
| 用途 | 安装使用 | 安装使用 | 开发 |
| 拿到什么 | 最近一次发布版 | `main` 最新代码 | 你本地改动 |
| 版本特点 | 稳定 | 最新，可能不稳定 | 你自己决定 |
| 更新依据 | npm 上的版本号 | 仓库最新提交 | 安装的即本地目录，无需更新 |

从 npm 和从 GitHub 装出来的文件基本一致，差异只在版本新旧。想用还没发版的改动就从 GitHub 装，想要稳定版本就从 npm 装。

### 安装之后

停掉正在运行的 `dsh web`，重新启动它。只刷新页面不够——插件的 host 半区在服务端进程里加载，必须重启才生效。重启后刷新页面，侧边栏就会出现「任务看板」入口。

入口和 DSH 自带的「插件」面板并排：点它，看板占用中间主区域，再点侧边栏里的任意会话即可回到对话。插件的设置项在 **设置 → 任务看板**。

卸载：

```sh
dsh plugin --profile web remove @firetruck666/dsh-task-board
```

同样需要重启 `dsh web`。卸载不会删除你的任务数据。

## 主要能力

### 看板与任务

五列：待规划、待办、进行中、待审核、已完成。卡片只显示摘要（标题、描述、来源、状态与自动化徽章、关联会话、下一行动、更新时间），执行窗口和评论时间线在详情页。所有会话跑完自然落「待审核」。

标题、描述、执行 Prompt 三者都不填也能建卡；空 Prompt 的任务不能执行，界面会说明原因。

### 真实执行

点「执行」即开跑，执行会话出现在 DSH 原生会话列表里，可以点进去看完整对话。执行 Prompt 以 `/` 开头时按原生命令执行（例如 `/plan ...` 进入计划模式）。

「任何一次真正执行」都会补全空着的标题和描述（标题取 Prompt 第一行）；已经填写的内容永远保持原样。评论和需求完善不算执行，不会改动它们。

### 多端同步

看板真相在 host，落在 `~/.dsh/storages/dsh_task_board.json`，单文件、人可读、可以直接备份。浏览器是乐观副本：入口点开即进，不等网络，断线时看板照常可用，恢复后自动追平。

两端并发编辑按记录合并，不依赖设备时钟。首次升级时各设备旧的 localStorage 数据会并入 host，不会丢。

定时、巡航、接续这类时间驱动的行为同一时刻只由一个打开的界面执行（host 租约仲裁）。正在看的那台设备持有引擎席位，另一台切到前台后立刻接管。

### 评论与对话

每个会话行打开一个面板：左侧是实时对话（Markdown 预览），右侧是计量、运行配置、评论线程和发送区。留言默认排队，等本条会话空出来按序注入，也可以切成插话立即送达。

支持 `/` 斜杠命令和 `@` 引用（文件、文件夹、会话），与主界面输入框用同一套机制。可以发图片和任意文件：图片在浏览器内先压缩，其他文件按原字节上传。

**附件本身就是内容**：只发一张图或一个文件、不写字也照样发得出去（不要求为附件凑一句正文）。反过来说，如果某次没发出去，界面会直接说明「没能发出去」并保留你的草稿，不会安静地把内容退回来。

agent 挂起时（计划确认、提问）评论区会实时出现交互卡，**就在卡上作答**：选项、自定义答案、上一题/下一题、跳过本题、提交/确认执行/拒绝，与 DSH 原生提问卡是同一批部件、同一套行为（点选项自动进下一题、回车继续、答不完就近报原因）。答完当场结算，模型立刻继续；想回到完整对话，卡上的「去会话回答」与「查看会话」始终可用。同区还显示 to-do、goal、子代理状态，与原生面板同源。

### 需求完善

待规划的任务可以让 AI 调研需求、逐条提问，产出可执行的 Prompt，确认后才应用。完善中的卡片留在待规划列，只显示「完善中」。AI 提问时答案框就出现在这一区里（与评论区同一张交互卡），不必跳回原生会话。

### 自动化

任务详情和看板上的「自动化」总览是同一个编辑器，分「任务自动化」和「会话规则」两块。

- 任务级：按 cron 定时执行，或「完成后接续」——武装即开跑，完成一轮自动接下一轮，可以设次数上限。
- 会话级：给某个会话发指令，内容可以自定义，也可以直接用任务的执行 Prompt；触发方式可以按时间表，也可以每次完成后触发。

每条规则都有发送方式（排队或插话）。每个会话最多一条规则。两半互相独立，关掉任务级计划不影响会话规则。

### 自动巡航

看板头部一键批量执行全部待办任务，带全局并发上限和定时窗口。总开关是主权：窗口只在到点自动开关，增删窗口不改变当前开关状态。

### 并行按会话计算

板头的「并行数」是唯一的闸门，含义是「同时最多跑几个会话」。设成 1 就退回严格串行。同一张卡片里的多条会话互不阻塞；同一条会话内永远按提交顺序一条条来。

### 手机与窄屏

以看板自身的宽度自适应，与侧栏是否展开、窗口多大无关，和桌面用同一套代码。

紧凑档五列变成横向滑动的列，配一排五等分的列导航标签（短名，完整名称保留在无障碍标签里）。板头是确定的两行结构，手机上再确定性地换行，每个控件都保留文字；另有底部拇指栏放新建、通知铃和动态。弹窗、详情、复盘都随面板定尺、可滚动、底部按钮可达。

评论面板在手机上打开后第一眼就是对话内容，发送框钉在面板底边。「上下文与运行配置」默认收起，「评论」默认展开，两处折叠各自在自己的限高区域里滚，不互相遮盖。

触屏没有悬停，因此所有必要说明都做成可点可达，不藏在鼠标提示里。

### 拖拽与整理

卡片拖列移动、同列重排（带精确插入条），拖到列边缘自动滚动。侧边栏的会话和工作区可以直接拖进看板建卡，也可以拖进详情页的会话区添加来源绑定。

板顶整理栏可以批量选色；Ctrl/Cmd 加点击多选后可全选、清选、完成、删除。批量执行只发有 Prompt 的选中卡片。

### 模板与运行配置

详情页可以「存为模板」，新建任务时一键填表。运行配置（Agent、工作区、模型、思考程度、权限）在新建和编辑两处共用同一个编辑器，可以存成预设并设为默认；默认预设被删除或存储异常时回退到部署默认配置。

未发送的输入自动记住草稿。

### 通知与动态

通知中心聚合全板等你处理的会话（审批、计划确认、提问）和未读的待审核任务，支持分组过滤、整组标已读、行内直接处理。动态页把全板近况按自然日分组，支持过滤、筛选和加载更多，点开可以先看富预览再跳转。

## 数据保存在哪里

- 看板真相：`~/.dsh/storages/dsh_task_board.json`（任务台账、巡航、定时预设、运行配置预设、删除墓碑）。单文件原子写入，可以直接备份；删除这个文件等于清空看板。
- 浏览器 localStorage 保存离线镜像和本地状态：`dsh.taskBoard.v1`、`dsh.taskBoard.cruise.v1`、`dsh.taskBoard.presets.v1`、`dsh.taskBoard.runPresets.v1`；草稿 `dsh.taskBoard.drafts.v1` 是设备本地的未发送输入，刻意不跨设备同步。
- 第一次连接时如果本地数据与 host 有分歧，本地副本备份到 `dsh.taskBoard.preSync.v1`，host 为准。
- host 没有挂载存储后端时，看板自动退回纯 localStorage 模式。

## 更新

最直接：看板 Header 右侧工具栏里有常驻的「检查更新」按钮，点一下即对比当前版本与最新版。有新版时它会给出你这种安装方式对应的更新命令，复制后在自己的终端里执行。

装了插件市场的话，在「已安装」标签页里点「更新」。也可以直接重新执行一次安装命令：

```sh
dsh plugin --profile web add @firetruck666/dsh-task-board@latest
```

或者：

```sh
dsh plugin --profile web add github:FiretrUCK666/dsh-task-board
```

更新后同样要重启 `dsh web`。

## 从源码构建

前置：Node.js 22 或 24、pnpm、能访问官方 npm 源（类型和运行时 API 全部来自 `@deepseek-ai/*`，不需要 DSH 源码 checkout）。

```sh
git clone https://github.com/FiretrUCK666/dsh-task-board.git
cd dsh-task-board
pnpm install
pnpm build       # 产出 lib/index.js 和 lib/client.js
pnpm typecheck   # 类型检查
pnpm test        # 单元与契约测试
pnpm verify      # 独立插件静态门禁
```

`lib/` 是构建产物，但它随仓库一起提交。原因是从 GitHub 或 npm 安装时只会复制文件，不会执行构建，仓库里没有 `lib/` 的话装完就启动不了。改完源码要重新构建，并把 `lib/` 和源码放在同一次提交里（CI 会检查两者是否一致）。

仓库根目录的 `AGENTS.md` 记录了项目的约定、架构索引与发布流程，是 AI 助手在这个仓库里工作时用的依据。

## 贡献指南

欢迎提 Issue 与 Pull Request。动手前先读 [CONTRIBUTING.md](CONTRIBUTING.md)：开发环境、提交 PR 前要跑的检查、硬性规范都在里面。报告加载失败类问题时，附上三个信息：DeepSeek Harness 版本、本插件版本、报错原文。

## 常见问题

**装完刷新页面看不到入口。**
host 半区在服务端进程里加载，必须重启 `dsh web`，只刷新页面不够。

**从旧版本升级上来，入口和设置的位置变了。**
新版把看板接进了 DSH 的官方界面机制（这也是它能在界面改版后继续正常显示的原因）：
入口从「侧边栏底部的一行」变成「侧边栏的面板图标，与 DSH 自带的『插件』面板并排」，
设置项从「设置 → 内置插件」搬到「设置 → 任务看板」。功能没有减少，任务数据也没有变化。
如果你看到的是旧位置，说明这一端还跑着旧的前端资源——刷新页面即可。

**升级 DeepSeek Harness 之后插件加载失败（页面提示 Failed to load plugins）。**
DeepSeek Harness 的内部接口会随版本变化，本插件需要跟着改。先做这两步：

1. 把本插件更新到最新版，然后重启 `dsh web`：

   ```sh
   dsh plugin --profile web add @firetruck666/dsh-task-board@latest
   ```

2. 仍然失败，说明本插件还没跟上你用的那个 DSH 版本。请到 [Issues](https://github.com/FiretrUCK666/dsh-task-board/issues) 提交，附上三个信息：你的 DeepSeek Harness 版本、本插件版本（在设置的已安装插件列表里看）、页面上那段报错原文。有这三样就能直接定位。

**改了代码没生效。**
改 host 半区（`src/index.ts`、`src/host/`）需要重启 `dsh web`；改 client 半区刷新页面即可。两种情况都要先 `pnpm build`。

**手机上打开位置不对，或反复开合侧栏会跳位。**
这是修复过的问题。如果仍然出现，先确认服务端进程是重启过的新版本：插件在板头会显示「服务端未重启 · 点此了解」，点开可以看到当前连接的服务端进程的启动时间。如果时间明显是旧的，说明这个地址连到了另一个没重启的实例。

**两端同时开着会不会重复执行定时任务。**
不会。定时、巡航、接续这类行为由 host 租约仲裁，同一时刻只有一个界面在执行，另一台设备切到前台后会接管并补上期间漏掉的状态。

**任务数据在哪，换电脑会丢吗。**
在 `~/.dsh/storages/dsh_task_board.json`。换电脑时把这个文件拷过去即可；浏览器里的 localStorage 只是离线镜像。

**`dsh plugin` 报错找不到 pnpm。**
先安装 pnpm（`npm install -g pnpm`），再重新执行安装命令。

## 命名约定

| 用途 | 值 |
| --- | --- |
| 插件 id | `dsh-task-board` |
| npm 包名 | `@firetruck666/dsh-task-board` |
| 设置路由 | `/api/dsh-task-board/settings` |
| 权限预设路由 | `/api/dsh-task-board/permissions` |
| 看板数据路由 | `/api/dsh-task-board/board`（含 `/lease`、`/command`、`/events`） |
| host 存储单元 | `dsh_task_board` |
| 看板舞台 slot | `main`（`key: dsh-task-board`） |
| 侧栏入口 slot | `sidebar.panellist`（`id: dsh-task-board`） |
| 设置界面 slot | `settings.section`（`id: dsh-task-board`） |
| localStorage 键 | `dsh.taskBoard.v1` 等 |

插件 id 和包名是两件事：id 决定加载器行、浏览器资源路径、设置命名空间、路由、存储单元和上面的三个 slot；包名只是 pnpm 安装时的标识。包名带作用域不会改变 id。

## 许可证

MIT，见 LICENSE 文件。
