Draggable floating card that follows background jobs: a progress bar and percentage parsed from wget/curl/apt/pip output, elapsed time, ETA when present, and the latest output line.
Install
# from a prebuilt release tarball
dsh plugin --profile web add "https://github.com/yezitotempeace/dsh-job-progress/releases/latest/download/dsh-job-progress.tgz"
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:yezitotempeace/dsh-job-progress
Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).
README
As soon as a background job starts (a download, a build, a render…), a floating card appears in the bottom-right corner of the session: one row per job with a progress bar, percentage, elapsed time and the latest output line. It disappears when everything has finished.
What it shows
| Part | Detail |
|---|---|
| Label | The job label, usually the command that started it |
| Status | Dot: green = running, amber = stopping, red = failed, grey = settled |
| Bar | The job's own progress field when set; otherwise parsed from the output tail (45%, curl's table row, 1.2 GB / 3.4 GB); indeterminate when nothing parses |
| Percentage | Shown on the right when a number is known |
| Elapsed | Ticks live while running, freezes when settled |
| Latest output | Last line (ANSI stripped, whitespace collapsed, 180 chars), with eta appended when present |
At most 4 rows; the rest collapse into "N more".
Interaction
- Click the header to collapse into a pill:
Background jobs 2+ aggregate bar + average percentage; click again to expand. - The whole card drags: press the header and move it anywhere on screen; the spot
is remembered in the browser (
localStorage, keydsh-job-progress/position) and restored after a reload. The collapsed pill drags too, and positions are clamped to the viewport. - A settled job stays for 8 seconds with its final state, then the card goes away (nothing renders when there are no jobs).
- Only the current session is watched; output streams are subscribed on demand and released when the row unmounts or the job ends.
What it can parse
wget, curl (default table and -# bar), apt, pip, npm, and anything that prints
NN% to stdout. The reading is heuristic:
- the job's own
progressfield wins when the producer sets one; - otherwise the last 40 output lines are scanned for a percentage, including
\r-refreshed meters; - if nothing parses, the card shows an indeterminate bar plus the latest output — at least you can see it moving.
How it works
| Part | Approach |
|---|---|
| Data | ctx.jobs.state (roster) + ctx.jobs.watchRows(sessionId) + ctx.jobs.observe(sessionId, id) |
| Mount | conversation.session.header.actions (only for sessionId), rendered into document.body through createPortal |
| Parsing | pure parseProgress(text): strip ANSI → split on \r\n → scan the tail for % / curl's table → speed, ETA, byte ratio |
| Rendering | fixed position, z-index: 60, bottom-right by default (safe-area-aware bottom), theme tokens for colour |
| Dragging | pointer events + setPointerCapture; movement past 4px counts as a drag, otherwise a click; position clamped to the viewport and written to localStorage |
Never reads conversation content and issues no extra network requests (only the job output stream).
Test
node test/smoke.mjs
# [job-progress] PASS (19 checks)
Covers bundle registration and inject, and parseProgress for wget/apt/curl
table/curl bar/pip/ANSI/\r updates/byte ratio/ETA, plain logs not misread, empty
output, and the drag-position clamp.
Install
dsh plugin --profile web add github:yezitotempeace/dsh-job-progress
Then add dsh-job-progress to dsh.profile.bundles in the profile package.json and
restart the Web app. (plugin add only installs the dependency; bundles are not
mounted automatically.)
Local development: put the repo at /root/dsh-job-progress, set
"dsh-job-progress": "link:/root/dsh-job-progress" in dependencies, add
dsh-job-progress to dsh.profile.bundles, link node_modules/dsh-job-progress, and
restart the Web app.
Limits
- A job must print progress to stdout; progress written to a file stays invisible.
- The card is fixed bottom-right, above the composer on narrow screens; collapse it to a pill.
- Output comes from DSH's
job.followstream — nothing is retained once the card is gone.
License
MIT
Links
More in this category
zhu1090093659/dsh-web#packages/dsh-task-board★ 9262
Task board for the dsh web GUI: a sidebar multi-column kanban whose cards run in real DSH agent sessions and can also be scheduled with cron expressions, executed host-side even with the browser closed.
zhu1090093659/dsh-web#packages/dsh-web-all★ 9262
Plugin and skin collection for the DSH Web UI: task board, Git graph, right-side panel, remote mobile UI, pet, live token stats, and a skin center.
MeteorNOX/DeepSeek-Balance-Whale-Widget★ 5677
A fixed-corner whale widget for the DSH web GUI — balance, today's usage and per-turn cost with peak/off-peak pricing, editable balance-alert and daily-budget bubbles, a module-based custom bubble queue with A/B weighted choices and random lines or images, 30+ vendor templates (OpenAI, OpenRouter, Kimi, SiliconFlow, Ark, Zhipu, MiniMax and more) with per-model balance and subscription quota, plus task-end sound, imported audio, custom roles and a resource manager. Local-only, no telemetry.
ccch1mneyyy/dsh-TUI★ 5125
Claude Code-style full-screen terminal UI: pixel-whale header, live status line, and streaming thought expansion.
omdsh-dev/DSH-better-sidebar★ 4413
Full sidebar workbench with file rendering and editing, terminal, Git, and subagents; third-party plugins can register new tabs.
Devin-AXIS/deepseek-design#deepseek-idesign★ 1491
Visual design studio for websites, app prototypes, posters, cards, reports, and magazines, with templates, direct element editing, selection-aware AI draft handoff, and export.
Community comments
Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.