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

@richardgill/pi-tmux-bash

v0.0.12

Published

Drop-in `bash` replacement that runs commands in the background using tmux.

Readme

pi-tmux-bash

Drop-in bash replacement that runs commands in the background using tmux.

Demo

tmux-bash demo

Watch demo video

How it works

  • All bash calls happen inside tmux
  • Foreground bash timeouts keep running in background (or kill)
  • Background bash sends a follow-up result when the command finishes.
  • Model can enable polling to receive periodic updates on background output.
  • Model can tmux:peek to see latest background output.
  • Model can tmux:kill to kill managed tmux windows.
  • Output matches pi's built-in bash tool (enforced with e2e tests which check against vanilla pi)

Install

pi install npm:@richardgill/pi-tmux-bash

Then:

pi 'Run: for i in $(seq 1 90); do echo "$i"; sleep 1; done. Poll every 10s.'

Or try it out without installing:

pi -e npm:@richardgill/pi-tmux-bash 'Run: for i in $(seq 1 90); do echo "$i"; sleep 1; done. Poll every 10s.'

See Configuration for defaults and overrides.

bash tool

Runs all bash commands in a tmux window. If a foreground bash command hits a timeout, either leave it running in the background or kill it.

{
  "command": "pnpm test",
  "name": "test",
  "timeout": 30,
  "timeoutAction": "background" // or "kill"
}

Run a bash command in the background and return immediately, with optional polling for periodic output check-ins.

{
  "command": "pnpm dev",
  "name": "dev-server",
  "background": true,
  "pollInterval": 10,
  "pollLines": 40
}

tmux tool

The tmux tool allows the model to inspect running bash processes.

List background bash tmux windows.

{ "action": "list" }

List tmux windows with polling enabled.

{ "action": "list-polls" }

Capture output from one window.

{ "action": "peek", "window": "@123" }

Kill one window by stable tmux #{window_id}.

{ "action": "kill", "window": "@123" }

Start periodic output check-ins for a window.

{ "action": "poll", "window": "@123", "pollInterval": 10, "pollLines": 40 }

Stop periodic output check-ins for a window.

{ "action": "unpoll", "window": "@123" }

You can limit available tmux actions and bash-started polling:

{
  "tmuxEnabledActions": ["peek", "kill"],
  "bashPollIntervalEnabled": false
}

Configuration

You can override individual settings in tmux-bash.jsonc.

The default location is ~/.pi/agent/tmux-bash.jsonc, or $PI_EXTENSION_CONFIG_DIR/tmux-bash.jsonc when set.

Default config settings:

