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

@swarmai/acp

v0.1.1

Published

Agent Communication Protocol server — JSON-RPC surface for editor extensions (VS Code / Zed / JetBrains / Cursor) to drive SwarmAI from inside the editor

Downloads

34

Readme

@swarmai/acp

Agent Communication Protocol server for SwarmAI — the JSON-RPC surface that editor extensions (VS Code, Zed, JetBrains, Cursor) connect to so the agent can read open buffers, propose edits, fetch diagnostics, and drive the integrated terminal.

This plugin ships the server side only. Editor extensions live in their own repos and are not part of this package as of v0.1.0.

What this is

ACP is the wire protocol that lets an editor act as an agent surface equal to the gateway dashboard. Once an editor is paired:

  • The editor pushes workspace/didOpen and workspace/fileChanged notifications to the gateway.
  • The gateway pulls buffer/get, diagnostics/get, selection/get from the editor.
  • The gateway proposes edits via buffer/proposeEdit; the editor shows the diff inline and the user accepts/rejects.
  • The gateway can drive the integrated terminal (terminal/run) and invoke editor commands (command/run).

See docs/15-device-and-developer-integration.md §2 in the monorepo for the full design.

Install

  1. Drop swarmai-acp/ under your $SWARMAI_PLUGINS_DIR root (default F:\Published\Pluggins\ on Windows when the operator has set it).
  2. Add '@swarmai/acp' to your plugins.yaml so the loader imports it at boot.
  3. Restart the gateway. You should see [@swarmai/acp] ACP plugin loaded — host must explicitly wire AcpServer via the library exports. in the boot log.

Status: v0.1.0 server only

Editor extensions are not published yet. Until they ship, @swarmai/acp is useful for:

  • Hand-rolled clients that speak the JSON-RPC verbs directly (e.g. a Neovim integration).
  • Custom IDE plugins built against the typed schemas.
  • Sidecar editor processes that the gateway spawns and talks to over stdio (see StdioTransport).

The register() entry is a no-op log line because the host integration shape for "long-lived JSON-RPC server with WS upgrade" hasn't stabilised across SDK versions. Host code wires the server explicitly via the library exports:

Wire-up sketch

import { AcpServer, AcpPairingRegistry } from '@swarmai/acp/lib.js';
import type { AcpSession } from '@swarmai/acp/lib.js';

const pairing = new AcpPairingRegistry();

const acp = new AcpServer({
  pairing,
  onVerb: async (session: AcpSession, verb: string, params: unknown) => {
    // Route inbound editor verbs into the agent session.
    // E.g. workspace/didOpen → record the workspace; workspace/fileChanged → invalidate caches.
    return await routeIntoSession(session, verb, params);
  },
});

// In the gateway's HTTP upgrade handler:
httpServer.on('upgrade', (req, socket, head) => {
  if (req.url === '/ws/acp') {
    const pairToken = extractBearer(req);
    wss.handleUpgrade(req, socket, head, (ws) => {
      const transport = wrapWebSocketAsTransport(ws);
      acp.attach(transport, { pairToken });
    });
  }
});

// Mint a pair code from a CLI subcommand or the dashboard:
const { code, expiresAt } = pairing.mint({
  workspaceId: ctx.workspaceId,
  editor: 'vscode',
  createdBy: ctx.userId,
});
console.log(`Editor pair code: ${code} (valid for 5 min)`);

JSON-RPC verbs

Wire-protocol shape is JSON-RPC 2.0. Verbs split by direction:

| Direction | Verb | Purpose | |---|---|---| | Editor → Gateway | workspace/didOpen | Editor signals a workspace just opened | | Editor → Gateway | workspace/fileChanged | A file was saved or modified | | Gateway → Editor | buffer/get | Read the current buffer content of a URI | | Gateway → Editor | buffer/proposeEdit | Propose a diff; editor shows it inline for accept/reject | | Gateway → Editor | diagnostics/get | Fetch lint / type errors | | Gateway → Editor | selection/get | Read the current selection | | Gateway → Editor | command/run | Invoke an editor command (run tests, format, …) | | Gateway → Editor | terminal/run | Run a command in the integrated terminal |

Each verb's params and result are Zod schemas exported from '@swarmai/acp/lib.js'WorkspaceDidOpenParams, BufferGetParams, BufferGetResult, etc.

Pairing flow

  • 6-character alphanumeric codes drawn from an unambiguous alphabet (excludes O, 0, I, 1, L).
  • 5-minute TTL, single-use.
  • Constant-time compare on redeem to defeat timing attacks.
  • Per-mint metadata: workspace id, editor kind, who created the code.
const { code } = pairing.mint({ workspaceId: 'main', editor: 'vscode', createdBy: 'op-1' });
// Operator enters `code` in their editor extension.
const result = pairing.redeem(code);
if (result) {
  const { workspaceId, editor } = result;
  // Proceed to attach the transport.
}

Writing a hand-rolled client

If you want to write a custom client (e.g. for Neovim or a hand-rolled VS Code extension), import the JSON-RPC primitives:

import {
  parseFrame, encodeFrame, createRequest, createIdGenerator,
  WorkspaceDidOpenParams,
} from '@swarmai/acp/lib.js';

const nextId = createIdGenerator();
const frame = encodeFrame(
  createRequest(nextId(), 'workspace/didOpen', WorkspaceDidOpenParams.parse({
    workspaceId: 'main',
    rootUri: 'file:///path/to/project',
    editor: { kind: 'vscode', version: '1.85.0' },
  })),
);
ws.send(frame);

parseFrame validates inbound JSON against the JSON-RPC 2.0 envelope; the verb schemas validate the params.

Transports

StdioTransport (newline-delimited JSON over stdio) is provided for sidecar editor processes. WebSocket is the recommended transport for browser-hosted editors — the gateway wraps the WS in a Transport adapter during the upgrade handshake (see the wire-up sketch above).

createMemoryTransportPair() is exported for tests — gives you both ends of an in-memory transport pair.

Security

  • Pairing codes are single-use and expire in 5 minutes — replay-safe.
  • No persistent secrets — pair codes are mint-and-burn.
  • The plugin itself does NOT bind a port — the host controls where the JSON-RPC server lives (typically /ws/acp on the gateway's existing HTTP server). All of the gateway's existing TLS / reverse-proxy / origin-gate posture applies.
  • buffer/proposeEdit is never auto-applied — the editor shows the diff inline and the user accepts or rejects. This is enforced editor-side; the protocol just describes the proposal.

License

PolyForm-Noncommercial-1.0.0 — see LICENSE.