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

butmux

v0.4.6

Published

butmux - Terminal workspace manager for GitButler, tmux, and Kitty

Readme

butmux

butmux is a terminal UI for managing GitButler branches as real tmux and terminal work contexts.

It gives you one place to:

  • add and switch project directories
  • create independent or dependent GitButler branches from the TUI
  • sync GitButler branches into managed tmux sessions and terminal tabs
  • focus a context, workspace session, or agent pane
  • rename contexts across GitButler, tmux, and the selected terminal backend
  • reorder managed contexts from the keyboard
  • remove orphan tmux and terminal state
  • inspect Codex and Claude panes per context

Requirements

  • macOS or Linux
  • Node.js
  • tmux
  • but (GitButler CLI)
  • kitty with remote control enabled, or wezterm

butmux assumes working contexts are backed by:

  • GitButler branch state
  • tmux sessions
  • terminal tabs in Kitty or WezTerm

Install

npm install
npm run build

During local development, run the built command directly:

./dist/cli.js

To expose butmux on PATH, use your preferred Node/package workflow, for example:

npm link

Run

Start the terminal UI:

butmux

Add the current directory from a shell:

butmux add

Keyboard

j/k or Up/Down     move selection
Enter              focus selected workspace, branch, or agent
r                  refresh
s                  sync selected row's project
a                  add project path
b                  create independent branch in selected row's project
B                   create dependent branch from selected branch
n                  rename selected managed branch
g                  run suggested GitButler setup or teardown
x                  remove selected project or orphan branch after confirmation
c                  create selected row's project workspace session
[ / ]              reorder selected managed branch
,                  cycle terminal backend
?                  show help
q or Ctrl+C        quit

Branch Creation

Use b to create a new independent GitButler branch for the selected row's project. butmux runs:

but branch new <name>

Use B from a managed branch row to create a dependent branch anchored to the selected branch. butmux uses the selected GitButler branch id when available and falls back to the branch name. It runs:

but branch new <name> -a <anchor>

After creation, butmux syncs the project so the new branch gets its managed context, tmux session, and terminal tab.

Configuration

butmux stores user settings under XDG config:

${XDG_CONFIG_HOME:-~/.config}/butmux/config.json

Example:

{
  "terminalBackend": "kitty"
}

Supported terminal backends:

  • kitty
  • wezterm

If the config file is missing, butmux defaults to kitty.

State

butmux stores projects, contexts, and ordering under XDG state:

${XDG_STATE_HOME:-~/.local/state}/butmux/registry.json

Example shape:

{
  "projects": [],
  "contexts": []
}

How butmux Works

For each GitButler branch in a registered project, butmux manages:

  • one tmux session
  • one terminal tab
  • one registry entry for ordering and persistence

Managed names use this shape:

bm_<project-slug>_<branch-key>

Examples:

  • git-butler-practice + butmux-parser-test -> bm_gbp_butmux-parser-test
  • butmux + kn-branch-1 -> bm_butmux_kn-branch-1

Each project can also have a workspace session. Its tmux session name is the project directory basename, for example /repo/butmux -> butmux.

Agent Integration

butmux supports Codex and Claude status updates through tmux pane options.

The intended flow is:

Agent hook -> butmux hook <agent> <event> -> tmux pane options -> butmux TUI refresh

Supported Codex Events

  • SessionStart
  • UserPromptSubmit
  • Stop

These map to:

  • session-start
  • user-prompt-submit
  • stop

Supported Claude Events

  • SessionStart
  • UserPromptSubmit
  • Notification
  • Stop
  • StopFailure
  • PostToolUse
  • SessionEnd

tmux Pane Options

butmux writes and reads these pane options:

  • @butmux_agent
  • @butmux_status
  • @butmux_prompt
  • @butmux_cwd
  • @butmux_started_at
  • @butmux_attention
  • @butmux_wait_reason

Pane status values:

  • idle
  • running
  • waiting
  • error

