Repository navigation
dsh-task-progress 0.1.0
Changelog
All notable changes to this plugin are recorded here. The format follows
Keep a Changelog, and the project uses
Semantic Versioning.
The version here, in package.json, and in both READMEs is checked by
test/release.test.ts, so they cannot drift apart.
0.1.0 — 2026-09-20
First release.
Added
- Progress file protocol (
docs/PROTOCOL.md): append-only JSONL, one file per
task, at<workspace>/.dsh-progress/<session-id>/<task>.jsonl. Any language can
write it; no IPC, no ports, no authentication. - Host half: a
ctx.shellEnvcontributor handing every shell call
DSH_PROGRESS_DIRandDSH_PROGRESS_CLI; a directory-polling store that folds
those files into tasks; and one read-only, cookie-authenticated route
(GET /plugins/task-progress/state) behind the composition's connection trust. - Browser half: a floating overlay in
shell.overlaythat appears only while
work is running, and a right-sidebar tab listing the session's tasks, finished
ones included. - Settings page: the namespace
task-progress, editable in
Settings → Plugins → Plugin configuration, with the plugin row'sconfigas the
composition base layer and live application of every change. - Out-of-the-box convention: a short system-prompt section, so the model
reports long commands without the user editing their own instructions. - Producer CLI (
dsh-progress):emit,done,fail,cancel,path,
list,clear— dependency-free, Node 20+. - Example:
examples/simulate.ps1prints a self-reporting long task.
Notes
- The plugin never reads a background job's output. That cursor is
single-consumer and belongs to the model'sjob_outputtool, so progress here
is what a script chooses to report. - Zero runtime dependencies: the host half imports Node built-ins only, and the
browser half bundles everything it owns (React is a platform external).
Security
First release, so these are properties rather than changes:
- The state endpoint is scoped to one session per request and carries no
filesystem paths. DSH's web login fences the instance, not a session, so an
unscoped endpoint would expose every session's task names to any authenticated
caller. maxTasksbounds the Host's in-memory task set as well as the wire document,
so a producer cannot grow the process by minting task ids.- Producer input is constrained by regular expressions at every level that
becomes a path (session segment, task id, directory name), and the store reads
only*.jsonlfiles it finds inside those directories. - No runtime dependencies, no
postinstall, no network calls from either half,
and no HTML injection surface in the browser half.