Skip to content
dsh.fish
Bundle

dsh-statusbar

VSCode-like bottom status bar for DSH Web: conversation token usage, host CPU/memory with Linux-style colored char bars, clock, and a public API for other plugins.

Source
Small-Miao
stars
2 stars
License
MIT
Updated
Updated 13 days ago

Readme

# dsh-statusbar

A VSCode-style bottom status bar for **DeepSeek Harness Web**. Shows your conversation
usage, host CPU/memory, and a live generation rate — every item configurable.

![DSH Web](https://img.shields.io/badge/DSH%20Web-plugin-4fc1ff) ![License](https://img.shields.io/badge/license-MIT-green) [![Release](https://img.shields.io/github/v/release/Small-Miao/dsh-statusbar)](https://github.com/Small-Miao/dsh-statusbar/releases) [![Changelog](https://img.shields.io/badge/changelog-md-blue)](./CHANGELOG.md)

English | [简体中文](./README.zh.md)

## Features

- 24px bottom bar rendered via the `shell.overlay` seat; the app frame reserves bottom
  space so the page content (sidebar settings, composer) is **never covered**.
- Built-in items (each individually configurable — see [Configuration](#configuration)):
  - `DSH` brand (left)
  - `⧉ Tokens` — estimated tokens of the current conversation (`tokenMeter`)
  - `7 轮 · 64 步` — session turns / steps (`sessionStats`)
  - `LLM 14m12s · 工具调用 48.4s` — accumulated LLM / tool wall time
  - `首 token 平均 1.3s · 129 tok/s` — first-token average + decode throughput
  - `缓存命中 97%` — prompt-side cache hit rate (`tokenUsage`)
  - `输入 7.4M tok · 输出 98.9K tok` — billed input / output tokens
  - `TPS 363 tok/s` — live generation rate (`liveTokenUsage`; needs [dsh-live-stats])
  - `CPU 20% [||||||||||]` — Linux-style colored char bar (green → yellow → red)
  - `MEM 55% (8.2G/14.8G) [||||||||||]` — memory usage with char bar
  - Host clock
- Hides the original stats line + TPS row under the composer input box (now redundant).
- Polls `/dsh-statusbar/snapshot?session=<id>` every 2 s.

[dsh-live-stats]: https://github.com/zhu1090093659/dsh-web-ui

## Installation

Prerequisites: a DSH install with a web profile (e.g. the default `web` profile created by
`dsh web`).

```bash
# from the GitHub repository
dsh plugin --profile web add https://github.com/Small-Miao/dsh-statusbar

# or via SSH (needs GitHub SSH access on this machine)
dsh plugin --profile web add git@github.com:Small-Miao/dsh-statusbar.git

# or from a local checkout (development)
dsh plugin --profile web add /path/to/dsh-statusbar
```

The command runs `pnpm add` in the profile, installs the bundle into
`~/.dsh/profiles/web/node_modules`, and appends the plugin to `dsh.profile.bundles`.
Then **restart DSH**; the plugin mounts at startup and the bar appears after a page
refresh.

> Manual install (no `dsh plugin`): `pnpm --dir ~/.dsh/profiles/web add <path-or-url>`
> works too — the plugin is a standard `dsh.bundle` package.

## Configuration

**Settings → 状态栏**: toggle each item's visibility, side (left / right), and order
(number input, ascending = further left), plus a "全部重置" (reset all) button.

Config is stored host-side and persisted to `dsh-statusbar-config.json` next to the
profile composition. HTTP: `GET /dsh-statusbar/snapshot?session=<id>` returns
`{ items, catalog, config }`; `POST /dsh-statusbar/config` accepts `{ id, patch }`
(`patch` = `{ visible?, align?, order? }`, or `null` to clear) or `{ resetAll: true }`.

## Public API for other plugins

The host exposes a `statusbar` Cordis service. Other host plugins can add their own
items — including live text and char progress bars:

```js
export function apply(ctx) {
  const statusbar = ctx.get('statusbar')
  if (statusbar === undefined) return   // plugin not installed — degrade gracefully
  ctx.effect(() => statusbar.registerItem({
    id: 'my.item',          // required, unique
    order: 15,              // sort order, ascending (configurable by the user)
    align: 'right',         // 'left' | 'right'
    label: () => 'value',   // string or lazy thunk
    style: 'bar',           // 'text' (default) | 'bar'
    progress: () => 62,     // 0-100, number or lazy thunk (bar style)
    barChar: '|',           // optional, default '|'
    barTotal: 10,           // optional, default 10
    color: '#4fc1ff',       // optional label color
    tooltip: 'hint',        // optional hover text
  }))
  // also: statusbar.updateItem(id, patch) / statusbar.removeItem(id) / statusbar.list()
}
```

### Registering a data source

For plugins that own a live value (their own metric, service readout, projection...),
`registerDataSource` lets the status bar pull from a `provide()` callback on its own
refresh cadence and render it as an item (text or char bar):

```js
export function apply(ctx) {
  const statusbar = ctx.get('statusbar')
  if (statusbar === undefined) return
  ctx.effect(() => statusbar.registerDataSource({
    id: 'disk.usage',       // required, unique — also the config key
    order: 55,              // default position
    align: 'right',         // 'left' | 'right'
    style: 'bar',           // 'text' (default) | 'bar'
    barChar: '|',           // optional, default '|'
    barTotal: 10,           // optional, default 10
    refreshMs: 5000,        // optional, default 2000 — host re-calls provide() when stale
    tooltip: '磁盘用量',
    provide: async () => ({ // required — called by the host; return the latest value
      text: '磁盘 62%',
      progress: 62,         // 0-100, used when style is 'bar'
      color: '#4fc1ff',     // optional
      tooltip: 'updated hint', // optional, overrides the default tooltip
    }),
  }))
  // also: statusbar.removeDataSource(id)
}
```

Data sources appear in the bar and in Settings → 状态栏 exactly like built-in items
(users can toggle/position them), and the host renders the last known value while a
slow `provide()` is in flight.

## Development

```bash
git clone https://github.com/Small-Miao/dsh-statusbar
dsh plugin --profile web add ./dsh-statusbar   # or symlink into the profile
```

- `lib/index.js` — host half: `statusbar` service, `/dsh-statusbar/*` HTTP routes,
  `node:os` CPU/memory sampling, session projections (`sessionStats` / `tokenUsage` /
  `liveTokenUsage`) cached 4 s per session.
- `lib/client.js` — browser half (`__ModuleLoader__` bundle): the bar in `shell.overlay`
  and the settings section in `settings.section`.

### Layout note

The reserved bottom space relies on the app frame's hashed class (`.pI_x6G_frame` in the
current web build). If the web app is rebuilt with new CSS hashes, update that selector in
`lib/client.js`.

## License

[MIT](./LICENSE)

Install

dsh plugin --profile web add github:Small-Miao/dsh-statusbar

Profile: web

  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source