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

@aywengo/mercury-fleet

v0.1.0

Published

Federation layer for independent Mercury hosts: host registry, probing, Run dispatch and routing, reconciliation, event aggregation and a Prometheus rollup

Readme

Fleet

Fleet manages several independent Mercury instances from one place. It is a federation layer: it talks to each Mercury over its public HTTP API and never touches a Mercury database or imports Mercury code.

Design: docs/fleet-design.md. All six build phases are shipped: registry and probe, dispatch, reconciliation, event aggregation, routing, interaction, and the metrics rollup.

Two surfaces, deliberately different:

  • fleet (this CLI) — the host registry, probing, and credential inspection. Local, interactive, no network service of its own.
  • fleet serve (the service) — everything that has to outlive the person who started it: submitting Runs, routing them, reconciling their state, aggregating events, and the Prometheus rollup. See Service below.

Version FLEET_VERSION lives in version.ts and must match package.json. Changelog: CHANGELOG.md. fleet --version prints mercury-fleet <version>. GET /healthz includes product: "fleet" and that same version.

Quick start

# 1. Child credentials live in a 0600 file, referenced by name. Never a command-line argument: argv is
#    world-readable through ps, and Fleet holds a credential for every Mercury it can reach.
mkdir -p ~/.fleet && chmod 700 ~/.fleet
cat > ~/.fleet/credentials.json <<'JSON'
{ "mac-studio": "<token from that host's MERCURY_API_TOKENS>" }
JSON
chmod 600 ~/.fleet/credentials.json

# 2. Register hosts and look at them.
npm run fleet -- hosts add mac-studio --url https://studio.lan:3000 --credential mac-studio
npm run fleet -- hosts list --live
ID         STATE      SEEN  WORKERS  RUNS  QUEUE  AGENTS  URL
mac-studio up         0s    1        2     0      5       https://studio.lan:3000
box-lan-2  auth-fail  0s    0        0     3      -       http://box2.lan:3000
    box-lan-2: HTTP 401 from /api/agents: the host is reachable but this credential was rejected.
box-lan-3  down       4m    -        -     -      -       http://box3.lan:3000

Commands

| Command | Does | | --- | --- | | fleet hosts add <id> --url <base> --credential <ref> [--label k=v] [--path <abs>] [--disabled] | Register a host. --credential names a ref; the secret is never an argument. | | fleet hosts list [--json] [--live] | Show hosts with their last probe. --live probes first. | | fleet hosts probe [<id>] [--json] | Probe now. Exits non-zero if the host is unusable, so it composes in a readiness check. | | fleet hosts enable\|disable <id> | Include or exclude a host from sweeps. | | fleet hosts rm <id> | Forget a host and its cached probe. | | fleet probe --watch | Sweep every enabled host on FLEET_PROBE_INTERVAL_MS until interrupted. | | fleet credentials list | Credential names only. Values are never printed by any command. |

What each state means

The states are deliberately not collapsed into up/down. Each one sends the operator somewhere different, and a probe that reports "down" for a host that is healthy but rejecting our token wastes the operator's time on the wrong machine.

| State | Means | Fix | | --- | --- | --- | | up | Reachable, queue configured, credential accepted. | — | | auth-fail | Host is fine. Our credential is not. | Check the ref in the credential file. | | no-worker | API answers, but its queue is not configured, so it executes nothing. | Start that host's worker. | | down | Nothing listening. | Host, port, or MERCURY_BIND_HOST. | | timeout | Something answered too slowly to trust. | Load, or a half-dead process. | | not-mercury | A server is there; it is not a Mercury API. | Wrong port or URL. | | http-error | Unexpected status from a Mercury endpoint. | Check that host's logs. | | never-probed | Registered, not swept yet. | fleet hosts probe. |

Configuration

