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

@azad-ai/workbenchd

v0.1.12

Published

Multi-root workbench daemon: filesystem, search, git, terminal, and LSP over one multiplexed JSON-RPC WebSocket.

Downloads

1,513

Readme

@azad-ai/workbenchd

A multi-root workbench daemon. One process serves N workspace roots to N clients over a single multiplexed JSON-RPC 2.0 WebSocket: filesystem, ripgrep search, git, terminals, and LSP.

It is a standalone daemon with no knowledge of any particular agent runtime or UI. A supervisor starts it, hands it a port and a token, and points clients at it.

bun add -g @azad-ai/workbenchd
workbenchd serve --port 8790 --token "$(openssl rand -base64 24)" --allowed-root /workspace

Bun is required. The pty is built on Bun.spawn({ terminal }), which has no Node equivalent that avoids a native module. Everything else deliberately uses node:child_process, but terminals will not work under Node.

bash is required for command tracking. Shell integration is injected with bash's --init-file; a POSIX sh (busybox ash, dash) rejects that flag, so those shells run plainly and emit no OSC 633 markers — exit codes, cwd tracking, and busy detection stay inert. The daemon warns when it lands in that state. Linux, macOS, and both glibc and musl are verified; Windows is not supported.

Why one socket

Roots are attached explicitly — roots.attach {path} returns an opaque rootId — and every method carries that id. The connection is never bound to a root, so switching workspaces is a parameter change rather than a reconnect, and a second client attaching to the same root shares its watcher, shells, git cache, and language servers immediately.

Terminal output and file bytes travel as binary frames with a 24-byte aligned header on the same socket, so pty traffic never pays for UTF-8 re-encoding or JSON escaping.

Surface

| Namespace | Methods | |---|---| | workbench | hello, unsubscribe | | roots | attach, list, detach, describe | | fs | stat, read, write, mkdir, remove, rename, list, watch | | search | paths, text | | git | snapshot, log, commit, stageFiles, fetch, push, blame/diff/timeline, … | | term | create, list, close, rename, sendInput, resize, attach, watchAll | | lsp | attach, send, detach, status, getPreferences, setDocumentLanguageEnabled |

workbench.hello is mandatory before anything else and negotiates the protocol version. The full machine-readable contract is emitted by workbenchd emit-openrpc --out openrpc.json.

Requests are cancellable with $/cancelRequest, which really does kill the underlying git or rg subprocess rather than merely abandoning the promise.

Terminals

Shells run with VS Code's shell-integration scripts injected, so OSC 633 markers drive cwd, lastCommand, lastCommandExitCode, and a live isRunningProcess flag. Output is retained in a ring buffer with absolute byte offsets, so a reconnecting client resumes exactly where it left off — or gets a rendered screen snapshot when it has fallen too far behind.

Language servers

None are bundled. Servers resolve from the workspace's own node_modules/.bin first, then PATH; WORKBENCHD_LSP_CMD_<LANG> overrides a specific one. Presets exist for typescript, eslint, json, python, rust, and go. Anything not installed is reported as unsupported by lsp.status and is never fatal.

Two transports reach the same session: the hub tunnel (lsp.attach / lsp.send) and a raw /lsp WebSocket, because monaco-languageclient insists on dialling its own socket. N clients multiplex onto one server process via request-id rewriting and document-ownership refcounting.

Options

workbenchd [serve] [options]        Start the workbench server
workbenchd emit-openrpc --out FILE  Write the OpenRPC contract document

  --host HOST            Bind address (default 127.0.0.1)
  --port PORT            Port; 0 picks a free one (default 0)
  --token TOKEN          Require this token in workbench.hello
  --no-auth              Serve without a token (required to start unauthenticated)
  --allowed-root PATH    Confine roots.attach (comma-separated)
  --allow-all-roots      Serve any path the daemon's user can read; the right choice
                         when the daemon already runs inside the sandbox it would be
                         confined to
  --trusted-origin ORIG  Browser Origins allowed to connect (comma-separated); required
                         when clients reach the daemon through a tunnel
  --dev                  Loopback dev mode: generate a token, default roots to cwd,
                         relax the Origin check, and write .azad/workbenchd.json
  --idle-eviction-ms MS  Idle grace before a root's engines are torn down

The daemon exits 1 rather than starting unauthenticated. Pass --no-auth to do that on purpose.

Running as a service

See packaging/ for systemd units, the environment contract, and the auto-update timer.