🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

Shell 步骤进度 9087/dsh-shell-progress

DeepSeek Harness
908720 天前有提交已提供中文文档扫描:含敏感能力

在工具卡片里实时显示多步命令执行到第几步

29.9/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/15 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add 9087/dsh-shell-progress
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:需留意
是什么[目录]—
dsh 原生插件 · ui
暂无时间戳·判据 →
装得上吗[实装验证]!
实装验证未通过(unknown),装前请到仓库确认最近更新与 issue
L4 · 真实安装等级说明 →
数据截至 2026/11/04·判据 →
安全吗[自动扫描]—
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
数据截至 2026/11/04·判据 →
还在维护吗[仓库]✓
活跃:最近一次提交在 20 天前
暂无时间戳·判据 →
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →

可信度证据

⚠︎ 实装验证未通过(unknown · 2026/11/4) ——可能是验证环境差异,装前建议到 GitHub 仓库确认最近更新与 issue。
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件
查看扫描证据(共 43 处,展示前 26 条)
  • 读取本地文件
    build/tsdown.client.ts:200
    const source = await readFile(fileId)
  • 读取本地文件
    build/tsdown.client.ts:238
    if (existsSync(emitted)) return emitted
  • 读取本地文件
    e2e/card.spec.ts:162
    if (!existsSync(join(repoRoot, 'lib', 'client.js'))) {
  • 写入本地文件
    e2e/card.spec.ts:1724
    mkdirSync(dirname(path), { recursive: true })
  • 写入本地文件
    e2e/card.spec.ts:1757
    mkdirSync(dirname(hoverPath), { recursive: true })
  • 读取本地文件
    e2e/card.spec.ts:1847
    if (existsSync(file)) {
  • 读取本地文件
    e2e/card.spec.ts:1848
    const line = readFileSync(file, 'utf8').split('\n').find((entry) => entry.includes(marker))
  • 读取本地文件
    e2e/fixtures/seed-session.mjs:447
    if (!existsSync(CWD)) process.stdout.write(`SHELL_PROGRESS_E2E_WARN cwd missing: ${CWD}\n`)
  • 读取本地文件
    e2e/helpers/host.ts:52
    if (explicit !== undefined && explicit !== '' && existsSync(explicit)) {
  • 读取本地文件
    e2e/helpers/host.ts:59
    if (existsSync(entry)) return { cmd: process.execPath, prefix: [entry], via: `PATH shim in ${dir}` }
  • 读取本地文件
    e2e/helpers/host.ts:67
    if (existsSync(npxRoot)) {
  • 读取本地文件
    e2e/helpers/host.ts:69
    for (const hash of readdirSync(npxRoot)) {
  • 读取本地文件
    e2e/helpers/host.ts:72
    if (!existsSync(entry)) continue
  • 读取本地文件
    e2e/helpers/host.ts:86
    const version = (JSON.parse(readFileSync(packageFile, 'utf8')) as { version?: unknown }).version
  • 执行外部命令来自配置/变量
    e2e/helpers/host.ts:161
    const proc = spawn(
  • 执行外部命令固定命令
    e2e/helpers/host.ts:211
    const killer = spawn('taskkill', ['/pid', String(proc.pid), '/T', '/F'], { stdio: 'ignore', windowsHide: true })
  • 写入本地文件
    e2e/helpers/host.ts:241
    mkdirSync(workspace, { recursive: true })
  • 写入本地文件
    e2e/helpers/host.ts:247
    writeFileSync(join(home, 'settings.yaml'), `locale:\n preference: ${locale}\n`)
  • 写入本地文件
    e2e/helpers/host.ts:248
    writeFileSync(join(home, '.credentials.yaml'), 'version: 1\nrefs:\n DEEPSEEK_API_KEY: sk-e2e-placeholder-not-a-real-key\n')
  • 删除本地文件递归
    e2e/helpers/host.ts:253
    cleanup: () => { rmSync(home, { recursive: true, force: true }) },
  • 写入本地文件
    e2e/helpers/host.ts:288
    writeFileSync(packageFile, `${JSON.stringify(manifest, null, 2)}\n`)
  • 写入本地文件
    e2e/helpers/host.ts:290
    mkdirSync(join(profile, 'node_modules'), { recursive: true })
  • 写入本地文件
    e2e/helpers/host.ts:310
    writeFileSync(registryFile, `${JSON.stringify(registry, null, 2)}\n`)
  • 读取本地文件
    src/bashtree.ts:147
    if (!existsSync(fileURLToPath(grammarUrl))) return undefined
  • 读取本地文件
    src/pwsh-path.ts:97
    if (existsSync(candidate)) return candidate
  • 执行外部命令来自配置/变量
    src/pwshtree.ts:279
    execFile(
扫描于 2026/11/4(1 天前) · 范围 全包扫描(包内未声明入口) · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

社区实装还没有人打卡 · 装过的第一个就是你
依赖的 DSH / Cordis 模块
@deepseek-ai/dsh-llm@deepseek-ai/dsh-sandbox@deepseek-ai/dsh-tools@deepseek-ai/schemastery@deepseek-ai/cordis@deepseek-ai/dsh-client-connection@deepseek-ai/dsh-client-locale@deepseek-ai/dsh-client-store@deepseek-ai/dsh-client-ui-chat@deepseek-ai/dsh-client-ui-primitives@deepseek-ai/dsh-client-ui-slots@deepseek-ai/dsh-client-ui-tool
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

README

由 DeepSeek 最新模型翻译生成
dsh-shell-progress 一个 DeepSeek Harness 插件:在多步 shell 命令的工具卡片里显示一条分段进度条,一眼就能看出「这条命令现在执行到哪一步」。 ┌──────────────────────────────────────────────────┐ │ Shell 步骤进度 · 构建并运行测试 2/7 │ │ [████|████|▓▓▓| | | | ] ▶ 47s │ ← 收起态就有 ├──────────────────────────────────────────────────┤ │ ● 1 $total = 0 │ │ ● 2 if ($true) { │ ← 展开后: │ ▶ 3 Write-Output "adding $n" │ 每步代码 + 该步输出 │ → adding 1 │ │ ○ 4 Write-Output "done" │ └──────────────────────────────────────────────────┘ 它回答的问题是「命令还在跑,还是卡住了?」——因此实时位置是功能本体,不是加分项。 进度条常驻在收起态:瞄一眼就能定位,藏进展开区就失去了意义。
展开完整文档(README 剩余 1 节)
dsh-shell-progress

一个 DeepSeek Harness 插件:在多步 shell 命令的工具卡片里显示一条分段进度条,一眼就能看出「这条命令现在执行到哪一步」。

┌──────────────────────────────────────────────────┐
│ Shell 步骤进度 · 构建并运行测试 2/7 │
│ [████|████|▓▓▓| | | | ] ▶ 47s │ ← 收起态就有
├──────────────────────────────────────────────────┤
│ ● 1 $total = 0 │
│ ● 2 if ($true) { │ ← 展开后: │ ▶ 3 Write-Output "adding $n" │ 每步代码 + 该步输出 │ → adding 1 │ │ ○ 4 Write-Output "done" │ └──────────────────────────────────────────────────┘

它回答的问题是「命令还在跑,还是卡住了?」——因此实时位置是功能本体,不是加分项。
进度条常驻在收起态:瞄一眼就能定位,藏进展开区就失去了意义。

安装

dsh plugin --profile web add dsh-shell-progress

或直接在 profile 的 cordis.patch.yml 里挂载:

- insert:
- id: shell-progress
name: dsh-shell-progress

然后重启 dsh web(宿主只在启动时加载一次插件)。

模型看到什么

什么都不变。shell_progress 注册的工具,其模型可见文本与 pwsh 工具跑同一条命令 逐字节一致:同样的 stdout、同样的 [stderr] 段、同样的 [exit code: N] 标记。
步骤信息从不进入对话,它走工具结果的 presentationMeta,由宿主持久化到 tool/result 事件上。

模型能读到的地方没有 nonce、没有标记、没有重排序。

配置

| 字段 | 默认值 | 含义 |
| enabled | true | 是否注册 shell_progress 工具。 |
| pollIntervalMs | 120 | 宿主读取运行中进程输出的间隔。 |
| maxStepOutputChars | 8192 | 每步输出在持久化进度里保留的字符数。 |
| maxSteps | 400 | 超过此步数的命令按原样执行。 |
| liveRetentionMs | 300000 | 已结束调用的实时记录保留多久,供迟到的轮询读取。 |

工作原理

1. 切分:只在顶层步骤打点——非空行、起始于第 0 列、不以 } 开头、花括号深度为 0。
计数时跳过单引号串、双引号串(含反引号转义)与 # 注释。循环体永远不是步骤,所以迭代多少次都只产生一个标记。
2. 插桩:标记前缀在该步骤自己那一行,不新增行,其余行逐字保留。
3. 执行:插桩后的文本走 ctx.shell,与 pwsh 工具完全同路——同样的超时、沙箱策略、受管环境与取消语义。
4. 跟随:命令运行期间读增量输出,把每个标记变成「当前步骤」,并用单调时钟打时间戳。
5. 持久化:每步起止时间与输出走 output.presentationMeta,因此重新加载会话后,整张卡片可以只凭会话日志复现。

埋点必须内联

src/instrument.ts 里有完整说明;一句话版:PowerShell 里函数调用本身也是一条命令,它会覆盖 $?。所以把埋点写成辅助函数,就会悄悄改掉被插桩命令读到的值——而且调用方之后读到的 $? 是辅助函数的成功状态,即使在函数内部捕获并恢复也无济于事。
本机实测(Windows PowerShell 5.1,即未装 PowerShell 7 时 shell 能力缝实际解析到的那个):

| 埋点形态 | 紧接失败命令之后的 $? |
| 不插桩(对照) | False ✅ |
| 辅助函数(内部捕获+恢复) | True ❌ |
| 内联捕获+恢复 | False ✅ |

tests/powershell.spec.ts 会把两种形态都真的跑一遍并断言这个差别,所以将来若有人把埋点重构成函数,测试会失败。

什么时候不跟踪

以下任一条件成立时,命令按原样执行,卡片降级为「知道有几步、但不知道在哪一步」:

- 切分器遇到无法判定的结构(未闭合引号、块注释、here-string、续行符、花括号或圆括号不平衡);
- 命令只有 1 步或更少;
- 命令里已经出现本方案的标记形状,或已经使用 $__ok;
- 解析出的沙箱模式是 read-only;
- 步数超过 maxSteps。

这些都不是错误:模型拿到的与 pwsh 完全一致。

结构

| 半边 | 源码 | 运行环境 |
| Host | src/index.ts(以及旁边的纯函数模块) | DSH 宿主进程(Node) |
| Client | src/client/*(React) | 浏览器 |

两边只共享 src/types.ts 与 src/split.ts。

实时通道是轮询,不是推送。 安装在 DSH 仓库之外的插件收不到宿主事件(转发事件白名单是构建里的静态数组),所以浏览器在调用进行期间每隔约 250ms 向本插件自己的已认证请求/响应通道 /shell-progress 问一次。已结束的状态不需要轮询:它本来就在会话日志里。

开发

pnpm install
pnpm run typecheck
pnpm test
pnpm run build

详见 DEVELOP.md 与 PUBLISH.md。

许可

MIT
预览分享卡片长什么样 ↓9087/dsh-shell-progress
分享 · DeepSeek Harness Hub
9087/dsh-shell-progress

在工具卡片里实时显示多步命令执行到第几步

这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。
认领条目 →
回到顶部