npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@williamthorsen/toolbelt.git

v0.4.1

Published

Utilities for working with git

Downloads

444

Readme

@williamthorsen/toolbelt.git

Utilities for working with git.

Installation

pnpm add @williamthorsen/toolbelt.git

Requires Node.js 24 or later.

CLI

The package ships a tb-git command exposing the same functions to a shell caller.

pnpm add --global @williamthorsen/toolbelt.git   # puts tb-git on PATH
npx @williamthorsen/toolbelt.git branch-number   # or run it without installing

The short npx form works because the package declares exactly one bin, which npm falls back to, whatever its name. Were a second bin added, the invocation would become npx --package @williamthorsen/toolbelt.git tb-git ....

tb-git --help, each subcommand's --help, and tb-git --version report the surface and the installed version.

tb-git branch-number [<branch>] [options]

Prints deriveBranchNumber's result.

| Option | Effect | | ------------ | ----------------------------------------------- | | --key K | The project's ticket key, matched in any casing | | --max N | Upper bound, inclusive (default 4294967295) | | --min N | Lower bound, inclusive (default 0) | | --offset N | Rotate the result within the bounds |

tb-git branch-number 232_add-widget --min 3000 --max 3999
# 3232

A negative offset takes the = form, --offset=-3: A bare -3 reads as an option rather than as the value.

tb-git ticket-ref [<branch>] [options]

Prints findBranchTicketRef's id.

| Option | Effect | | --------- | ----------------------------------------------- | | --json | Print the whole ref on one line as JSON | | --key K | The project's ticket key, matched in any casing |

tb-git ticket-ref wt/MAC-22.1-add-widget
# MAC-22

tb-git ticket-ref wt/MAC-22.1-add-widget --json
# {"id":"MAC-22","key":"MAC","number":22,"revisit":1}

The branch argument

With no <branch>, both subcommands resolve the checked-out branch with git branch --show-current, which reports a worktree's own branch. A directory that is not a repository, an absent git, and a detached HEAD each fail rather than falling back to a derived value. An empty argument is an error too, so tb-git ticket-ref "$BRANCH" with BRANCH unset fails instead of quietly using the current branch.

Exit codes

| Code | Meaning | | ---- | ----------------------------------------------------------------------- | | 0 | A result was printed | | 1 | ticket-ref found no ticket in the branch name; both streams are empty | | 2 | Usage or validation error, with the message on stderr |

A bound, offset, or key rejected by the library exits 2, reporting the message that it raises. So does an empty option value, so --min "$PORT_MIN" with PORT_MIN unset fails instead of bounding at 0.

if ref=$(tb-git ticket-ref); then
  echo "on ticket $ref"
fi

findBranchTicketRef

findBranchTicketRef(branch: string, options?: { key?: string }): BranchTicketRef | undefined;

interface BranchTicketRef {
  readonly id: string;
  readonly key?: string | undefined;
  readonly number: number;
  readonly revisit?: number | undefined;
}

Finds the ticket encoded by a branch name, or undefined when it encodes none.

import { findBranchTicketRef } from '@williamthorsen/toolbelt.git/candidate';

findBranchTicketRef('wt/MAC-22.1-add-widget');
// { id: 'MAC-22', key: 'MAC', number: 22, revisit: 1 }

findBranchTicketRef('232_add-widget');
// { id: '232', number: 232 }

A ref must begin a segment. / and _ both delimit one, so an author prefix and a worktree-safe spelling parse alike, and the leftmost segment with a ref wins. Anchoring to a segment keeps a kebab-case description from reading as a ticket: feat/add-widget-2 encodes none, because widget follows a hyphen rather than a separator.

Two forms are recognized, each taking an optional .N revisit suffix. A keyed ref is a Jira-style key and number, the key matching Jira's own rule of a letter followed by letters and digits. A bare-numeric ref is the number alone. id and key are emitted uppercased, since a branch name may be lowercase but the ticket that it names is MAC-22.

By default a key must be uppercase, which Jira permits and which is the only property separating a real key from an ordinary word: Without it, feat-2 would read as ticket FEAT-2. Declaring the project's own key through key is both more permissive and more precise, since it then matches in any casing and is the only key that matches at all.

findBranchTicketRef('mac-22/add-widget');
// undefined -- a lowercase key with none declared

findBranchTicketRef('mac-22/add-widget', { key: 'mac' });
// { id: 'MAC-22', key: 'MAC', number: 22 }

findBranchTicketRef('feat-2', { key: 'mac' });
// undefined -- `feat` is not the declared key

The bare-numeric form stays active whether or not a key is declared. A RangeError names the fault when key is not a well-formed key, which would otherwise match nothing at all.

A trailing -N is not read as a sub-ID, being indistinguishable from a description: 232-3-column-layout has no revisit. Neither suffix affects number.

deriveBranchNumber

deriveBranchNumber(branch: string, options?: { key?: string; max?: number; min?: number; offset?: number }): number;

Derives a number from a branch name, for a port offset, a bucket, or any slot that must stay stable across checkouts of the same branch.

import { deriveBranchNumber } from '@williamthorsen/toolbelt.git/candidate';

deriveBranchNumber('232_add-widget');
// 232

deriveBranchNumber('main');
// 663286764

The number is the ticket's when the branch names one, and a hashString digest of the whole name when it does not, so every branch yields something. min, max, and offset are hashString's, and apply to both paths alike: The two land in one range, and offset stays a pure rotation.

deriveBranchNumber('232_add-widget', { min: 3000, max: 3999 });
// 3232

deriveBranchNumber('refactor/tidy-imports', { min: 3000, max: 3999 });
// 3508

A number that overruns the range wraps into it, so deriveBranchNumber('1232', { max: 999 }) is 232. key is passed through to findBranchTicketRef, and a bad key, bound, or offset raises the same RangeError whether or not the branch names a ticket.