Bundle
dsh-task-completion
任务完成约束自动化插件:监听 AI 回合结束,检测回复是否含 ✅ 任务完成,按「推送许可」开关自动 commit+push 交付物。带 HTTP API(status/config)与 agent 工具(task_completion_status / task_completion_config)。
- Source
- EIGHTfs
- Updated
- Updated 19 days ago
Readme
# dsh-task-completion
DSH(DeepSeek Harness)任务完成约束自动化插件。把 task-completion-report 的硬性约定固化为**代码管道**(零 token、确定性):
> AI 回复输出 `✅ 任务完成` 即视为完成(= 提交授权)→ 按「推送许可」开关自动 `commit + push` 交付物。
## 功能

- **自动触发**:监听 AI 回合结束(`session/event` turn/end),提取最后一条回复文本,检测完成标记
- `✅`(任务完成 / 已解答)→ 完成;`❌` 失败 / `⚠️ 未完成` → 明确阻断,不触发
- **推送许可开关**(`pushOnComplete`,**默认关闭**):开启后,回复含 ✅ 即自动 commit+push;关闭时只记录检测结果,绝不自动推
- **自动推送**:扫描 workspace 全部 git 仓库(复用 dsh-git-push 已验证逻辑)
- `-c safe.directory=` 兼容 CIFS 只读卷;自动识别分支(master/main);push 前 fetch + ahead/behind 检查,远端领先不推
- 并发闸(同时只跑一个推送)+ 回合去重(同回合只触发一次)
- 开关状态持久化(storageDomain,重启保留)
- **HTTP API**:`status` / `config`,curl 即可调用;可选 `apiToken` 认证
- **agent 工具**:`push_permit_status`(查开关/最近记录)、`push_permit_config`(切开关)
## 安装
```bash
# 1. 源码放 node_modules_local/ 或 workspace 独立目录,注册三要素:
# package.json 加 "dsh-task-completion": "file:./node_modules_local/dsh-task-completion"(或相对路径)
# node_modules 补软链
# cordis.patch.yml 追加:
- insert:
- id: task-completion
name: dsh-task-completion
config:
workspaceRoot: '/vol1/@appshare/DeepSeekHarness/workspace'
extraRepos: ['/vol02/1000-0-1789e550/gamebanana-mods-downloader']
# pushOnComplete: false # 推送许可,默认关闭;true=开启
# pushScope: 'all' # 'all'=workspace 全部 | 'session'=仅会话 cwd 所在仓库
# commitMessage: 'chore(ai): 任务完成自动提交'
# apiToken: 'xxx' # 可选,配置后 API 需带 Bearer token
# 2. 重启 DSH(改 patch 必须重启)
```
## API
| 接口 | 说明 |
|---|---|
| `GET /api/push-permit/status` | 插件状态 + 许可开关 + 最近检测/推送记录 |
| `POST /api/push-permit/config` | `{"pushOnComplete": true/false}` 切换推送许可 |
- 配置了 `apiToken` 时,请求需带 `Authorization: Bearer <token>` 或 `?token=<token>`,否则 401
```bash
# 查询状态(推送许可关闭时)
curl -s http://127.0.0.1:3083/api/push-permit/status
# 开启推送许可
curl -s -X POST http://127.0.0.1:3083/api/push-permit/config \
-H 'Content-Type: application/json' \
-d '{"pushOnComplete": true}'
# 关闭推送许可
curl -s -X POST http://127.0.0.1:3083/api/push-permit/config \
-H 'Content-Type: application/json' \
-d '{"pushOnComplete": false}'
```
预期输出(status):
```json
{
"ok": true,
"plugin": "dsh-task-completion",
"enabled": true,
"pushOnComplete": true,
"pushScope": "all",
"lastAttempt": null,
"lastAutoPush": null
}
```
## 工具(agent 会话内直接调用)
- `push_permit_status`:查询许可开关与最近自动推送记录(回复前确认是否会自动推送)
- `push_permit_config`:`{enabled: true/false}` 切换推送许可
## 配置
| 字段 | 默认 | 说明 |
|---|---|---|
| `enabled` | `true` | 插件总开关 |
| `pushOnComplete` | `false` | **推送许可**:AI 回复 ✅ 后是否自动 commit+push |
| `pushScope` | `'all'` | `'all'`=workspace 全部有变更仓库;`'session'`=仅会话 cwd 所在仓库 |
| `workspaceRoot` | `process.cwd()` | 扫描根目录 |
| `extraRepos` | `[]` | 额外仓库绝对路径(find 范围外) |
| `depth` | `3` | find 深度 |
| `commitMessage` | `'chore(ai): 任务完成自动提交'` | 自动提交 message |
| `apiToken` | `''` | 可选,保护 API(Bearer 或 ?token=) |
| `triggerPattern` / `blockPattern` | `/✅/` / `/❌\|⚠️\s*(未完成\|失败)/` | 完成/阻断正则 |
## 权限说明(重要)
- **自动 push 走本机 SSH remote**(全局 `core.sshCommand` 已配,密钥在 `~/.ssh/id_ed25519`)→ **无需任何 token**
- 若目标仓库只有 HTTPS remote:本机 git 缺 `remote-https`,push 会失败(同 dsh-git-push 已知边界),需改用 SSH remote
- `apiToken` 是**插件 API 访问凭据**(可选):配置后所有 `/api/push-permit/*` 请求需带 token,防止未授权切换推送许可
- 插件只做可逆操作(commit+push);删除仓库/覆盖生产数据等不可逆操作不在自动授权内
## 开发与测试
```bash
node --check lib/git.js && node --check lib/detect.js && node --check lib/index.js # 语法
node test/test-detect.mjs # 完成检测 26 项(纯函数)
node test/test-git.mjs # git 逻辑 12 项(真实临时仓库)
node test/test-apply.mjs # apply mock 17 项(含端到端:turn/end → ✅ → 许可开 → 自动提交)
```
## 已知边界
- 自动推送**默认关闭**:需通过 API / 工具 / 配置显式开启 `pushOnComplete`
- push 依赖 SSH remote(本机缺 remote-https)
- 远端领先时拒绝推送(防覆盖),需先 pull
- commit message 固定模板(`commitMessage` 配置),不做智能生成
Install
dsh plugin --profile web add github:EIGHTfs/dsh-task-completion
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install dsh-task-completion from the hub
- This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.