Skip to content
dsh.fish
Bundle

@dsh-external/dsh-ui-progress

DSH Web UI 会话进度插件:输入框停靠区常驻会话进度条(todos 真实进度 / 无投影默认 100% / 中断橘红态 / 实时 token 生成速率),零核心改动。

Source
omdsh-dev
stars
1 stars
License
BSD-3-Clause
Updated
Updated 4 days ago

Readme

# @dsh-external/dsh-ui-progress

DSH Web UI 会话进度插件:为 DeepSeek Harness 的 Web GUI 的输入框停靠区提供常驻会话进度条,**零核心改动**(纯 client 插件,不触碰 agent-loop)。

> **你的 DSH 版本决定装哪个插件版本**(装错会崩:常见症状 `useConversation is not a function`)
>
> - DSH **0.1.2-alpha.1 ~ 0.2.1-alpha.1**:装**新版**(下方默认命令;各 DSH 版本对应的插件 tag 见[版本对应表](#版本对应--version-compatibility))
> - 更旧的 DSH(0.1.1-rc.2 及以前):**无可用版本**
>

## 安装

> **安装方式(v0.11.4 起自动挂载)**:本包自 v0.11.4 起自带 `cordis.patch.yml` 并声明 `dsh.bundle.patch`——`dsh plugin --profile web add` 安装后**自动注册 profile 层并挂载**,不再需要手写 `insert` 配置行(固定旧 tag 的部署仍需)。**GUI 注意**:插件页「添加插件」只接受注册表包名或本地目录路径;`name@github:owner/repo#tag` 是 pnpm 别名规格(CLI 专用),粘进 GUI 会报 `ERR_PNPM_INVALID_PACKAGE_NAME`——GUI 请克隆后用本地目录路径,或等 npm 发布后用包名。


```sh
# 方式一:git 依赖固定 tag(公开镜像,推荐;也可用 github:omdsh-dev/dsh-ui-progress)
dsh plugin --profile web add '@dsh-external/dsh-ui-progress@github:omdsh-dev/dsh-ui-progress#v0.11.9'

# 方式二:本地 link(开发)
git clone https://github.com/omdsh-dev/dsh-ui-progress.git
cd dsh-ui-progress && pnpm install && pnpm run build
dsh plugin --profile web add link:/path/to/dsh-ui-progress
```

配置行(`$DSH_HOME/profiles/web/cordis.patch.yml`,热重载,无需重启):

```yaml
- insert:
    - id: dsh-ui-progress
      name: '@dsh-external/dsh-ui-progress'
```

> **安装提示**:pnpm 11 首次安装可能拦截 node-pty 等构建脚本——在 `~/.dsh/profiles/web` 下执行 `pnpm approve-builds --all` 放行后重跑安装命令;装完**硬刷新浏览器**(Ctrl/Cmd+Shift+R)。

### 提示词安装(让 DSH 自己装)

把下面这段提示词发给任意一个 DSH 会话,模型会替你完成安装:

> 帮我安装 dsh-ui-progress 插件(DSH 会话进度条:输入框常驻会话进度条/todos 真实进度/中断橘红态),步骤:
> 1. 执行 `dsh plugin --profile web add '@dsh-external/dsh-ui-progress@github:omdsh-dev/dsh-ui-progress#v0.11.9'`(首次可能被 pnpm 11 拦截 node-pty 构建脚本而失败)
> 2. 在 `~/.dsh/profiles/web` 下执行 `pnpm approve-builds --all`(放行构建脚本)
> 3. 再执行一次第 1 步的安装命令
> 4. 完成后提醒我硬刷新浏览器(Ctrl/Cmd+Shift+R)
> 遇到报错先查 https://github.com/omdsh-dev/dsh-ui-progress README 的常见问题/已知限制。

## 版本对应 / Version compatibility

## 智能版本门控更新提示 / DSH-gated update chip

更新浮标会结合**当前运行的 DSH 版本**(宿主端从 dsh 安装清单读取,随 `/dsh-ui-progress/latest` 一并返回)与仓库根的 [`compatibility.json`](compatibility.json)(版本→支持的 DSH 列表,精确匹配)判定提示形态:

- 最新版支持当前 DSH → 正常「新版本 vX 可用,点击更新」;
- 最新版需要更高 DSH、但存在支持当前 DSH 的中间新版 → 提示更新到中间版,并注明「另有 vX 需更高 DSH」;
- 最新版需要更高 DSH、且当前 DSH 无任何可用新版 → 琥珀色信息条:「新版本 vX 支持更高 DSH 版本,当前 DSH vY 暂不可用」,不提供直接升级。

兼容数据拉取失败或无该版本条目时,自动回退为旧的普通升级提示(离线安全)。**发版时需同步维护 `compatibility.json`**(与下表同一步骤新增一行)。

## 版本对应 / Version compatibility

构建产物随 DSH 快照版本更新,安装时按快照选择对应版本:

| 插件版本 | DSH 快照 | 说明 |
| --- | --- | --- |
| `v0.11.9`(默认) | 与上一版相同 | 声明支持 dsh-v0.2.1-rc.1(0.2.1 系首个候选版,整合 alpha.1–5 全部插件面变更;升级实机验证:web profile `--dump-config` 全插件行加载零错误;运行时只读探测 file-trace mermaid/katex 路由 200、better-sidebar fence 活;宿主保留 webStartup 服务、无 alpha.5 之外的插件面破坏性变更;零适配改动);双 bundle `node --check` 通过 |
| `v0.11.8` | 与上一版相同 | **修复工具执行期 token 速率冻结**:短思考→工具调用的切换中,实时 token 速率会带着旧值冻结显示整个工具执行期(根因:滑动窗口只在有新 token 时更新读数、空窗口永远保留旧值,而 tool-call 步的 partial 在参数流完后 tokens 恒定);现在连续两个空窗口(约 2 秒)自动清空读数、token 恢复流动即重新显示,单窗口间隙仍保留旧值不闪零。新增 5 个 hook 测试,全量 62 测试通过 |
| `v0.11.7` | 与上一版相同 | 声明支持 dsh-v0.2.1-alpha.5(升级实机验证:web profile `--dump-config` 全插件行加载零错误;运行时只读探测 file-trace mermaid/katex 路由 200、better-sidebar fence 活;宿主保留 webStartup 服务、无插件面破坏性变更——新增的 `conversation.input.model.label` Slot 为并列新增键,与本插件既有注入面(`conversation.input.for` / `conversation.input.dock` 等)无冲突;零适配改动);双 bundle `node --check` 通过 |
| `v0.11.6` | 与上一版相同 | 声明支持 dsh-v0.2.1-alpha.4(升级实机验证:web profile `--dump-config` 全插件行加载零错误;宿主保留 webStartup 服务、无插件面破坏性变更——新引入的 engines.dsh 兼容判定仅对声明者生效,本插件未声明故沿用原有规则;六插件零适配改动);双 bundle `node --check` 通过 |
| `v0.11.5` | 与上一版相同 | 声明支持 dsh-v0.2.1-alpha.3(升级实机验证:web profile `--dump-config` 全插件行加载零错误;运行时只读探测 file-trace mermaid/katex 路由 200、better-sidebar fence 活;宿主保留 webStartup 服务,六插件零适配改动);双 bundle `node --check` 通过 |
| `v0.11.4` | 与上一版相同 | **自带 bundle 声明**:补齐 `cordis.patch.yml` 并声明 `dsh.bundle.patch`——`dsh plugin --profile web add` 装完自动注册并挂载 profile 层,不再需要手写 insert 行(社区反馈「GUI 安装后不生效」的根因);双 bundle `node --check` 通过 |
| `v0.11.3` | `dsh-v0.1.2-alpha.1 ~ alpha.5`、`rc.1`、`0.1.3-alpha.1 ~ 0.1.7-alpha.2`、`0.1.7-rc.1`、`0.1.7-rc.2`、`0.2.0-rc.1`、`0.2.0-rc.2`、`0.2.1-alpha.1`、`0.2.1-alpha.2` | 声明支持 dsh-v0.2.1-alpha.2(升级实机验证:web profile `--dump-config` 全插件行加载、peer 校验零错误,宿主启动监听正常,零适配改动);双 bundle `node --check` 通过 |
| `v0.11.2` | `dsh-v0.1.2-alpha.1 ~ alpha.5`、`rc.1`、`0.1.3-alpha.1 ~ 0.1.7-alpha.2`、`0.1.7-rc.1`、`0.1.7-rc.2`、`0.2.0-rc.1`、`0.2.0-rc.2`、`0.2.1-alpha.1` | 声明支持 dsh-v0.2.1-alpha.1(升级实机验证:web 宿主七插件挂载激活正常,零适配改动);typecheck/57 单测/构建全绿 |
| `v0.11.1` | `dsh-v0.1.2-alpha.1 ~ alpha.5`、`rc.1`、`0.1.3-alpha.1 ~ 0.1.7-alpha.2`、`0.1.7-rc.1`、`0.1.7-rc.2`、`0.2.0-rc.1`、`0.2.0-rc.2` | **窄宽度两行自适应**:尾部计数收拢为不可拆分的 `.meta` 组,进度条 `flex-wrap` 在百分比处折行——单行布局与原先完全一致,折行后第二行 `margin-inline: auto` 居中;条高 36px→min-height 自适应不裁切;typecheck/57 单测/构建全绿,实机窄窗口验证(用户确认) |
| `v0.10.10` | `dsh-v0.1.2-alpha.1 ~ alpha.5`、`rc.1`、`0.1.3-alpha.1 ~ 0.1.7-alpha.2`、`0.1.7-rc.1`、`0.1.7-rc.2`、`0.2.0-rc.1`、`0.2.0-rc.2` | 声明支持 dsh-v0.2.0-rc.2(升级实机验证:六插件挂载激活正常,零适配改动);typecheck/57 单测/构建全绿 |
| `v0.10.9` | `dsh-v0.1.2-alpha.1 ~ alpha.5`、`rc.1`、`0.1.3-alpha.1 ~ 0.1.7-alpha.2`、`0.1.7-rc.1`、`0.1.7-rc.2`、`0.2.0-rc.1` | 测试覆盖与内部重构(行为不变):抽出纯函数 `countRunningJobs(rows)` 并新增 5 个单测(空 roster / running+stopping 计数 / 已结束不计 / subagent-kind 排除防双重计数 / 未知 kind 仍计、无 status 不计)——v0.10.8 的后台态修复此前零测试覆盖;typecheck/57 单测/构建全绿 |
| `v0.10.8` | `dsh-v0.1.2-alpha.1 ~ alpha.5`、`rc.1`、`0.1.3-alpha.1 ~ 0.1.7-alpha.2`、`0.1.7-rc.1`、`0.1.7-rc.2`、`0.2.0-rc.1` | **后台任务计入后台态**:`ctx.jobs` roster(`ctx.get('jobs')` 可选读取,running/stopping 计数、排除 subagent 类 job 防双重计数)与子代理运行合并为同一青色「后台运行中」态——修复主会话空闲而后台 job 运行时误显绿色「会话就绪」;无该服务的宿主降级为 0 不影响旧版本;typecheck/52 单测/构建全绿,双会话实机验证(dock 卸载事故两轮修复:cordis 服务属性未 inject 访问抛错已全防御) |
| `v0.10.7` | `dsh-v0.1.2-alpha.1 ~ alpha.5`、`rc.1`、`0.1.3-alpha.1 ~ 0.1.7-alpha.2`、`0.1.7-rc.1`、`0.1.7-rc.2`、`0.2.0-rc.1` | 声明支持 dsh-v0.2.0-rc.1(升级实机验证:六插件挂载激活正常,零适配改动);typecheck/52 单测/构建全绿 |
| `v0.10.6` | `dsh-v0.1.2-alpha.1 ~ alpha.5`、`rc.1`、`0.1.3-alpha.1 ~ 0.1.7-alpha.2`、`0.1.7-rc.1`、`0.1.7-rc.2` | 声明支持 dsh-v0.1.7-rc.2(npm 升级实机验证:六插件挂载激活正常,零适配改动);typecheck/52 单测/构建全绿 |
| `v0.10.5` | `dsh-v0.1.2-alpha.1 ~ alpha.5`、`rc.1`、`0.1.3-alpha.1 ~ 0.1.7-alpha.2`、`0.1.7-rc.1` | 声明支持 dsh-v0.1.7-rc.1(舰队扫检零错误零崩溃,零适配改动) |
| `v0.10.4` | `dsh-v0.1.2-alpha.1 ~ alpha.5`、`rc.1`、`0.1.3-alpha.1 ~ 0.1.6-alpha.2`、`0.1.7-alpha.1`、`0.1.7-alpha.2` | **新增 DSH 版本门控更新提示**:浮标结合当前运行 DSH 版本(宿主端读取)与 compatibility.json 判定——最新版不支持当前 DSH 时改提示「需更高 DSH」(琥珀色)或中间版本(蓝+备注),数据缺失回退旧行为。声明支持 dsh-v0.1.7-alpha.2(实机验证);typecheck/52 单测/构建全绿 |
| `v0.10.3` | `dsh-v0.1.2-alpha.1 ~ alpha.5`、`rc.1`、`0.1.3-alpha.1 ~ 0.1.6-alpha.1`、`0.1.7-alpha.1` | **适配 dsh 0.1.7-alpha.1 图标集改名**:primitives 全部 `*16` 图标取消(→ `*Medium`/`*Regular` 双变体),静态解构得 `undefined` → React #130 → slot 错误边界卸载整个输入栏 dock(症状:进度条消失,控制台仅一条压缩报错)。改为运行时回退解析(`*16` → `*Medium` → `*Regular`),单构建兼容 0.1.5/0.1.6/0.1.7+ 宿主;typecheck/45 单测/构建全绿,无头浏览器 E2E 验证 dock 恢复渲染、零控制台报错 |
| `v0.10.2` | `dsh-v0.1.2-alpha.1 ~ alpha.5`、`rc.1`、`0.1.3-alpha.1 ~ 0.1.6-alpha.2` | **适配 dsh 0.1.6-alpha.2 运行时解析重构**:dock 标准 props 移除 `useSessions`/`useSessionPendingInteraction`,子代理待办/运行指示降级隐藏,其余(todos 进度、token 速率/面板、ETA、状态文案)全功能;typecheck/45 单测/构建全绿,alpha.2 实机验证(进度条恢复显示)。v0.10.1 为纯版本号发布(声明支持 0.1.6-alpha.1),未单独建行 |
| `v0.10.0` | `dsh-v0.1.2-alpha.1 ~ alpha.5`、`rc.1`、`0.1.3-alpha.1 ~ 0.1.5-rc.2` | **新功能双发**:①「后台运行中」状态(青色)——主会话完成而子代理树仍在执行时,进度条不再误显就绪绿;②Token 用量徽标 + 悬停/点击明细面板(总量/未缓存输入/缓存读取/缓存写入/输出/缓存命中%,实时更新)。typecheck/45 单测/构建全绿,热挂载实机验证 |
| `v0.9.17` | `dsh-v0.1.2-alpha.1 ~ alpha.5`、`rc.1`、`0.1.3-alpha.1 ~ 0.1.5-rc.2` | 声明支持 0.1.5-rc.1~rc.2(npm 已发布,钉版本实机验证;rc.1 为 0.1.5 系列首个候选版本,client 插件面零代码差异;typecheck/build/39 单测全绿,热挂载实机验证) |
| `v0.9.16` | `dsh-v0.1.2-alpha.1 ~ alpha.5`、`rc.1`、`0.1.3-alpha.1 ~ 0.1.5-alpha.2` | 声明支持 0.1.5-alpha.2(npm 已发布,钉版本实机验证;alpha.2 改动为 Sidebar 文档预览、模型文件交付、minimal 默认工具调整与 `fs-ext` 安装修复,client 插件面零代码差异;typecheck/build/39 单测全绿,启动清单确认加载) |
| `v0.9.15` | `dsh-v0.1.2-alpha.1 ~ alpha.5`、`rc.1`、`0.1.3-alpha.1 ~ 0.1.5-alpha.1` | 声明支持 0.1.5-alpha.1(npm 已发布,钉版本实机验证;0.1.5 改动在会话格式 V3 / ctx.agent 移除 / 宿主 bundle 服务路由 `/plugins/??`,client 插件面零代码差异;typecheck/build/单测全绿,启动清单确认加载) |
| `v0.9.14` | `dsh-v0.1.2-alpha.1 ~ alpha.5`、`rc.1`、`0.1.3-alpha.1`、`0.1.3-alpha.2` | 声明支持 0.1.3-alpha.2(npm 已发布,钉版本实机验证;alpha.2 改动全在 pi-ai/Web 顶栏/子代理消息/host 面,client 插件面零代码差异;typecheck/build/单测全绿) |
| `v0.9.13` | `dsh-v0.1.2-alpha.1 ~ alpha.5`、`rc.1`、`0.1.3-alpha.1` | 声明支持 0.1.3-alpha.1(npm 未发布,源码宿主实机验证;0.1.3 破坏性变更集中在 host/session 侧,client 插件面零代码差异;typecheck/build/单测全绿) |
| `v0.9.12` | `dsh-v0.1.2-alpha.1 ~ alpha.5`、`rc.1` | 声明支持 rc.1(alpha.5→rc.1 为纯版本号提交,零代码差异;实机 rc.1 验证通过) |
| `v0.9.11` | `dsh-v0.1.2-alpha.1 ~ alpha.5` | 声明支持 alpha.5(typecheck/build 全绿;alpha.5 为纯 bug 修复,无 API 变更) |
| `v0.9.10` | `dsh-v0.1.2-alpha.1 ~ alpha.4` | 声明支持 alpha.4(typecheck/build 全绿) |
| `v0.9.9` | `dsh-v0.1.2-alpha.1 ~ alpha.3` | 更新提示词补「按 DSH 版本选 tag」路由说明与排查指引 |
| `v0.9.8` | `dsh-v0.1.2-alpha.3`(npm alpha) | 兼容 DSH 0.1.2-alpha.3:typecheck/build/单测全绿 + 实机验证 |
| `v0.9.3` | npm `@deepseek-ai/dsh@0.1.1-rc.1` | 修复中断检测:0.1.x 的停止不再留旧式节点痕迹,改以最新回合的 `turn/end reason` 为主信号(`aborted`/`interrupted` 区分手动停止与崩溃),窗口节点痕迹降级为旧宿主回退路径;新增 12 例单测,npm 0.1.1-rc.1 实机核验 |
| `v0.9.2` | npm `@deepseek-ai/dsh@0.1.1-rc.1` | 0.1.1-rc.1 实机 boot 验证通过(boot 清单 + client.js 200),依赖的槽位/服务不变 |
| `v0.9.1` | `snapshots/20260810T155924Z`(snapshot0810) | 兼容性构建:客户端插件元数据从顶层 `dshClient` 迁移为嵌套 `dsh.client`(0810 的 ClientModuleHostService 只读该字段;顶层 `dshClient` 被静默忽略),inject/platform 原样保留 |
| `v0.9.0` | `snapshots/20260809T140917Z`(snapshot0809) | 新构建(原生 0809):运行中新增**实时 token 生成速率**(自校准估算 + 1s 滑动窗口平滑,首 token 到达起算,贴近真实 provider usage) |
| `v0.8.0` | `snapshots/20260808T121140Z`(snapshot0808) | 新构建:移除自带 `report_progress` 工具与上报引导(宿主 half 置空)、移除工具卡片;填充改为 todos 真实比例(无 todos 默认 100%);新增中断橘红态(手动打断/API 错误等意外停止) |
| `v0.7.0` | `snapshots/20260808T121140Z`(snapshot0808) | 新构建:适配 0808 的 slot 迁移(`conversation.chat.toolview` → `tool.call.toolview`,注册经 `slots.inject` 等待声明) |
| `v0.6.0` | `snapshots/20260807T130646Z`(snapshot0807) | 新构建:已耗时 0.1s 步进(满分钟折叠)+ subagent 待办琥珀提示 |
| `v0.5.1` | `snapshots/20260807T130646Z`(snapshot0807) | 同快照上一构建:会话完成进度条浅绿色 |
| `v0.5.0` | `snapshots/20260807T130646Z`(snapshot0807) | 同快照上一构建:自带工具 + 上报引导 |
| `v0.4.0` | `snapshots/20260806T160212Z`(snapshot0806) | 同快照上一构建(ETA 仅来自模型上报) |
| `v0.3.1` | `snapshots/20260806T160212Z`(snapshot0806) | 同快照上一构建(ETA 为线性外推) |
| `v0.3.0` | `snapshots/20260806T160212Z`(snapshot0806) | 同快照上一构建(卡片耗时/ETA 文案插值缺失) |
| `v0.2.0` | `snapshots/20260806T160212Z`(snapshot0806) | 同快照早期构建(无耗时/ETA/失败态/阶段时间线) |
| `v0.1.0` | `snapshots/20260805T134133Z`(snapshot0805) | 旧构建,按旧安装方式(`~/.dsh/config.yaml` + `pnpm add -w link:`) |

> **兼容性说明**:当前版本为 `v0.9.12`(面向 `dsh-v0.1.2-rc.1`);以下为历史快照兼容记录。`v0.8.0` 构建基于 snapshot0808 开发,同时兼容 snapshot0809(`snapshots/20260809T140917Z`),实机验证通过;`v0.9.0` 为原生 snapshot0809 构建;`v0.9.1` 面向 snapshot0810(`snapshots/20260810T155924Z`,默认版本),同时兼容 snapshot0811(`snapshots/20260811T152241Z`)与最终快照 snapshot0812(`snapshots/20260812T172954Z-final`)——0811 与 0812 实机 boot 验证通过(见下)。

> **npm 发版兼容**:兼容 DSH npm 发版 `@deepseek-ai/dsh@0.1.1-rc.1`(v0.9.2 实机 boot 验证通过:`dsh --profile web` 启动后 boot 清单包含 `@dsh-external/dsh-ui-progress`,`/plugins/@dsh-external/dsh-ui-progress/client.js` 返回 200;`conversation.input.dock` 槽位与 `locale`/`invariants` 服务在 0.1.1-rc.1 上保持不变),同时兼容 `@deepseek-ai/dsh@0.0.1-rc.5`(dist-tag `next`,即最终快照 snapshot0812 的 npm 发版;`npm exec -p @deepseek-ai/dsh@0.0.1-rc.5 -- dsh --profile web --port <port>` 可访问指定版本并启动,lib 生产模式),同时保持兼容 `@deepseek-ai/dsh@0.0.1-rc.2`(snapshot0811 的 npm 发版)。实测(npm rc.5 基线):`dsh web` 启动后 `window.__DSH_BOOT__` 清单包含 `@dsh-external/dsh-ui-progress`(inject: `dsh-client-locale`/`dsh-client-runtime`/`dsh-client-ui-conversation`),`/plugins/@dsh-external/dsh-ui-progress/client.js` 返回 200;src 对 rc.5 基线构建产物 typecheck 全绿(本插件已把 cordis 类型导入与 peer 迁移至 `@deepseek-ai/cordis`,见下)。注意:0811 起 vendored cordis 更名为 `@deepseek-ai/cordis`(npm 发版不再发布 `cordis` 名义的 vendored 包),本插件已迁移(peer 声明 `@deepseek-ai/cordis: ^4.0.1-rc.1`,npm rc.5 基线上为 `4.0.1-rc.4`),纯 `npm install` 不再报 ERESOLVE。

> **alpha 发版兼容**:兼容 `dsh-v0.1.2-alpha.1`(GitHub tag `dsh-v0.1.2-alpha.1`,源码构建安装,不发布 npm;v0.9.4 迁移并验证:0.1.2-alpha.1 移除了 `@deepseek-ai/dsh-client-runtime` 客户端包,`ClientContext` 改从 `@deepseek-ai/cordis` 导入、`ConversationSnapshot` 重构为 views 架构(旧 `nodes`/`turnTimings`/`turnEnds`/`partial`/`runningCalls` 全部移到 `ChatSnapshot.legacy` 兼容投影,turn 时间线在 `ChatSnapshot.timeline`)。本插件已在 0.1.2-alpha.1 源码基线上重写状态推导(session-state.ts 改为读取 Chat legacy 切片 + 新 SessionSnapshot 的 `lastAgentError`),typecheck、39 个单测与构建全绿,注册改用 `ctx.slots.inject('conversation.input.dock', …)` 新范式)。
本插件 v0.9.7 起内置**兼容性自诊断**:apply 时探测所需客户端 API,不满足时不再崩溃,而是在页面右下角渲染修复指引横幅(点击可关闭),提示升级 DSH 或更新插件。

> git 依赖方式固定 tag(公开镜像,推荐):`pnpm add '@dsh-external/dsh-ui-progress@github:omdsh-dev/dsh-ui-progress#v0.11.9'`(或 `github:omdsh-dev/dsh-ui-progress`;历史版本:0809 用户用 `#v0.9.0`,0808 用户用 `#v0.8.0`,0807 用户用 `#v0.6.0`,0805 用户用 `#v0.1.0`)。

## 0809 兼容要点(snapshot0809,实机验证)

- 0809 运行中的 `dsh web` 的 `window.__DSH_BOOT__` 清单包含 `@dsh-external/dsh-ui-progress`,`conversation.input.dock` 进度条正常渲染——运行中加载圈旋转、todos 真实比例填充、完成浅绿、中断橘红、待办琥珀各态实测正常。
- **加载机制变化**:0809 重构了客户端插件机制——旧的 `dsh.plugin.json` 清单 + `resolveClientPath`(`packages/plugin/plugin`)已删除,改为 **package.json 的 `dshClient` 声明**(`platform: 'web'`,可选 `inject`/`immediately`)+ `exports["./client"]` 指向构建产物;宿主扫描 loader 条目组成 boot 图,Web 端从 `/plugins/<id>/client.js` 拉取。本插件 package.json 已满足该声明,无需改动。
- 本插件使用的槽位 `conversation.input.dock`(list/session)与 keyed `tool.call.toolview` 在 0809 上仍由官方客户端声明(`tool.call.toolview` 的 owner 类型与 0808 一致);`useSession` 快照与 todos 投影契约未变。
- **构建要求**:0809 宿主在激活时校验 `dshClient` 包的构建产物,缺失会抛 `ClientPackageCompositionError` 并**拒绝启动 `dsh web`**——升级快照或改源码后必须重新 `pnpm run build` 再启动,否则浏览器拉到的是旧 `lib/client.js`。

## 0810 兼容要点(snapshot0810,实机验证)

- **元数据发现变化**:0810 的 ClientModuleHostService 在启动时扫描已加载插件的 package.json,但只读**嵌套 `dsh.client`**(`packages/client/modules/src/index.ts` 的 `resolveMeta`,`pkg.dsh.client`);顶层 `dshClient` 字段读不到会静默丢出 boot 图——无日志、无报错,"启动顺利但插件全没"。本插件已从顶层 `dshClient` 迁移为嵌套 `dsh.client`(inject/platform 原样保留),0810 实机验证 `window.__DSH_BOOT__` 清单包含本插件、进度条各态正常。
- **无需重构建**:`lib/client.js` 构建产物不变,package.json 不参与编译;symlink 安装改源仓库即生效,无需重装。

## 0811 兼容要点(snapshot0811,实机验证)

- **cordis 更名(本快照唯一影响本插件的官方变化)**:0811 将 vendored cordis 由 `cordis@4.0.0-rc.7` 更名为 **`@deepseek-ai/cordis@4.0.1-rc.1`**(官方 client 包随之全部改从 `@deepseek-ai/cordis` 导入)。本插件对 cordis 只有 type-only 导入(`src/invariant.ts` 的 `import type { Context } from 'cordis'`),**构建产物(lib/*.js)零 cordis 运行时导入**——更名不影响已构建 bundle 的运行时加载;但源码对 npm rc.2 基线 typecheck 时 `cordis` 裸导入报 TS2307(仅此一处),**将类型导入迁移为 `from '@deepseek-ai/cordis'` 后全绿**。建议同步把 `peerDependencies.cordis` 迁移为 `@deepseek-ai/cordis: ^4.0.1-rc.1`。
- **实机 boot 验证**:snapshot0811(`snapshots/20260811T152241Z`)web 启动后 `window.__DSH_BOOT__` 清单包含 `@dsh-external/dsh-ui-progress`(inject: `dsh-client-locale`/`dsh-client-runtime`/`dsh-client-ui-conversation`),`/plugins/@dsh-external/dsh-ui-progress/client.js` 返回 200。本插件使用的槽位 `conversation.input.dock`(list/session)、`useSession` 快照与 todos 投影契约在 0811 上均保持声明。
- **测试 fixture 漂移**:typecheck 的 src 全绿;`tests/session-progress-bar.spec.tsx` 有两处 fixture 未跟上 0811 新增字段——`ConversationSnapshot.views`(0811 新增视图快照存储)与 `InputState.imageIds`(0811 新增草稿图片附件)——源码与构建产物不受影响(fixture 已在 v0.9.1 最终快照适配中补齐,见下)。

### 0812/最终快照 兼容要点(snapshots/20260812T172954Z-final,实机验证)

- **cordis 更名落地**:本插件已把 type-only 导入(`src/invariant.ts` 的 `import type { Context } from '@deepseek-ai/cordis'`)与 `peerDependencies`/`devDependencies` 迁移至 `@deepseek-ai/cordis`(`^4.0.1-rc.1`;npm rc.5 基线上为 `@deepseek-ai/cordis@4.0.1-rc.4`)——构建产物(lib/*.js)零 cordis 运行时导入,npm rc.5 消费者 typecheck 全绿,`npm install` 无需 `--legacy-peer-deps`。
- **invariants 源码包迁移(仅影响本地 typecheck)**:最终快照将 `@deepseek-ai/dsh-invariants` 源码包由 `packages/support/invariants` 移至 `packages/runtime-diagnostics/invariants`,devDependencies 路径已同步更新;服务名 `invariants` 与注册协议未变,运行不受影响。
- **测试 fixture 补齐**:`tests/session-progress-bar.spec.tsx` 的 fixture 已补齐 0811 起新增的 `ConversationSnapshot.views`(空视图快照 `{ get: () => undefined }`)与 `InputState.imageIds`(空数组)字段——typecheck(含 tests)与 27 个单测对最终快照基线通过。
- **实机 boot 验证**:最终快照(`snapshots/20260812T172954Z-final`)web 启动后 `window.__DSH_BOOT__` 清单包含 `@dsh-external/dsh-ui-progress`,`/plugins/@dsh-external/dsh-ui-progress/client.js` 返回 200;npm rc.5 consumer `dsh web` 启动后 boot 清单同样包含本插件。本插件使用的槽位 `conversation.input.dock`(list/session)、`useSession` 快照与 todos 投影契约在最终快照与 rc.5 上均保持声明。typecheck、build 与 27 个单测对最终快照基线通过。

## 功能

- **常驻会话进度条**(`conversation.input.dock`,输入框停靠区):读取框架 `useSession` 快照渲染真实执行状态——运行中/空闲、当前在飞的工具名、当前窗口已结算的工具结果数、当前轮次。运行中左侧加载圈**旋转**,进度条 shimmer 扫光 + 品牌色光环脉冲,填充宽度缓动。**填充宽度**:有 `todos` 投影时按真实完成比例((已完成+进行中)/总数,进行中任务计入进度);无 todos 时固定默认 **100%**——会话整体进度没有专门投影,不展示伪百分比(v0.8.0 起移除旧的"每个已结算工具结果进一格、窗口上限 10"分段填充)。运行中额外显示**实时已耗时**(自当前回合开始,0.1s 步进跳动,满一分钟折叠为 `XmYs` 后按秒递增)与 **ETA 预计剩余时间**(仅当模型在最近的 `report_progress` 上报里给出 `eta` 估计——不做线性外推,模型没报就不显示);空闲时显示上一回合耗时。**会话完成(跑过至少一轮后空闲)进度条切换为浅绿色**,从未运行过的会话保持中性蓝灰。
- **中断橘红态**(v0.8.0 新增):本会话**最近一个已结束回合被中断/停止**——手动打断、API 故障或其他意外原因——进度条切换为**橘红色**(浅橘背景 + 橘红填充/图标/百分比 + 慢速脉冲),标签显示"已中断",优先于运行中/完成态的常规配色。只按**最近一个**回合判定:中断后继续发送并正常完成的新回合会让进度条恢复正常配色(中断遗留标记仍保留在窗口内但不再触发)。注意态(琥珀,见下)仍优先于中断态。
- **实时 token 生成速率**(v0.9.0 新增):运行中**模型正在生成**时(有流式 partial 内容、且无待处理的人机交互),进度条在已耗时旁显示实时速率(如 `12.3 tok/s`,斜体品牌色,固定最小宽度保持进度条右侧稳定)。流式 chunk 不携带 token 计数(核心端只有回合结束后的 provider usage),因此该值是**自校准估算值**:初始按 CJK 感知字符密度折算当前 partial 的 token 数(中日韩宽字符 1 字符 ≈ 1 token,其余按核心 token-meter 同款 4 字符 ≈ 1 token);一旦窗口内任何已结算 step 上报了真实 output tokens,就用其「真实 tokens ÷ 加权字符数」密度缩放当前流式估算——数字会贴近所用模型 tokenizer 的真实密度,而非固定字符启发式。速率按**滑动窗口平均**(默认 1s 窗口)计算:每 ~1s 刷新一次、只统计最近窗口内新增的 token,消除逐 chunk 闪动;空窗口保持上次读数不归零。速率除以窗口时长(排除 TTFT)——与核心端回合结束后显示的结算 tokens/s(outputTokens/decodeMs)口径一致,运行中数值可直接与结算值对比。每个新 step 重新起算;工具执行/等待人机交互/回合结束时不显示(结算后的精确速率由核心 StatsLine 呈现,避免重复展示同一事实)。
- **待办提醒(attention)**:本会话或其后代 subagent 会话存在**等待人处理的交互**(沙箱命令审批 / 选项选择 / 计划审阅)时,进度条切换为**琥珀色警告态**(浅琥珀背景 + 琥珀填充/图标 + 慢速脉冲),文字提示来源与类型——`等待审批` / `需要选择`(本会话)、`子代理等待审批` / `子代理需要选择`(subagent)、`等待审批 · 子代理 2 项待处理`(并存时)。subagent 会话被官方侧边栏隐藏,其 pending 状态从全局会话列表(`origin: 'subagent'` 行的 `pendingInteraction`)读取——这是主 agent 感知子代理等待的主要出口。优先级:pending(琥珀) > running(蓝) > interrupted(橘红) > done(绿) > idle(中性)。

## Model Experience

v0.8.0 起本插件**不再注入任何模型可见输入**:`report_progress` 工具与上报引导段落已移除(宿主 half 为空),插件只做浏览器端呈现。若其他宿主插件注册 `report_progress` 工具,会话进度条的 ETA 行仍会读取其上报的 `eta` 字段(见上文)。

不注入任何用户消息内容;会话文本与上下文注入不受影响。

## 安装

见 [INSTALL.md](INSTALL.md)(组织内成员)。

## 配置

无配置键。安装后只需在配置树里插入一行:

```yaml
- insert:
    - id: dsh-ui-progress
      name: '@dsh-external/dsh-ui-progress'
```

## Export shape

浏览器半 `./client`(`apply`/`inject` 命名空间插件)、空 Node half `./index`、标准 invariant companion `./invariant`。

## Known Limitations and Deferred Work

- 会话整体进度无专门投影:无 todos 时填充固定 100%,不展示伪百分比;todos 比例只反映当前 todos 列表,不代表会话全程进度。
- 中断检测按当前窗口 + 最新回合判定(v0.9.3 起以 `turn/end reason` 为主信号,停止即检出,不再依赖节点痕迹);分页/压缩后旧标记被截断,中断态随之消退;窗口内没有 `turn/end` 事件(如会话被强杀且未修复)时回退到节点痕迹,仍可能漏检。处于重试路径(model-retry)的回合不显示中断态。
- ETA 完全依赖模型在 `report_progress` 的 `eta` 字段上报:模型不报或报错(非字符串/非正数)就不显示;进度条取窗口内**最近一次**上报的 eta,若最近一次未带 eta 则隐藏(即使更早的上报带过)。
- 浏览器 half 刷新页面即生效(宿主 half 为空,升级安装无需重启 `dsh web`)。
- CSS 动效常量(时长/缓动)为本地字面量(当前样式体系尚无 motion token 族);中断橘红色为 warn/error token 的 `color-mix`(样式体系无独立橘色 token)。
- 实时 token 速率为**估算值**(流式 chunk 无 token 计数):先按 CJK 感知字符密度起算,一旦有已结算 step 的真实 provider usage 即按密度**自校准**(首个校准 step 之前的首个回合仍为字符启发式);推理/正文/工具参数一并计入;显示为 1s 滑动窗口平均(本地字面量 `TOKEN_RATE_WINDOW_MS`),非 provider 报告值,回合结束后以核心 StatsLine 的结算 tokens/s 为准。

Install

dsh plugin --profile web add github:omdsh-dev/dsh-ui-progress

Profile: web

  • This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source