
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
At Wirth & Horn we use Redmine for project management and time tracking. Since 2024 we have a custom internal Slackbot that lets us track our active work hours and greet each other.
This CLI tool, whstats ("Wirth & Horn Statistics"), reads both sources, and provides a custom unified view of booked vs clocked hours, as well as longer term statistics. It is custom built for my own needs and those of my colleagues, and is not intended for public use.
A custom CLI tool for tracking and analyzing work hours at Wirth & Horn.
Get started!
Run directly
·
Configure
·
Contribute
whstats can be run directly with bun x whstats or npx whstats, which ensures you're always running the latest version.
The first time you will be prompted to set up your credentials interactively. See: Configuration.
You can install it globally, allowing you to run whstats directly, but this requires manual updates.
bun:
# install
bun install -g whstats
# update
bun update -g whstats
npm:
# install
npm install -g whstats
# update
npm update -g whstats
# Show time statistics for the last 7 days (default)
whstats
# Range commands
whstats --week # or -w, show last 7 days (same as default)
whstats --month # or -m, show last 30 days
whstats --year # or -y, show past 365 days
whstats --year-to-date # or -Y, show from Jan 1 to today
# Output modifiers (combine with range commands)
whstats --brief # or -b, concise output (daily totals only)
whstats --json # or -j, output as JSON
whstats -mb # combined example for --month --brief
# Configuration commands
whstats --config # or --setup, first time setup (interactive)
whstats --show-config # show config file location and current settings
whstats --reset # delete configuration
# Help
whstats --help # or -h, show help
whstats --version # or -v, show version
Run whstats --config (or whstats --setup) to interactively enter your Redmine API key and other settings. Values marked in square brackets [] show preconfigured defaults, or past configuration, and can be accepted by pressing Enter.
To change your configuration later, simply run whstats --config again to edit and overwrite existing values.
Configuration is stored in ~/.config/whstats/config.json automatically.
{
"redmineUrl": "https://redmine.wirth-horn.de",
"redmineApiKey": "<your_redmine_api_key>",
"mssqlServer": "10.10.10.15",
"mssqlDatabase": "wh_timelogger",
"mssqlUser": "<username>",
"mssqlPassword": "<password>",
"slackUserId": "<slack_user_id>",
"targetHoursPerDay": 8,
"ignoredRedmineTicketIds": [39193]
}
ignoredRedmineTicketIds lets you exclude one or more Redmine ticket IDs from "booked-hour" calculations. This is useful for "non-productive" tickets (for example, sick days), that don't pair with Slackbot presence data. In the interactive setup, use comma-separated numbers.
During whstats --setup, existing ignored IDs are prepopulated so you can edit and overwrite the full list.
Fetching time entries for John Doe...
[...]
2026-02-03 Monday: 8h booked / 8.25h clocked
- #11111 4h Implemented feature X
- #22222 4h Code review and testing
2026-02-04 Tuesday: 7h booked / 7.41h clocked
- #33333 3h Bug fixes
- #44444 4h Documentation updates
────────────────────────────────────────────────────────────
Summary (past 6 days)
Target: 40h + 7.41h
Booked: 40h + 7h = 99% (-0.41h)
Clocked: 43.59h + 7.41h = 115% (+3.59h)
Efficiency: 92% (booked/clocked ratio)
# Install dependencies
bun install
# Run locally
bun run index.ts
# Run with flags
bun run index.ts --help
bun run tscbun run index.ts and verify output is correct--help and --version flags (also -h, -v)--week (-w), --month (-m), --year (-y), --year-to-date (-Y)--brief (-b), --json (-j)bun run index.ts -Yb or --month --jsonbun run build && node dist/index.js --version) runs correctlyFollow this checklist when publishing a new version:
files array in package.json to ensure only necessary files are publisheddist/ directory is not committed to git (should be in .gitignore)CHANGELOG.md, --help command output and README.md are up to date with new changes, if relevantBump version (creates git tag automatically):
npm version patch # 1.0.0 → 1.0.1 (bug fixes)
npm version minor # 1.0.0 → 1.1.0 (new features)
npm version major # 1.0.0 → 2.0.0 (breaking changes)
Publish to npm:
npm publish
prepublishOnly hook runs npm run build before publishing (compiles TypeScript)package.json files array are published (dist//*.js, dist//*.d.ts)v1.0.1) when you run npm versionnpm view whstatsnpx whstats --helpgit push --follow-tagsMIT
FAQs
WH Stats - Compare booked hours (Redmine) vs clocked hours (timelogger)
We found that whstats demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.