Plugin Hook Setup

butmux provides Codex and Claude Code plugins in this repository. The plugins install lifecycle hooks that call butmux hook <agent> <event> without butmux editing your personal ~/.codex or ~/.claude settings files directly.

Install the butmux CLI first:

npm install -g butmux

For local development, npm link is also fine as long as butmux resolves on PATH:

command -v butmux

If butmux is not on PATH, set BUTMUX_BIN to an executable path before starting Codex or Claude Code:

export BUTMUX_BIN=/absolute/path/to/butmux

Codex Plugin

The Codex marketplace file is:

.agents/plugins/marketplace.json

Add the GitHub marketplace and install the plugin with the Codex CLI:

codex plugin marketplace add kdnk/butmux
codex plugin add codex-butmux@butmux

For local plugin development from a cloned checkout, use codex plugin marketplace add . from the repository root instead.

Then start a new Codex session. Use /hooks in Codex to review and trust the plugin hooks if Codex asks for hook review.

The plugin provides:

SessionStart      -> butmux hook codex session-start
UserPromptSubmit  -> butmux hook codex user-prompt-submit
Stop              -> butmux hook codex stop

Claude Code Plugin

The Claude Code marketplace file is:

.claude-plugin/marketplace.json

Add the GitHub marketplace and install the plugin with the Claude Code CLI:

claude plugin marketplace add kdnk/butmux
claude plugin install claude-butmux@butmux

For local plugin development from a cloned checkout, use claude plugin marketplace add . from the repository root instead.

Then run /reload-plugins or start a new Claude Code session. Use /hooks in Claude Code to inspect the installed hook definitions.

The plugin provides:

SessionStart      -> butmux hook claude session-start
UserPromptSubmit  -> butmux hook claude user-prompt-submit
Notification      -> butmux hook claude notification
Stop              -> butmux hook claude stop
StopFailure       -> butmux hook claude stop-failure
PostToolUse       -> butmux hook claude post-tool-use
SessionEnd        -> butmux hook claude session-end

Verify Hook Status

Run Codex or Claude Code inside a tmux pane, then start or resume a session. The plugin hooks intentionally no-op when TMUX_PANE is missing, so sessions outside tmux will not update butmux pane state.

In another pane, open:

butmux

The selected context should show the active Codex or Claude pane after the first hook event fires.

Troubleshooting Hooks

  • Check command -v butmux, or set BUTMUX_BIN.
  • Confirm the agent session is running inside tmux so TMUX_PANE is present.
  • Open /hooks in Codex or Claude Code and confirm the plugin hooks are enabled and trusted.
  • Check whether hooks are disabled by user, project, or managed policy.
  • Confirm the plugin is installed and enabled.

Manual Hook Reference

The plugin setup above is preferred. Manual hook configuration is still possible if you do not want to use plugins.

Codex commands:

butmux hook codex session-start
butmux hook codex user-prompt-submit
butmux hook codex stop

Claude Code commands:

butmux hook claude session-start
butmux hook claude user-prompt-submit
butmux hook claude notification
butmux hook claude stop
butmux hook claude stop-failure
butmux hook claude post-tool-use
butmux hook claude session-end

Manual Notifications

Use butmux notify inside a tmux pane when you need to raise a waiting state manually:

butmux notify "implementation finished"

Build

npm run build

This typechecks the project and builds:

dist/cli.js

Test

npm test

Operational Notes

  • If but status -fv reports Setup required: No GitButler project found, butmux runs but setup and retries.
  • If a project warning says but setup or but teardown is needed, select that project's row and press g to run the suggested GitButler command.
  • If a terminal tab is missing during focus, butmux creates one.
  • If a tmux session is missing during focus, butmux creates one.
  • If a target pane lives in another tmux window, butmux switches to that window before selecting the pane.
  • Orphan cleanup removes both the tmux session and matching terminal tab.

Development Notes

Important files:

Specs and plans: