bin/stats.js
Coerces every argv token through Number.isFinite, early-exits on empty, and switches stddev to divide by (n − 1). Smallest possible diff that closes the issue — but adds no tests, so the same regression could slip in next quarter.
parallel-agents · herdr
一个真实 herdr 会话:4 个 pane、4 个 worktree、4 个不同角度的 coding agent,左侧 sidebar 实时打上 working / blocked / idle 图标;等每条分支落一个真实 commit,一份 DIFF_COMPARE.md 建议合哪条。
Open herdr.cast in any asciinema player for the animated version, or view the GIF: herdr-session.gif.
bin/stats.js
Coerces every argv token through Number.isFinite, early-exits on empty, and switches stddev to divide by (n − 1). Smallest possible diff that closes the issue — but adds no tests, so the same regression could slip in next quarter.
bin/stats.js
Splits parse / compute / print, replaces per-branch process.exit(1) with a single catch → console.error → exit at the top level, and exports the pieces for reuse. Reads well — but that's a wider structural change than a 30-line file is asking for today.
bin/stats.jstest/stats.test.js
Wrote three new failing tests first (empty argv, non-numeric token, sample-stddev = 1.29099…), then the smallest change to greenify. Closes the issue AND leaves guardrails behind so the class of bug can't come back.
ROOT_CAUSE.mdbin/stats.js
Wrote ROOT_CAUSE.md first — "two distinct bugs, one symptom" — then only the change the note justifies, plus a linkback comment at the top of bin/stats.js. Best explanation of *why*; the code change itself is close to stats-a.
stats-c. It closes the issue and leaves behind a test suite that stops the same class of bug (empty input, non-numeric tokens, population-vs-sample σ) from returning. Carry stats-b's parse/compute split into a follow-up refactor once the file grows past ~80 lines. Keep stats-d's ROOT_CAUSE.md as a reference, but squash the code change into the stats-c PR. Stats-a's diff is subsumed. You would never have picked this from one agent's output alone.
working means it's producing tokens right now; blocked means it's showing a permission or select-an-option prompt and needs a human; idle means it's back at its input, ready for the next instruction — that's the state you poll with herdr wait agent-status <pane> --status idle. When an agent finishes and exits its shell, the pane drops to unknown, because there's no live output to read anymore — that isn't a bug; it's herdr telling you truthfully "there's no agent here now". The ground truth for "the work is done" is the branch tip: git -C <worktree> log --oneline -1.