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

@tejgor/deckhand

v0.1.3

Published

A lightweight agent workbench for your IDE terminal.

Readme

Deckhand

A lightweight agent workbench for your IDE terminal.

Status: early/experimental. Behavior, on-disk state, and the daemon IPC protocol may change between versions.

  • Start claude, pi, or codex sessions from one UI
  • Preview output without attaching to every session
  • Attach/detach while sessions keep running in the background
  • Pick a worktree mode per session: none, new, or existing
  • Designed to work well in IDE integrated terminals

Context

Tools like claude-squad and agent-deck manage parallel agent work with tmux and git worktrees. Deckhand uses a different stack with no tmux dependency: an Ink UI, a local daemon, and node-pty workers.

Features

  • Split view with session sidebar and Preview / Terminal / Git / Dev tabs
  • Live previews of session output without attaching
  • Sessions persist across UI quits and crashes — the daemon owns them
  • Cleanup prompts after a session exits to remove its worktree and branch
  • Merge helpers to merge or squash-merge a session's worktree into the current branch (staged, not committed) for review
  • Optional Git tab powered by lazygit
  • Configurable Dev tab for a command such as npm run dev

Requirements

  • Node.js >= 20
  • macOS or Linux
  • A POSIX shell
  • git available on PATH
  • claude, pi, and/or codex available on PATH, depending on which agents you want to run
  • Optional: lazygit on PATH for the Git tab

Installation

Install from npm:

npm install -g @tejgor/deckhand

Then run:

deckhand

For local development, install from source:

git clone https://github.com/tejgor/deckhand.git
cd deckhand
npm install
npm run build
npm link

After changing source code, rebuild before re-running the linked CLI:

npm run build

The CLI binary is declared in package.json as deckhand → dist/cli.js.

macOS note: npm install runs scripts/fix-node-pty.js, which best-effort repairs the node-pty spawn-helper binary (executable bit, xattr, ad-hoc codesign). See Troubleshooting if install fails.


Quick start

From inside a git repository:

deckhand

Then:

  1. Press n to create a new session
  2. Choose claude, pi, or codex
  3. Enter a session name
  4. Press tab to choose a workspace mode: no worktree, new worktree, or existing worktree
  5. Press enter to launch

Use j / k to move between sessions and o to attach to the selected session.


Controls

Main view

| Key | Action | | --- | --- | | n | New session | | tab | Cycle Preview / Terminal / Git / Dev tabs | | o | Attach to the selected session, opening whichever tab is currently shown | | d | Start/stop the selected session's Dev tab command | | m | Merge selected worktree into the current branch | | j / k | Move between sessions | | h / l | Resize the sidebar | | x / X | Kill selected running session / force kill | | s | Restart selected exited session | | backspace | Drop selected exited session from the list | | r | Refresh session list | | ? | Show keyboard shortcuts | | q | Quit the UI; running sessions continue in the daemon |

Worktree sessions may prompt to keep/delete the worktree, or delete both the managed worktree and branch when it is safe to do so.

Attach mode

| Key | Action | | --- | --- | | (any) | Sent directly to the attached pane/session | | Ctrl+Space | Detach and return to Deckhand |


Workspace modes

When creating a session, Deckhand can launch it in one of three workspace modes:

| Mode | Behavior | | --- | --- | | No worktree | Run in the current repository directory | | New worktree | Create or resolve a worktree for the session | | Existing worktree | Pick from existing git worktrees, including the current/main one |

New worktrees are created through a project hook when present; otherwise Deckhand falls back to git worktree add under ~/.deckhand/worktrees/.


Configuration

Deckhand reads configuration from ~/.deckhand/config.json.

Dev command

The Dev tab is started explicitly with d. Configure the global command like this:

{
  "dev_command": "npm run dev"
}

Set dev_command before pressing d. If omitted, Deckhand tries to runs a dev alias.

Attach scroll sensitivity

Attached sessions dampen trackpad/mouse-wheel scrolling. Configure the multiplier like this:

{
  "attach_scroll_sensitivity": 0.25
}

Use 1 for normal terminal scrolling, lower values for slower scrolling, or 0 to ignore vertical wheel events while attached. Default: 0.25.

State and logs

| Path | Purpose | | --- | --- | | ~/.deckhand/state.json | Persisted session list | | ~/.deckhand/config.json | User configuration | | ~/.deckhand/daemon.log | Supervisor daemon diagnostics | | ~/.deckhand/daemon.pid | Active supervisor daemon PID | | ~/.deckhand/daemon.sock | Local IPC socket | | ~/.deckhand/workers/ | Per-session worker PID/log files | | ~/.deckhand/worktrees/ | Default location for auto-created worktrees |


