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

@mclawnet/swarm

v0.1.18

Published

Swarm coordination, message routing, and role management. Phase 2 adds an **Inbox layer** (`InboxStore` + `InboxRelay`) on top of the existing `SwarmCoordinator`, giving the host a push-based path for delivering messages to agent sessions.

Readme

@mclawnet/swarm

Swarm coordination, message routing, and role management. Phase 2 adds an Inbox layer (InboxStore + InboxRelay) on top of the existing SwarmCoordinator, giving the host a push-based path for delivering messages to agent sessions.

BREAKING CHANGE — persistence path migrated

Swarm state has moved under the per-project directory shared with @mclawnet/task:

OLD:  ~/.clawnet/swarms/<swarmId>/...
NEW:  ~/.clawnet/projects/<encoded-cwd>/swarms/<swarmId>/...

There is no backward-compatibility shim. Snapshots, message logs, and inbox files written by 0.1.4 and earlier will not be picked up by 0.1.5+. Any in-flight swarms should be drained before upgrading.

<encoded-cwd> is computed by encodeCwd() from @mclawnet/task (absolute path with / replaced by -).

Modules

Coordinator (existing)

SwarmCoordinator, action parsing, role/template loading, persistence, and recovery — see exports in src/index.ts. Inter-role messaging is delivered via InboxStore + InboxRelay (see below).

Inbox (new)

interface InboxMessage {
  id: string;
  from: string;
  type: string;
  data: string;
  taskId?: string;
  timestamp: number;
  delivered: boolean;
  deliveredAt?: number;
}

class InboxStore {
  constructor(workDir: string, swarmId: string);
  append(instanceId: string, msg: InboxMessage): Promise<void>;
  readAll(instanceId: string): Promise<InboxMessage[]>;
  readUndelivered(instanceId: string): Promise<InboxMessage[]>;
  markDelivered(instanceId: string, ids: string[]): Promise<void>;
}

class InboxRelay {
  constructor(
    sessionAdapter: SessionAdapter,
    getSwarm: (swarmId: string) => SwarmInstance | undefined,
  );
  deliver(swarmId: string, instanceId: string): Promise<void>;
  onAgentTurnSettled(swarmId: string, instanceId: string): Promise<void>;
}

InboxStore writes one JSON file per recipient under ~/.clawnet/projects/<encoded-cwd>/swarms/<swarmId>/inboxes/<instanceId>.json, guarded by proper-lockfile for concurrent appenders.

InboxRelay is the push side. It wraps undelivered messages in a single <info_for_agent> envelope and feeds them to the session through SessionAdapter.sendInput. Four gates guard the push:

  1. single-flight — at most one in-flight deliver() per (swarmId, instanceId).
  2. liveness — swarm and role must exist with a workDir.
  3. lifecycle — agents in spawning or stopped are skipped.
  4. pending-echo — messages already pushed but not yet ack'd by a turn completion are not re-pushed.

onAgentTurnSettled() is called when the host sees a result event for a turn; it marks pending messages delivered=true and triggers another deliver pass to flush messages that arrived mid-turn.

Wiring points

The host connects the relay to the coordinator at three places:

  • spawn — after SwarmCoordinator creates a role and the session is ready, call relay.deliver(swarmId, instanceId) to flush any inbox messages buffered before the agent existed.
  • resume — on snapshot recovery, call deliver() for each restored role so agents receive what queued up while offline.
  • turn-complete — on the session adapter's turn-settled signal, call relay.onAgentTurnSettled(swarmId, instanceId).

Producers append to the inbox via InboxStore.append() (e.g. router fan-out, task notifications); the relay handles delivery semantics.

Example

import { InboxStore, InboxRelay } from "@mclawnet/swarm";

const store = new InboxStore(process.cwd(), swarmId);
await store.append("worker-1", {
  id: crypto.randomUUID(),
  from: "host",
  type: "task-assigned",
  data: "please pick up TASK-42",
  taskId: "TASK-42",
  timestamp: Date.now(),
  delivered: false,
});

const relay = new InboxRelay(sessionAdapter, (id) => coordinator.get(id));
await relay.deliver(swarmId, "worker-1");
// later, when the agent's turn completes:
await relay.onAgentTurnSettled(swarmId, "worker-1");