Back to home

Chance-Wu

dsh-task-capsule

把 Harness 的执行过程收敛成一个始终可见、几乎不打扰的任务状态指示器

Stars
0
Language
TypeScript
Created
Aug 15, 2026
Updated
Aug 15, 2026

Introduction

dsh-task-capsule

An always-visible, expandable task-status pill for the DeepSeek Harness session header — "what is it doing, how far along, how long has it taken", with almost no noise.

DeepSeek Harness 的任务胶囊插件:把 Harness 的执行过程收敛成一个始终可见、几乎不打扰的任务状态指示器——「状态 → 任务计数 → 时间」。二期(Interaction Polish)砍掉了所有管理形态的 UI;三期在本仓库落地的迭代里,把「最近任务列表」和「设置中心」从砍掉清单里拿了回来,同时补上折叠层的正确性修复(turn 结束完成度推断、帧洪峰抑制)、回合间隔状态、进度条、目标行与密度/强调色设置。

task-capsule mock

功能

  • 紧凑胶囊(会话头部右侧):● 任务 已完成3 进行中1 待处理5 · 02:18——状态点 + 任务计数(已完成/进行中/待处理)+ 时钟式耗时(MM:SS,超一小时 HH:MM:SS;未开始显示 )。耗时以弱化的等宽时钟呈现,并用「·」与前面的状态文字隔开;胶囊变窄时仅状态文字省略,时钟始终可见。
    • 未使用 todo 计划时会话固定显示「会话任务处理」。
    • 终态胶囊收起为记录:✓ 任务完成 5/5 · 02:31(状态词 + 已完成/总数 + 冻结耗时,不随页面刷新增长)。
    • 运行/等待中的状态点是呼吸动画(轻微透明度脉动),不是转圈。
    • 配置 alwaysVisible: true 可让胶囊在会话空闲、无任何活动时也保持显示。
  • 展开面板(胶囊"长大"成面板,180ms morph 过渡):
    • 头部 Task Capsule ×(× 关闭;ESC / 点击外部同样收起)。
    • 状态行(glyph + 状态词;等待时附带原因,如 等待确认 · bash;状态变化经 aria-live 播报)。
    • 当前任务行(名称强调 + 耗时;列表存在但无进行中项时显示「全部完成」)。
    • 文件统计行改动 3 个文件 · +12 −4(来自 fs 工具 tool/result 的 diff 折叠)。
    • 子代理汇总行(P0-1):◈ 子代理 2 · 已完成3 进行中1 待处理5 · 4 文件——宿主侧聚合整棵委托树的当前任务。
    • 任务列表,视觉层级严格 当前 > 已完成 > 等待;当前任务行下方显示当前操作(正在编辑的文件 / 执行的命令,超长两端保留截断)。已完成项默认收起为一组(点开展开);进行中项切换时有一帧强调动画;每项下方有耗时占比条(相对最久项)。
    • 失败块:一行错误摘要 + 查看详情 折叠展开,不放日志查看器
    • 最近任务:宿主持久化环形缓冲($DSH_HOME/task-capsule-history.json,重启不丢)的紧凑列表——状态词 + 完成数 + 耗时,顶部一行轻量统计(今日 N · 本周 M · 成功率 X% · 平均 MM:SS)。点击行打开对应会话;失败行显示原因并提供「重试」(重新入队一条「继续」提示);同会话后续尝试显示「重试 N 次」徽标(P0-2);行 tooltip 带归档帧数(P0-3,调试用)。
  • 展开面板 = 液态悬浮面板:通过 portal 渲染到 <body>position: fixed 锚定在胶囊下方(右对齐),不被会话头部/滚动容器裁剪,随滚动/缩放重新锚定;z-index 1000 悬浮于一切内容之上。液态质感:半透明玻璃表面(backdrop-filter 模糊)+ 轻微不规则的液滴圆角 + 顶层内高光;420ms 液滴沉降入场(圆角/模糊随沉降形变),之后进入每 5.5s 一次的微浮动;收起时液滴回吸(230ms 下坠、圆角张开、模糊加深)。下方空间不足时自动向上翻转并带指示箭头(P1-5);焦点进入面板、Tab 循环、关闭还原到胶囊(P1-6)。
  • 生命周期任务进行时胶囊自动展开面板(autoExpandRunning,默认开;手动收起后本次任务不再强制打开);计划全部完成(或空计划)后面板 1.5s 自动缩回紧凑胶囊态,完成态胶囊保留(时长可配);失败/中止不自动缩回——错误入口保持可见(可配置失败自动展开)。无 todo 计划的运行在终态显示「N 回合」(P0-4)。支持 prefers-reduced-motion,无烟花/Toast/弹窗。
  • 设置中心:设置面板里注册了「任务胶囊」页——显示开关(耗时/当前操作/进度条/失败展开/任务进行时自动展开/始终显示/帧追踪)、面板密度(舒适/紧凑)、强调色(自动/业务蓝/成功绿/警告黄/错误红)、保留时长、历史容量,全部可运行时调整(写回 /api/task-capsule/settings,与 yaml 配置同源)。