{
  // ─────────────────────────────────────────────────────────────
  // Bash tool settings
  // ─────────────────────────────────────────────────────────────

  // Default seconds to wait in foreground bash tool before applying timeoutAction (background or kill).
  "defaultTimeoutSeconds": 30,

  // Default action when a foreground bash command hits timeout.
  "defaultTimeoutAction": "background", // "background" (default) | "kill"

  // Maximum allowed bash-in-tmux timeout; higher values are capped here.
  "maxTimeoutSeconds": 60,

  // Milliseconds between streaming foreground bash output updates.
  "foregroundBashUpdateIntervalMs": 250,

  // ─────────────────────────────────────────────────────────────
  // System prompt customization
  // ─────────────────────────────────────────────────────────────

  // Bash tool name exposed to the agent. Change if another extension registers "bash".
  "bashToolName": "bash",

  // Tmux inspection/control tool name exposed to the agent.
  "tmuxToolName": "tmux",

  // Tmux actions exposed to the agent. Set [] to disable registering the tmux tool.
  "tmuxEnabledActions": ["list", "peek", "kill"],

  // Whether bash exposes pollInterval/pollLines and can start polling from a bash call.
  "bashPollIntervalEnabled": false,

  // Template variables:
  // `{{bashToolName}}`: configured with `bashToolName`, default `bash`
  // `{{tmuxToolName}}`: configured with `tmuxToolName`, default `tmux`
  // `{{attachCommand}}`:
  //   Uses `tmux switch-client -t @123` when Pi is already inside tmux. Otherwise `tmux attach -t @123`.
  //   Uses configured `tmuxBinary`.
  // `{{defaultTimeoutSeconds}}` / `{{defaultTimeoutAction}}` / `{{maxTimeoutSeconds}}`
  // `{{bashContextLines}}` / `{{maxOutputKb}}`

  // Bash tool description sent to the model tool schema.
  // Supports the same template variables as systemPromptGuidelines below.
  "bashToolDescription": "Execute a bash command in a background tmux window. Output is truncated to last {{bashContextLines}} lines or {{maxOutputKb}}KB. Defaults to a {{defaultTimeoutSeconds}}s timeout, max {{maxTimeoutSeconds}}s; timeoutAction defaults to \"{{defaultTimeoutAction}}\". Use background for long-running commands.",

  // Tmux tool description sent to the model tool schema.
  // Supports the same template variables as systemPromptGuidelines below.
  "tmuxToolDescription": "Inspect and control background tmux windows created by bash.",

  // modify Pi's built-in system prompt.
  "systemPrompt": true,

  // Tool snippets for Pi's generated system prompt tools section.
  "bashSystemPromptSnippet": "Execute bash commands in background tmux windows", // string | false (to disable)
  "tmuxSystemPromptSnippet": "Inspect and control the background tmux sessions created by bash tool", // string | false (to disable)

  // Guideline bullets appended to Pi's generated system prompt:
  //   Omit systemPromptGuidelines to use defaults.
  //   [] to disable tmux-bash guidelines.
  "systemPromptGuidelines": [
    "Use {{bashToolName}} with background: true or timeoutAction: \"background\" for long-running commands, servers, watchers, REPLs, interactive prompts, and background bash commands.",
    "Background bash commands will report automatically when they finish; do not keep polling manually unless you need interim output.",
    "Use {{tmuxToolName}} list to find background windows",
    "Use {{tmuxToolName}} peek/kill with a stable #{window_id} like @123.",
    "If asked, you can attach to tmux window using: {{attachCommand}}, where @123 is a #{window_id}."
  ],

  // ─────────────────────────────────────────────────────────────
  // Tmux settings
  // ─────────────────────────────────────────────────────────────

  // Use a global tmux session, or a per-git-root tmux session.
  "tmuxSessionScope": "global", // "global" (default) | "git-root"

  // Background tmux session name when tmuxSessionScope is "global".
  "globalTmuxSessionName": "pi-background",

  // Template for the background tmux session name when tmuxSessionScope is "git-root".
  // "{{gitRootSessionName}}" is replaced with the normal git-root session name.
  "gitRootTmuxSessionNameTemplate": "{{gitRootSessionName}}-bg",

  // Which windows inside the selected tmux session list/peek/kill/poll commands can access.
  "tmuxWindowScope": "pi-session", // "pi-session" (default) | "git-root" | "all"

  // Template for created tmux window names.
  // Supports {{nameOrCommand}}, {{name}}, and {{command}}.
  "tmuxWindowNameTemplate": "{{nameOrCommand}}",

  // Maximum tmux window name length.
  "maxTmuxWindowNameLength": 30,

  // Kill tmux windows after bash command completes.
  "autoCloseWindowsOnCompletion": true, // true (default) | false

  // tmux binary/path used for all tmux invocations.
  "tmuxBinary": "tmux",

  // ─────────────────────────────────────────────────────────────
  // Polling and output limits
  // ─────────────────────────────────────────────────────────────

  // Default seconds between automatic poll check-ins. 0 disables default polling.
  // Ignored by bash calls when bashPollIntervalEnabled is false.
  "defaultPollInterval": 0,

  // Whether poll cards trigger model turns or display only in the TUI.
  "pollDelivery": "model", // "model" (default) | "display"

  // Minimum seconds between model-delivered poll turns. Does not throttle display-only polls.
  "minimumPollIntervalSeconds": 10,

  // Maximum output bytes kept for model context and TUI cards.
  "maxOutputBytes": 51200,

  // Foreground bash output lines sent to model context.
  "bashContextLines": 2000,

  // Completed background command lines sent to model context.
  "completedContextLines": 20,

  // Poll output lines sent to model context.
  "pollContextLines": 30,

  // Peek output lines sent to model context.
  "peekContextLines": 2000,

  // Foreground bash output lines shown in compact TUI cards.
  "bashCompactDisplayLines": 5,

  // Foreground bash output lines shown in compact TUI cards when output is truncated.
  "bashTruncatedCompactDisplayLines": 2,

  // Foreground bash output lines shown in expanded/uncompacted TUI cards.
  "bashExpandedDisplayLines": 2000,

  // Completed background command lines shown in compact TUI cards.
  "completedCompactDisplayLines": 5,

  // Completed background command lines shown in compact TUI cards when output is truncated.
  "completedTruncatedCompactDisplayLines": 2,

  // Completed background command lines shown in expanded/uncompacted TUI cards.
  "completedExpandedDisplayLines": 20,

  // Poll output lines shown in compact TUI cards.
  "pollCompactDisplayLines": 5,

  // Poll output lines shown in compact TUI cards when output is truncated.
  "pollTruncatedCompactDisplayLines": 2,

  // Poll output lines shown in expanded/uncompacted TUI cards.
  "pollExpandedDisplayLines": 30,

  // Peek output lines shown in compact TUI cards.
  "peekCompactDisplayLines": 5,

  // Peek output lines shown in compact TUI cards when output is truncated.
  "peekTruncatedCompactDisplayLines": 2,

  // Peek output lines shown in expanded/uncompacted TUI cards.
  "peekExpandedDisplayLines": 2000,

  // ─────────────────────────────────────────────────────────────
  // Advanced settings
  // ─────────────────────────────────────────────────────────────

  // Hides wrapper/shim lines from the displayed command by showing only lines after the last marker.
  // Set to "" to disable.
  "displayCommandStartMarker": "# SHIM_END", // use "" to disable

  // Show the .out file path even when output is not truncated.
  "alwaysShowOutputFilePath": false, // true | false (default)

  // Keep .out files on pi shutdown instead of deleting the signal/output dir.
  "preserveOutputFiles": true, // true (default) | false

  // Base directory for per-session signal files, generated scripts, and .out files.
  "outputDir": "/tmp/pi-tmux-bash",

  // Environment names not exported from Pi into bash-in-tmux scripts.
  // Skips shell/tmux bookkeeping that should be owned by the new tmux window.
  "tmuxEnvExportDenylist": ["PWD", "OLDPWD", "SHLVL", "_", "TMUX", "TMUX_PANE"]
}

