Contributing¶
The contributing guide lives in .github/CONTRIBUTING.md in the repository and is included below.
Thanks for helping. Questions go to SUPPORT; everyone taking part follows the Code of Conduct.
Development setup¶
Clone the repository. You need Node 18 or newer. There is no install step: no npm dependencies and no build step.
- Run the tests with
node --test. Run the full suite astimeout 300 node --test. node --testruns every.jsfile undertest/, so keep nothing there except*.test.js. Helpers go infixtures/(a helper undertest/once hung the suite for hours).- CI runs the tests on Node 18, 20 and 22 on Linux and macOS for every push to
mainand every pull request. node scripts/check-version.js [tag]checks thatherdr-plugin.toml,package.jsonand the top CHANGELOG heading carry the same version.
The sandbox rule¶
Never run herdr against your live session. Your dev shell usually sits in a herdr pane where HERDR_SOCKET_PATH points at your real server, so any herdr … command acts on it. Use the sandbox procedure in PLAN.md → Testing. Before linking the plugin, confirm herdr plugin list in the sandbox shows no plugins. Link or install into your real herdr only on purpose.
Smoke test¶
scripts/smoke.sh /tmp/cbsmoke (or HERDR_BIN=/path/to/herdr scripts/smoke.sh /tmp/cbsmoke) starts its own headless herdr server in that directory, links a copy of the plugin and checks the tab labels: working ◐, blocked ?, done ✓, the focused tab plain; focusing a tab clears its ✓; the off action restores every name. It unsets every HERDR_* variable first, so it never touches your session.
- Prerequisites: herdr, node 18 or newer, perl; Linux or macOS.
- Exit codes: 0 pass, 1 failure (logs are dumped), 2 usage error or missing prerequisite.
- A run takes under 120 s.
- CI runs it against the minimum herdr (
min_herdr_versioninherdr-plugin.toml) and the latest herdr on Linux and macOS. A weekly canary runs it against the latest herdr.
Project layout¶
bin/cowbell.js: the daemon entry point.bin/ctl.js: the control CLI behind the actions and hooks (start, stop, on, off, toggle, refresh, cycle-preset, status).lib/churn.js: rename-fight bookkeeping.lib/config.js: reading, writing and cyclingconfig.json.lib/control.js: the control commands.lib/daemon.js: the event loop: subscribe, resync, rename, reconnect.lib/icons.js: presets, defaults and config validation.lib/label.js: pure tab-label logic.lib/lock.js: singleton pidfile lock.lib/socket.js: the herdr socket client.lib/state.js:state.jsonand the state directory.
Herdr socket calls stay in lib/socket.js. Label and icon logic stays pure and covered by unit tests.
Branches and commits¶
- Branch names are
{type}/{issue}-{slug}, for examplefix/23-toggle-starts-daemonordocs/24-readme-community. - Commits are conventional:
type(scope): subject (#issue), with a type offeat,fix,docs,ci,test,refactororchore.
Changelog¶
Every user-visible change adds one bullet under ## Unreleased in CHANGELOG.md, in ### Added, ### Changed or ### Fixed, ending in (#N).
Pull requests¶
Open the PR against main. The PR template checklist covers the linked issue, tests, the sandbox check and the CHANGELOG. CI must be green: tests, versions, docs and smoke.
Releasing¶
- Bump
versioninherdr-plugin.tomlandpackage.json. - Rename
## UnreleasedinCHANGELOG.mdto## X.Y.Z — YYYY-MM-DD(with an em dash, as check-version.js expects). - Run
node scripts/check-version.js vX.Y.Z. - Open a PR, let CI pass, merge.
git switch main && git pull, thengit tag vX.Y.Z && git push origin vX.Y.Z.- The Release workflow checks the versions against the tag, runs the tests and publishes the GitHub release with that CHANGELOG section as the notes plus the install line.
To preview, run gh workflow run release.yml -f tag=vX.Y.Z -f dry_run=true. A dry run checks the versions on main against the tag, runs the tests and prints the notes without creating anything, and the tag does not need to exist yet.