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

@mightybs/squad-hub

v0.5.0

Published

One place to see and control your Squad sessions, across every substrate.

Readme


The problem

Squad sessions run in more places than one person can watch. Two things go wrong the moment you step away from a keyboard:

  1. You lose sight of what is running. There is no single view.
  2. Agents stall. A session that pauses for tool approval waits until you return to that machine. On a 45-minute run that is the difference between finishing and not.

Squad Hub fixes both.

What it does

| | | |---|---| | See everything | One live list of every session, grouped by device | | Device presence | Online, stale, or offline, from a heartbeat | | Answer approvals remotely | The card shows the literal command and the paths it touches | | Start a session anywhere | Pick a device, write a prompt | | Steer and stop | Send follow-up input, or cut a run short | | Device tokens | Give a server a credential that can be a device and nothing else | | Squad-aware | Reads .squad/ for team, decisions, and model policy | | On your phone | Installable as a PWA |

What it looks like

Every session, across every device. Anything blocked on a person is pulled to the top and edged in amber — that is the only row that cannot make progress on its own.

An approval, answerable from anywhere. The card shows the literal command and every path it touches, each marked as reading or writing — not a summary, and not a yes/no with no context. This is the difference between a 45-minute run finishing and stalling until you get back to that machine.

Inside a session. The transcript as it happens, the Squad working it, and a box to steer the agent without touching the machine it runs on.

Your Squad, not just your sessions. Click a member to read their charter, or open the team's decisions and routing — read from the device, and rendered as text, never as markup. These files are written by agents as well as by people, so the hub does not turn them into HTML.

Starting work somewhere else. Choose a device, write a prompt. The agent and model lists come from that device — only it knows which agents its Copilot has and which models the agent offers. Leave them blank and the project decides: in a Squad project that means the squad agent, automatically.

Try it

You need: Node 18+, and the GitHub Copilot CLI on your PATH — that is the agent Squad Hub supervises.

There is nothing to build and nothing to install. Squad Hub has no dependencies, so there is no npm install step and no node_modules.

Squad is not bundled with this, and is not pinned to a version. Squad Hub supervises whatever the Copilot CLI on your PATH already has. It detects a Squad project from .squad/ or .github/agents/squad.agent.md on disk, then asks for the squad agent over the ACP protocol against the list that session advertises — so you always get the Squad you have installed, and upgrading Squad needs nothing from Squad Hub. If the agent it asked for is not there, the session runs with the default and says so, rather than quietly substituting.

Getting the squad-hub command

Three ways, easiest first. All of them give you the same command.

1. Run it without installing anything. npx fetches, caches and runs it:

npx squad-hub squad

2. Install it globally, so squad-hub is on your PATH for good:

npm i -g squad-hub
squad-hub squad

3. Clone it, if you intend to change it — see npm link below:

git clone https://github.com/swigerb/squad-hub
cd squad-hub
npm link

The package is also published as @mightybs/squad-hub, which is the same code under the org's namespace — use it if you prefer a scoped dependency. To run the unreleased main instead of the last release, both npm commands take github:swigerb/squad-hub in place of squad-hub.

Then, whichever way you got it

The recommended workflow, once you have a hub — either one already hosted for your team, or one you started yourself with serve below:

squad-hub connect --hub <url> --token <device-token>  # once, per machine

cd my-project
squad-hub squad                                       # every time after that

squad-hub squad starts the daemon if it is not already running, picks the Squad custom agent automatically in a Squad project (see docs/commands.md), and opens an interactive terminal on a new session — or, given a prompt (squad-hub squad "implement issue 42"), starts that session and returns.

What npm link actually does

This applies to the clone route only; npx and npm i -g do not need it.

It creates one global symlinksquad-hub on your PATH — pointing at this checkout. That is it. It does not install anything into the checkout, does not run a build, and does not start anything. Every squad-hub … afterward runs the exact code in this clone, with no node … prefix required. It is a developer-installation step, run once, not something that starts a service — squad-hub connect/squad-hub start do that.

Without npm link, run the same commands as node bin/squad-hub.js … instead of squad-hub ….

Hosted hub vs. running one yourself

Most people never run squad-hub serve. A production or team hub is normally already hosted somewhere (an Azure App Service, a Container App — see "Running it in the cloud" below), and connecting to it is the one-time squad-hub connect --hub <url> --token <device-token> above. Get that command, with a fresh token already filled in, from the hub's own account menu → Connect a device.

Run serve yourself only if you want a local hub — for example, to try Squad Hub before your team deploys one:

node bin/squad-hub.js serve

It prints a URL containing a token — open that, and you are signed in. It also prints the exact connect command for this device. In a second terminal, in the same folder:

node bin/squad-hub.js connect --hub http://localhost:7420 --token <token>

cd /path/to/your/project
node /path/to/squad-hub/bin/squad-hub.js squad "add a health endpoint and a test for it"

When the agent asks to run something, the approval card appears in the browser — on your desktop, or your phone — and in the interactive terminal if you have one open on that session.

Everything works from the CLI too:

squad-hub status          # sessions, and what each is waiting for
squad-hub doctor          # diagnose the whole setup end to end
squad-hub approve <session> <approval> allow_once
squad-hub kill <session>

How it works

The daemon dials out, so nothing has to be opened on your laptop or dev box.

The hub is a cache. The device is the record.

The daemon owns the agent, the session, and any pending approval. The hub holds only a projection of that, so a browser has something to render and command.