Worktree hooks

For new-worktree sessions, Deckhand first creates or resolves a git worktree, then starts the agent inside it. Deckhand uses this project hook if present; otherwise it falls back to git worktree add:

.claude/scripts/create-worktree.sh

Hook contract

  • Read JSON from stdin
  • Use name as the sanitized worktree/session name
  • Use cwd as the directory where deckhand was launched
  • Create or register a git worktree
  • Print the absolute worktree path to stdout as the final non-empty line
  • Exit 0 on success

Deckhand also sets CLAUDE_PROJECT_DIR to the launch cwd for compatibility with Claude-style hooks.

Input example

{ "name": "my_feature", "cwd": "/path/to/current/worktree" }
#!/bin/bash
set -e

INPUT="$(cat)"
NAME="$(echo "$INPUT" | jq -r '.name // "worktree"')"
CWD="$(echo "$INPUT" | jq -r '.cwd // env.CLAUDE_PROJECT_DIR // env.PWD')"
DIR="$HOME/.deckhand/worktrees/$NAME"
START="$(git -C "$CWD" rev-parse HEAD)"

if [ -d "$DIR/.git" ] || git -C "$DIR" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
  echo "$DIR"
  exit 0
fi

if [ -e "$DIR" ]; then
  echo "Path exists but is not a git worktree: $DIR" >&2
  exit 1
fi

if git -C "$CWD" show-ref --verify --quiet "refs/heads/$NAME"; then
  git -C "$CWD" worktree add "$DIR" "$NAME" >&2
else
  git -C "$CWD" worktree add -b "$NAME" "$DIR" "$START" >&2
fi

echo "$DIR"

If your hook copies symlinks from the source worktree, prefer resolving them with realpath so newly-created worktrees point directly at the real target instead of through another linked worktree.


Architecture

Deckhand has three main pieces:

  • Ink frontend — renders the terminal UI, sends requests to the daemon, and attaches to live panes when requested.
  • Local daemon — owns session state, IPC, worktree operations, and worker supervision.
  • Session workers — one worker per running session; each worker owns the agent PTY plus optional Terminal / Git / Dev PTYs.

Terminal output is fed into a headless xterm.js model. The UI receives rendered snapshots for previews, while attach mode streams input/output directly between your terminal and the selected PTY.

The UI can quit or crash without taking sessions down; the daemon owns them.

Daemon lifecycle

Deckhand spawns a long-lived supervisor daemon the first time you launch the UI. Quitting the UI with q leaves the daemon (and any running sessions) in place; relaunching deckhand reattaches. Stopping the daemon kills all running sessions.

| Action | How | | --- | --- | | Check whether the daemon is running | pgrep -F ~/.deckhand/daemon.pid | | Tail daemon logs | tail -f ~/.deckhand/daemon.log | | Stop the daemon (and all sessions) | kill $(cat ~/.deckhand/daemon.pid) | | Recover from a crashed daemon | Remove ~/.deckhand/daemon.pid and ~/.deckhand/daemon.sock, then relaunch |


Development

npm install
npm run dev      # run from source via tsx
npm run daemon   # run only the daemon in dev mode
npm run build    # compile to dist/

Useful checks before linking a build:

npm run build
npm pack --dry-run --ignore-scripts

Troubleshooting

deckhand can't find an agent. Confirm the binary you want is on PATH: which claude, which pi, which codex. Deckhand inherits the launching shell's environment.

node-pty fails to load on macOS (e.g. spawn-helper permission errors). Re-run the repair script directly:

node scripts/fix-node-pty.js

If that doesn't help, reinstall: rm -rf node_modules && npm install.

Stale daemon socket / PID. If deckhand hangs at startup or reports it can't reach the daemon, the supervisor may have exited uncleanly. Remove the stale files and relaunch:

rm -f ~/.deckhand/daemon.pid ~/.deckhand/daemon.sock
deckhand

Git tab is empty. Install lazygit and ensure it is on PATH.

Dev tab does nothing. The Dev command is started explicitly with d. If ~/.deckhand/config.json does not set dev_command, Deckhand runs the literal command dev, which usually doesn't exist.


Uninstall

npm unlink -g deckhand

To remove all local state (sessions, logs, auto-created worktrees):

rm -rf ~/.deckhand

If Deckhand created git worktrees under ~/.deckhand/worktrees/, prefer removing them through the UI (or git worktree remove) before deleting the directory, so git's bookkeeping stays consistent.


Contributing

Issues and pull requests are welcome. For larger changes, please open an issue first to discuss the approach. Run npm run build and confirm the CLI launches before sending a PR.


License

Deckhand is released under the MIT License.