语义(为什么胶囊和聊天可能"看起来不同步")

  • 任务状态唯一来自 agent 的 todo_write 工具(整表替换,last-write-wins)。聊天里的 todo 工具卡显示的是 agent 写入的同一份数据;如果 agent 在最终消息里口头说"完成"却没再写一次 todo 列表,胶囊会如实停留在最后一次写入的状态。
  • 回合结束推断turn/end 且 reason 为 completed 时,当前 in_progress 项自动升级为 completed(补齐 agent 换任务前漏写的那一步)。失败/中止/中断/等待决策(error / aborted / interrupted / blocked / max-tokens做推断——胶囊不为失败的回合伪造完成。
  • 回合间隔:框架的 todos 投影在 turn/start 清空(聊天 TodoPanel 两轮之间空白),胶囊保留列表跨回合——两者语义不同,但都是"如实反映"。

架构

Harness session 日志(append-only)
   │ session/event
   ▼
taskCapsule 投影(纯折叠)──session/projection 帧──▶ useProjection('taskCapsule')
   │                                                    │
   ▼                                                    ▼
task-history(agent 生命周期归档,宿主侧)──REST──▶ 客户端(useSession 快照合成状态)
  • 任务计划来自 agent 的 todo_write 工具;不用 todo 时胶囊退化为「状态 + 耗时」。
  • 状态由客户端从实时快照合成:running / 等待 → waiting,turn 结局 + lastAgentErrorsuccess/failed,goal phase → paused空闲但队列里还有工作 → turnGap(回合间隔)
  • 任务边界 = 一条直接人类提示词。
  • 帧洪峰抑制tool/result 不带 diff 时折叠返回同一引用,投影驱动层不产生帧——一次长会话里 taskCapsule 的帧数从「每个工具调用一帧」降到「每个 turn/todo 写一帧」量级(traceFrames: true 可在控制台观察)。

配置

显示开关可走 profile 的 cordis.patch.yml,也可在设置面板 → 任务胶囊里运行时调整(后者写回 $DSH_HOME/task-capsule.json):

- insert:
    - id: task-capsule
      name: dsh-task-capsule
      config:
        keepAfterDoneMs: 8000    # 完成态胶囊保留时长(0 = 立即收缩)
        autoExpandFailed: false  # 失败时自动展开面板
        autoExpandRunning: true  # 任务进行时自动展开面板(完成后缩回)
        historyLimit: 5          # 最近任务历史环形缓冲容量(3 | 5 | 10)
        showDuration: true       # 展开态显示逐任务耗时
        showCurrentOp: true      # 显示当前操作行
        alwaysVisible: false     # 空闲无活动时也保持胶囊可见
        showProgress: true       # 当前任务行下的细进度条
        density: comfortable     # 面板密度(comfortable | compact)
        accent: auto             # 强调色(auto | business | success | warn | error)
        traceFrames: false       # 控制台追踪投影帧(调试)

HTTP API(前缀 /api/task-capsule

资源说明
GET /settings · PUT /settings显示开关(胶囊启动时 GET 一次;PUT 供设置中心/程序化配置)
GET /history最近完成的任务(宿主侧归档,面板「最近任务」区消费)

胶囊数据本身全部走既有投影/会话快照通道,无 SSE、无轮询。

开发

pnpm install
pnpm typecheck     # tsc --noEmit
pnpm test          # vitest run(折叠/归档/设置清洗/状态派生/格式化 + jsdom 组件测试)
pnpm build         # tsc + tsdown(浏览器半边打包 lib/client.js)
pnpm dev:watch     # 宿主半边 tsc --watch + 浏览器半边 tsdown --watch

Harness 的 web profile 直接加载本包 lib/ 下的构建产物(main: lib/index.js./client → lib/client.js)。src/ 后必须 pnpm build,再刷新浏览器页面才会生效——prepare 钩子保证 git 方式安装时自动构建,日常开发用 pnpm dev:watch 免手动重建。

目录

src/
├── index.ts            # 插件入口:Config schema + 组合宿主半边
├── types/capsule.ts    # 线模型 + taskCapsule 投影键声明(两半共享)
├── harness/            # 事件 → 胶囊模型(纯折叠,可重放)
│   ├── adapter.ts      # 投影注册 + 折叠(turn 结束推断、帧洪峰抑制)
│   ├── event-parser.ts # 事件分类/窄化(direct prompt、diff meta、goal phase)
│   ├── task-mapper.ts  # todo 计时合并、turn 结局映射
│   ├── fold-fuzz.spec.ts    # 确定性随机重放不变式
│   └── integration.spec.ts  # 折叠 × 客户端存储 端到端同步
├── task/
│   ├── task-manager.ts # 按会话折叠存储
│   ├── task-history.ts # 历史环形缓冲(持久化)+ agent 生命周期归档(子代理过滤)
│   └── task-state.ts   # 设置服务 + 持久化
├── api/routes.ts       # REST 路由(history / settings)
└── client/             # 浏览器半边
    ├── index.ts        # 注册 header.utilities 胶囊 + settings.section 设置页
    ├── CapsuleChip.tsx / CapsulePanel.tsx / StatusGlyph.tsx
    ├── TaskTree.tsx / HistoryList.tsx / SettingsSection.tsx
    ├── status.ts / format.ts(progressLabel / historyStats)/
    ├── api.ts          # settings GET/PUT + history GET + session.prompt 客户端
    ├── session-nav.ts  # 最近任务点击打开会话(插件体注入)
    └── locales.ts

边界(仍明确砍掉)

❌ 日志面板 ❌ 任务搜索/筛选/标签/优先级/暂停/拖拽 ❌ 自定义主题(强调色是 token 语义色的单选) ❌ Dashboard/数据分析(历史只有一行统计) ❌ 内置 To-dos 条改动。

胶囊只做一件事:随时可感知、几乎不打扰地告诉你「现在在干什么、做到哪了、花了多久」