Report progress from any script, crawler, CI job or agent, and watch it from anywhere. Get a push notification when it finishes.
npm install -g progresswatchThe server is progress-watch/progresswatch, hosted at progress.watch or run by yourself.
progresswatch space new "My stuff" # saved as the default
TASK=$(progresswatch new "Crawl docs") # a task to report against
progresswatch update $TASK --current 1200 --end 50000 # in your loop
progresswatch done $TASK # sends the notificationTo report into a space you already have:
progresswatch space use <uuid> --server https://progress.watchprogresswatch status check the current space's server
progresswatch configure --server <url> point this machine at your own server
progresswatch space new [title] [--local] create a space, save as default
progresswatch space list spaces known locally
progresswatch space use <uuid> [--server <url>] [--local] switch the default
progresswatch space unbind drop this directory's space
progresswatch connect print QR + deep link to pair the phone
progresswatch new <title> [--parent <uuid>] create task, print uuid
progresswatch update <uuid> [--current N] [--end N] [--values k=v ...]
progresswatch start <uuid> mark task running, before it can count
progresswatch done <uuid> mark task finished
progresswatch list [--limit --before --after] tasks in the default space, unfinished first
progresswatch show <uuid> task detail with children
progresswatch run <command> run a command and track it
Every command supports --help.
TASK=$(progresswatch new "Crawl docs")
progresswatch start $TASK
progresswatch update $TASK --current 1200 --end 50000 --values pages=1200 --values log="Retrying /foo"
progresswatch done $TASKEvery update replaces the whole state, so send all of it each time; a log value shows as
the task's last line.
progresswatch run "python train.py"
progresswatch run --title "Nightly training" "python train.py --epochs 100"
progresswatch run -- rsync -av /data /backup # argv form, no shell involvedIt reports a start and a finish, not counts, and exits with the command's exit code.
DEPLOY=$(progresswatch new "Deploy")
BUILD=$(progresswatch new "Build" --parent $DEPLOY)
TEST=$(progresswatch new "Test" --parent $DEPLOY)One level deep. A parent's bar averages its children, but it does not finish on its own:
done it after the last step.
- stdout carries only the result: a bare UUID, or JSON with
--json - everything a person reads goes to stderr
- failure exits non-zero
export PROGRESSWATCH_SERVER="https://progress.watch"
export PROGRESSWATCH_SPACE="$MY_SPACE_UUID"
TOTAL=$(wc -l < urls.txt)
TASK=$(progresswatch new "Nightly crawl")
trap 'progresswatch done "$TASK" || true' EXIT
n=0
while read -r url; do
n=$((n + 1))
curl -sf "$url" -o "out/$n.html" || true
if (( n % 50 == 0 )); then
progresswatch update "$TASK" --current "$n" --end "$TOTAL"
fi
done < urls.txtprogresswatch show "$TASK" --json | jq -r '.progress.ratio'
progresswatch list --json | jq -r '.tasks[] | select(.finished_at == null) | .title'Stored at ~/.progresswatchrc, readable only by you:
{
"server": "https://progress.watch",
"space": "406d45fd-f623-472a-acac-eef9b5281549",
"spaces": [
{
"uuid": "406d45fd-f623-472a-acac-eef9b5281549",
"title": "Production",
"server": "https://progress.watch"
}
]
}PROGRESSWATCH_SERVER |
server URL; overrides the per-space server, for CI |
PROGRESSWATCH_SPACE |
space UUID, same as --space |
PROGRESSWATCH_CONFIG |
config file path, default ~/.progresswatchrc |
progresswatch configure --server https://pw.internal
progresswatch configure --listIt applies to spaces you create from now on; each existing space keeps the server it was created on.
progresswatch show "$TASK" --space "$OTHER_SPACE_UUID"progresswatch space new "Crawler" --local
progresswatch space use 406d45fd-... --local
progresswatch space unbindAnyone with it can read and write the space, and there are no accounts to recover it from:
keep it in a secret rather than a committed file, and back up ~/.progresswatchrc.
progresswatch connectOn iOS, add the page to the Home Screen to get notifications.
The package ships an agent skill, so an agent reports its own long-running work into a space:
npx skills add progress-watch/progresswatch-cliAn agent can also skip the CLI and use the server's MCP endpoint.
Requires Node 20 or newer.
npm install
npm run build # esbuild -> dist/cli.js
npm test # builds, then runs the suite against an in-process mock server
npm run typecheck
PROGRESSWATCH_E2E_SERVER=http://localhost:7979 npm run test:e2e # the same commands against a real serverDistributed under the MIT license.