You can restart or redeploy the hub while sessions are running. The agent never notices — its connection is to the daemon on the same machine, which never went away. A pending approval reappears in about two seconds, with the same id, and answering it still runs the tool.

A daemon restart is different: it reaps its agents deliberately, because an unsupervised agent holding a repository checkout is worse than no agent. Those sessions are gone, and the hub correctly shows none rather than offering approvals nobody can answer.

The full matrix of what survives what is in docs/architecture.md.

Running it in the cloud

The simplest option is Azure App Service — native Node, no container:

./scripts/deploy-appservice.ps1 -ResourceGroup rg-my-hub -Name my-squad-hub `
  -AuthMode github -Owner your-github-login

-Owner is not optional in practice. A hub can start sessions and approve commands on your machines, so the script refuses to deploy without one (or -AllowedUsers, or an explicit -AllowAnyone) rather than putting an open hub on a public hostname.

The resource group is created if it does not already exist. The deploy uses your active az subscription and prints which one; pass -Subscription to pin it.

The script refuses to deploy a configuration that cannot carry a device, and verifies the build it pushed is the one serving.

Container Apps and Kubernetes are also supported, and can additionally run a cloud device — a daemon in the cloud that appears in the device list beside your laptop:

./scripts/deploy-aca.ps1 -ResourceGroup rg -Environment cae -Registry acr -WithCloudDevice
./scripts/deploy-aks.ps1 -ResourceGroup rg -Cluster aks -Registry acr -HubUrl https://... -HubToken ... -AgentToken ...

Give a cloud device a GitHub token and it runs a real agent:

SQUAD_HUB_URL          the hub service
SQUAD_HUB_TOKEN        identifies the DEVICE to the hub
SQUAD_HUB_AGENT_TOKEN  authorises the AGENT to GitHub

Those last two are deliberately separate. The hub token says which device this is; the agent token spends a Copilot entitlement. Conflating them would let anyone who can register a device also spend someone else's.

A container that already knows what to run — a Container Apps job execution — can run one session and exit, so it does not bill for a process doing nothing:

SQUAD_HUB_ONESHOT=1
SQUAD_HUB_PROMPT="add a health endpoint and a test for it"

That is how Squad Hub supervises Squad on ACA runs, which lets a tool call inside a cloud job be approved from your phone — something an unattended job cannot do.

See docs/cloud.md.

Security

Lock it to yourself. A hub can start sessions and approve commands on your machines, so the deploy script refuses to deploy without an owner:

./scripts/deploy-appservice.ps1 -ResourceGroup rg -Name my-hub `
  -AuthMode github -Owner your-github-login

More than one account? List them all — they share one view:

-Owner [email protected],[email protected]

Partitioning is keyed on tenant + object id, so two accounts of the same person would otherwise be two separate hubs sharing a URL. -Owner says these are all me. Use -AllowedUsers for other people, who each keep their own devices.

A tenant filter is not an owner filter — every user in that tenant would otherwise be permitted. The check is enforced on the device WebSocket as well as the API, since registering a device is what an intruder would actually want.

Give a server a device token, not your own credential. A device token can be a device and nothing else: it cannot read the API, start work on your other devices, or watch your sessions. It expires, it can be revoked, and it can be restricted to device ids with a given prefix — so a token for cloud jobs cannot claim to be your laptop.

squad-hub device-token --hub <url> --token <yours> --label "build server" --ttl-hours 24

File access is off by default. No folder picker, no directory browsing, until you opt in:

squad-hub start --allow-files       # scoped to the launch directory
squad-hub start --allow-files-all   # the whole filesystem

The confinement root is enforced by the daemon and never leaves the device — the service is told only whether file access is on and whether it is scoped.

Per-user isolation is structural, not a filter applied at read time. Every lookup reaches into one subject's partition, so there is no code path that returns another user's data and then remembers to remove it.

See docs/security.md, and check your own deployment with node spike/security-probe.js --host <your-host>.

A constraint worth knowing up front

The Hub has to start the session. There is no supported way to attach an ACP client to a copilot process someone already launched by hand — running copilot, then picking the Squad custom agent with /agent, produces a session with no ACP surface for anything else to attach to. That is why squad-hub squad/squad-hub run launch copilot --acp themselves, from the very first prompt, with the Squad agent selected automatically when the project calls for it (--agent squad) — the daemon owns the process from the start instead of trying to attach to one later.

Keep it running at login (optional)

squad-hub install-service   # Windows Task Scheduler / systemd --user / LaunchAgent
squad-hub uninstall-service
squad-hub service-status

Registers a login task that runs squad-hub start once at sign-in, so the daemon is already up the next time you need it. Never requires admin or root. See docs/commands.md.

Testing

npm test              # the suite
node test/mutate.js   # break each mechanism, require a named test to fail

Two rules the suite follows:

Assert side effects, not replies. An approval test checks for a file the agent could only create by actually running the command. An agent that ran a denied command would report the denial just as convincingly.

A test that cannot fail is decoration. test/mutate.js disables each load-bearing mechanism in turn and requires the test that claims to cover it to fail by name. A mutation nothing catches is a mechanism nothing tests.

More in docs/.

How it is built

Built on public specifications: the Agent Client Protocol and GitHub Copilot CLI's published flags. Every protocol behaviour it depends on is proven by a script in spike/, with the captured wire payloads committed alongside.

No dependencies. Every require is a Node builtin — the WebSocket implementation included. There is no npm install, no node_modules, and no build step for the web app.

License

MIT.