API helpers

Other extensions can import tmux-bash helpers to target the same background tmux sessions and scoped windows.

loadTmuxBashConfig

Reads tmux-bash.jsonc from the extension config folder (PI_EXTENSION_CONFIG_DIR, then Pi's agent directory).

import { loadTmuxBashConfig } from "@richardgill/pi-tmux-bash/core";

const options = loadTmuxBashConfig();

resolveTmuxBashContext

Resolves the current git root, configured tmux session, and scoped window filters.

import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
import { loadTmuxBashConfig, resolveTmuxBashContext } from "@richardgill/pi-tmux-bash/core";

const options = loadTmuxBashConfig();
const context = resolveTmuxBashContext(ctx, options);
if (!context) ctx.ui.notify("Not in a git repository.", "error");

listBashWindows

Lists bash-created tmux windows matching the resolved scope.

import { listBashWindows, resolveTmuxBashContext } from "@richardgill/pi-tmux-bash/core";

const options = loadTmuxBashConfig();
const context = resolveTmuxBashContext(ctx, options);
const windows = context ? listBashWindows(context) : [];
// [{ id: "@2172", index: 3, title: "hello-sleep-done", outputFile: "/tmp/..." }]

Read the active background count from footer status

Tmux-bash publishes the active background count with Pi's status API. Footer extensions can read it from footerData.getExtensionStatuses() and handle their own string formatting.

const backgroundBashStatusKey = "backgroundBashTmuxCommands";

const formatBackgroundBashStatus = (value: string) =>
  `${value} background proc${value === "1" ? "" : "s"}`;

ctx.ui.setFooter((_tui, theme, footerData) => ({
  invalidate() {},
  render(width: number): string[] {
    const status = footerData.getExtensionStatuses().get(backgroundBashStatusKey);
    const backgroundBashStatus = status ? formatBackgroundBashStatus(status) : "";

    return [theme.fg("dim", backgroundBashStatus)];
  },
}));

The status key is backgroundBashTmuxCommands. Status values are strings; tmux-bash clears the status when there are no active background windows.

Credits

This extension was inspired by indigoviolet/pi-tmux.