| Variable | Default | Meaning | | --- | --- | --- | | FLEET_DB | fleet.db | Fleet's own SQLite database, separate from every Mercury's. | | FLEET_CREDENTIALS_FILE | ~/.fleet/credentials.json | Must be mode 0600; Fleet refuses otherwise. | | FLEET_PROBE_INTERVAL_MS | 15000 | Sweep interval for probe --watch. | | FLEET_PROBE_TIMEOUT_MS | 5000 | Per-request timeout. A hung host must not stall the sweep. | | FLEET_ALLOW_INSECURE_CREDENTIALS | unset | 1 bypasses the mode check. For filesystems that cannot do 0600. |

The default is laptop-shaped on purpose, for development. Fleet runs as a service (docs/fleet-design.md §15), and a hardened unit sets ProtectHome=true, which cannot read anything under a home directory. A service deployment sets FLEET_CREDENTIALS_FILE=/etc/fleet/credentials.json explicitly instead of relying on this default.

Service

fleet serve runs the HTTP API. It binds 127.0.0.1:3100 by default.

| Variable | Default | Meaning | | --- | --- | --- | | FLEET_BIND_HOST | 127.0.0.1 | Bind address. | | FLEET_PORT | 3100 | Listen port. | | FLEET_API_TOKENS | unset | token:owner[:hosts], comma-separated. hosts scopes a caller to a subset. | | FLEET_ADMIN_TOKEN | unset | A caller that may see and change every host. | | FLEET_TLS_CERT / FLEET_TLS_KEY | unset | Both or neither. Required to bind beyond loopback. | | FLEET_SWEEP_INTERVAL_MS | 10000 | How often bindings are reconciled against every host. | | FLEET_STREAM_POLL_MS | 1000 | Poll interval behind the aggregated Run stream. | | FLEET_REPO_URLS_FILE | unset | localPath → git URL map used by the router. |

It refuses to start in an unsafe configuration, rather than serving and leaving discovery to an audit: binding beyond loopback without TLS, half a TLS pair, or no caller tokens at all each fail at startup with the reason. A Fleet token reaches every Mercury in the fleet, so plaintext on a shared network is not a deployment someone should arrive at by omission.

| Endpoint | Does | | --- | --- | | GET /healthz | Liveness, with product: "fleet" and the version. Unauthenticated. | | GET /metrics | Prometheus rollup across hosts, every series relabelled host="<hostId>". | | GET\|POST /fleet/hosts | List and register hosts. | | POST /fleet/hosts/:id/enable, .../disable, DELETE /fleet/hosts/:id | Include or exclude a host from sweeps. | | POST /fleet/hosts/:id/probe | Probe one host now. | | POST /fleet/runs | Submit a Run. Name a host, or omit it and let the router choose. | | GET /fleet/runs | Every Run across the fleet, one merged view. | | GET /fleet/runs/:id | One Run, with its binding and current child state. | | GET /fleet/runs/:id/events, .../stream | Aggregated history and SSE for a fleet Run. | | POST /fleet/runs/:id/input, .../cancel, .../retry | Answer, cancel, or retry through Fleet. | | POST /fleet/probe | Sweep every enabled host. |

Changing the registry — adding, removing, enabling or disabling a host, and sweeping — requires the admin token. Reads and Run submission do not, but are scoped: a caller limited to a subset of hosts cannot route work onto a hidden host, read another host's Run, or learn another host's queue depth from /metrics. Routing failures name every host considered and why each was excluded, because "no host matched" without reasons is an hour of guessing.

Two rules this directory is built around

Nothing here imports from src/. Fleet speaks HTTP so that it can drive a Mercury it did not build. fleet/test/coupling.test.ts enforces this, and includes tests proving the guard can actually fire.

hosts is truth; everything else is cache. Probe results live in their own table, so deleting them costs one sweep. That split is what makes a Fleet crash cheap: the registry survives, and nothing Fleet holds can orphan a Run on a machine nobody is watching.

Development

npm run test:fleet    # 187 tests, no network beyond localhost
npm run typecheck     # covers fleet/ as well as src/