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

@auggy/link

v0.1.2

Published

Link — the v1 entry point to the Mesh. Peer-to-peer agent ↔ agent over A2A v0.2 (JSON-RPC), mutual bearer auth, durable task store, no central service. See ADR-022.

Downloads

536

Readme

@auggy/link

Peer-to-peer agent ↔ agent over A2A v0.2. Reference implementation in TypeScript on Bun. Receiver-side Hono app + outbound PeerClient + durable SQLite store + bearer auth + streaming + recovery contracts. Library, not service — consumers wire their own Bun.serve and supply a MessageHandler.

Mesh is the destination. Link is how aug1s (and any A2A-speaking runtime) join the mesh today. See ADR-022 for the destination-vs-entry framing and the implementation plan for the v0.1 anchor use cases. (PLAN.md is not shipped in the npm tarball — implementation history lives in the source repo.)


Status: v0.1.0

What's locked at v0.1:

  • A2A v0.2 protocol — JSON-RPC envelope, types, schemas, agent-card discovery
  • message/send, message/stream, tasks/get, tasks/cancel
  • Receiver-side Hono app via createLinkApp
  • BearerAuthProvider with rotation overlap windows
  • SqliteTaskStore (durable, WAL mode) + MemoryTaskStore (test only)
  • PeerClient outbound — retry, exponential backoff, Message-vs-Task return shape discrimination, tasks/get-based stream reattach
  • EnvAddressBook — peer config from env vars
  • Per-peer + global anonymous rate limiting
  • TLS termination + proxy header trust gating (TlsTrustConfig)
  • Idempotency-Key dedup with TTL eviction; restart-survival of replays
  • Stall sweep for in-flight tasks
  • SIGTERM drain — installSigtermHandler is the canonical wire-up
  • Railway deployment template (in the source repo: infra/Dockerfile, infra/deploy.md — the npm tarball is library-only)

What's deferred to v0.2+:

  • tasks/resubscribe (SSE re-attach without re-issuing the task)
  • Push notifications method group
  • File / image / non-text Part kinds (text-only at v0.1)
  • Multi-replica deployment with shared Postgres (single-instance per service at v0.1; PLAN §6.4 forbids multi-instance shared-DB)
  • Hot-reloadable address book (snapshot at construction at v0.1)
  • Auto-rotation of bearers (manual rotation runbook at v0.1)
  • Channels, federation, cross-org trust (separate sequencing per ADR-022)
  • Node compat (Bun-only at v0.1; the SQLite store imports bun:sqlite)

Install

bun add @auggy/link

Requires bun >= 1.0.0. Node is not supported at v0.1.


Quickstart

A receiver wired to Bun.serve, with bearer auth and an in-memory task store (swap MemoryTaskStore for SqliteTaskStore in production):

import {
  buildAgentCard,
  BearerAuthProvider,
  createLinkApp,
  type HandlerOutcome,
  type MessageHandler,
} from "@auggy/link";
import { MemoryTaskStore } from "@auggy/link/testing";

const agentCard = buildAgentCard({
  id: "00000000-0000-4000-8000-000000000001",
  name: "Demo Receiver",
  description: "Echoes incoming messages",
  endpoint_url: "https://demo.example.com",
  capabilities: [],
  skills: [],
});

const auth = new BearerAuthProvider({
  peers: {
    "00000000-0000-4000-8000-000000000002": {
      participant: {
        id: "00000000-0000-4000-8000-000000000002",
        locator: "https://peer-b.example.com",
        type: "agent",
        trust: "agent",
      },
      active: {
        bearer: process.env.PEER_B_INBOUND_BEARER!,
        bearer_id: "v1",
      },
    },
  },
});

const onMessage: MessageHandler = async ({ message }): Promise<HandlerOutcome> => {
  return {
    kind: "message",
    parts: [{ kind: "text", text: "echo: " + JSON.stringify(message.parts) }],
  };
};

const app = createLinkApp({
  agentCard,
  auth,
  taskStore: new MemoryTaskStore(),
  onMessage,
});

Bun.serve({ port: 8080, fetch: app.fetch });

Use SqliteTaskStore in production — it survives restart and satisfies Anchor III (originator restart, return-to-completed task):

import { SqliteTaskStore } from "@auggy/link";
const taskStore = new SqliteTaskStore({ path: "/data/link.db" });

For graceful shutdown, install the SIGTERM handler against the LinkAppHandle:

import { installSigtermHandler } from "@auggy/link";

const server = Bun.serve({ port: 8080, fetch: app.fetch });
installSigtermHandler({
  fetch: app.fetch,
  shutdown: async () => {
    await app.shutdown();
    server.stop(true);
  },
});

Public API surface

Every export below is locked at v0.1. Internal modules can be reorganized without a major version bump; this list cannot.

Protocol — import { ... } from "@auggy/link"

| Export | Kind | Purpose | |---|---|---| | buildAgentCard | function | Build a validated AgentCard for /.well-known/agent.json | | BuildAgentCardOptions | type | Options for buildAgentCard | | parseRequest | function | Validate + decode a JSON-RPC request envelope | | successResponse | function | Build a JSON-RPC success envelope | | errorResponse | function | Build a JSON-RPC error envelope | | parseError, invalidRequest, methodNotFound, invalidParams, internalError, taskNotFound, taskNotCancelable, pushNotificationNotSupported, unsupportedOperation, contentTypeNotSupported | factories | A2A error factory functions | | PARSE_ERROR, INVALID_REQUEST, METHOD_NOT_FOUND, INVALID_PARAMS, INTERNAL_ERROR, TASK_NOT_FOUND, TASK_NOT_CANCELABLE, PUSH_NOTIFICATION_NOT_SUPPORTED, UNSUPPORTED_OPERATION, CONTENT_TYPE_NOT_SUPPORTED | constants | Numeric A2A error codes | | MessageSendParamsSchema, MessageSendWireResultSchema, MessageStreamParamsSchema, TasksGetParamsSchema, TasksGetWireResultSchema, TasksCancelParamsSchema, TasksCancelWireResultSchema, HandlerSendResultSchema | zod schemas | Per-method runtime validators | | MessageSendParams, MessageSendWireResult, MessageStreamParams, TasksGetParams, TasksGetWireResult, TasksCancelParams, TasksCancelWireResult, HandlerSendResult | types | Per-method type aliases | | hashSendPayload, isTaskResult | functions | Idempotency-key payload hash + result-shape predicate | | Result | type | { ok: true; value } | { ok: false; error } | | AgentCard, Artifact, ISO8601, JsonRpcError, JsonRpcErrorPayload, JsonRpcRequest, JsonRpcResponse, Message, MessageRole, Part, Participant, ParticipantType, SkillDescriptor, SkillReturns, Task, TaskState, TextPart, TrustLevel, UUID | types | Wire-shape types | | AgentCardSchema, ArtifactSchema, JsonRpcErrorPayloadSchema, JsonRpcErrorSchema, JsonRpcRequestSchema, JsonRpcResponseSchema, MessageRoleSchema, MessageSchema, ParticipantSchema, ParticipantTypeSchema, PartSchema, SkillDescriptorSchema, SkillReturnsSchema, TaskSchema, TaskStateSchema, TextPartSchema, TrustLevelSchema | zod schemas | Wire-shape validators |

Server — import { ... } from "@auggy/link"

| Export | Kind | Purpose | |---|---|---| | AuthProvider | interface | Pluggable receiver-side auth contract | | AuthContext, AuthFailureCode, AuthVerifyRequest | types | Auth provider input/output shapes | | AuthFailure | class | Auth verify failure | | LinkAuthError | class | Auth error class | | BEARER_EXPIRED_HEADER, BEARER_EXPIRED_VALUE | constants | Bearer-expired wire signal | | BearerAuthProvider | class | Bearer auth implementation with rotation slots | | BearerAuthProviderOptions, PeerBearerConfig | types | Options for BearerAuthProvider | | MessageHandler | type | Wrapper-supplied handler callback | | HandlerContext, HandlerOutcome, MessageOutcome, TaskCreateOutcome, TaskContinueOutcome, TaskContinueOutcomeWorking, TaskContinueOutcomeInputRequired, TaskContinueOutcomeCompleted, TaskContinueOutcomeFailed, TaskContinueOutcomeCanceled, ErrorOutcome | types | Handler input + outcome variants | | TaskStore | interface | Persistence contract for receiver-side task state | | CreateTaskInput, LeaseToken, LinkStoreErrorCode, TaskStateTransition | types | Task store input shapes | | LEGAL_TRANSITIONS, isLegalTransition | constant + function | Task state-machine guard | | LinkStoreError, StoreError, TaskNotFound, TaskTerminal, IdempotencyConflict, LeaseExpired, StaleStateTransition | classes | Task-store error hierarchy | | SqliteTaskStore | class | Durable production TaskStore (WAL-mode SQLite) | | SqliteTaskStoreOptions | type | Constructor options for SqliteTaskStore |

Public API factories + classes — import { ... } from "@auggy/link"

| Export | Kind | Purpose | |---|---|---| | createLinkApp | function | Receiver-side factory; returns LinkAppHandle | | LinkAppOptions, LinkAppHandle, Fetch | types | Factory shapes | | RateLimitsConfig, TlsTrustConfig | types | Optional rate-limit + TLS-trust policy | | AddressBook | interface | Outbound peer config lookup | | EnvAddressBook | class | Env-var-backed AddressBook | | PeerClient | class | Outbound A2A client | | PeerClientConfig, TaskStreamEvent | types | Outbound config + stream event shape | | DEFAULT_PEER_CLIENT_CONFIG | constant | Default retry + timeout settings | | PeerSendError, PeerClientErrorCode | types | Outbound error shapes | | LinkClientError, PeerUnauthenticated, PeerNetworkError, PeerProtocolError, PeerRateLimited, PeerConfigError | classes | Outbound error hierarchy |

Runtime — import { ... } from "@auggy/link"

| Export | Kind | Purpose | |---|---|---| | installSigtermHandler | function | Wire SIGTERM/SIGINT to LinkAppHandle.shutdown | | InstallSigtermHandlerOptions | type | Options for installSigtermHandler |

Test-only — import { ... } from "@auggy/link/testing"

| Export | Kind | Purpose | |---|---|---| | MemoryTaskStore | class | In-process TaskStore for tests; lost on restart | | createDevApp | function | Bare Hono app exposing /health for bun run dev liveness |

The ./testing subpath is deliberately separate so production consumers cannot accidentally pull MemoryTaskStore and lose state on every restart (which would silently break Anchor III re-attachment).


A2A v0.2 wire compatibility

Link v0.1 targets A2A v0.2 only (Google + Linux Foundation, JSON-RPC over HTTPS, agent-card discovery at /.well-known/agent.json).

In scope at v0.1:

  • Methods: message/send, message/stream, tasks/get, tasks/cancel
  • Parts: text only
  • Bearer auth (the v0.2 spec admits mTLS and other schemes; we ship bearer)
  • Agent card discovery
  • A2A-spec error codes — every receiver-side error maps to a documented code

Deferred (still A2A-compatible, just not implemented in v0.1):

  • tasks/resubscribe — SSE re-attach without re-issuing the task
  • Push notifications method group
  • File / image parts
  • mTLS auth scheme

Mismatched-version peers (a future link-v0.2 talking to a link-v0.1) are an operational concern at the deployment layer, not at the library level. The AgentCard.capabilities field is the discovery point; future link versions will read it and decline unsupported method groups gracefully.


Two ways to use link

As a library (npm)

bun add @auggy/link

This is what the npm tarball delivers: compiled library code (dist/), type declarations, README, and LICENSE — nothing else. Wire it into your own runtime using the Quickstart above: createLinkApp + BearerAuthProvider + a TaskStore + your MessageHandler + Bun.serve.

As a reference deployment (clone the repo)

The package ships compiled library code only. To deploy a real link instance to Railway (or Docker, or any container runtime), clone the repository — it has the Dockerfile, railway.json, and operator runbook:

git clone https://github.com/looselyorganized/link.git
cd link
# follow infra/deploy.md

The Railway template, Dockerfile, and full deployment guide live at:

These deliberately are NOT shipped in the npm tarball — link is a library, not an operator distribution. v0.2 may publish a separate scaffolding package (a la create-next-app).

For repo contributors verifying the integration test suite from a clone: bun test tests/integration/two-instance-roundtrip.test.ts spawns two Bun.serve instances on different ports and exercises message/send + tasks/get round-trips with mutual bearer auth. (tests/ is dev-only and excluded from files, so this command only works against a clone, not against the tarball.)


Semver + breaking-change policy

v0.x is pre-1.0. Minor versions MAY break; patch versions never break. v1.0+ follows strict semver: major = breaking, minor = additive, patch = bugfix.

What counts as breaking

  • Removing a public export from @auggy/link or @auggy/link/testing
  • Narrowing an exported type's domain (e.g., adding a required option field, removing a union variant from an output type)
  • Renaming a public export (treated as remove + add)
  • Removing or renaming a method on an exported class
  • Removing a method from an exported interface (consumer-side impls would silently break — see caveat below)
  • Changing the wire protocol in a way that breaks A2A v0.2 compatibility (the wire is locked to A2A; link-level breaks only ship in a major bump)
  • Tightening a runtime validator's constraints (formerly-valid input rejected)

What does NOT count as breaking

  • Adding optional fields to options types
  • Adding new exports
  • Adding new error subclasses to an existing hierarchy (consumer instanceof checks still work; new ones can be added in user code)
  • Loosening a validator's constraints
  • Refactoring internal modules — the public barrel is the contract

Interface-method caveat

Adding a method to an exported interface is technically additive for callers but breaking for implementors (consumers who provide their own AuthProvider, TaskStore, AddressBook, MessageHandler). Link treats this as a minor at v1.0+ but ships a deprecation cycle: a default impl is provided on the interface for one minor version, and removed only at the next major. v0.1 makes no such promise — we may add interface methods freely until v1.0.

A2A version support

Link v0.x targets A2A v0.2 only. Future link versions will track A2A spec evolution. Mismatched-version peers (e.g., a link-v1.0 talking to a link-v2 peer that has dropped a method group) are an operational concern handled through AgentCard.capabilities discovery at the deployment layer, not at the library API level.


License

See LICENSE. License decision is deferred at v0.1.0 pending review by the LORF maintainers; the code is currently published under "all rights reserved" — clone for evaluation, but contact the maintainers before production use. A v0.2 release will commit to a specific OSI-approved license.


Contributing

Link is part of the Loosely Organized Research Facility (LORF) project. PRs are welcome, but the public API surface listed above is locked — additions follow the additive rules in the semver policy; removals and renames need a major version bump. File-level reorganization is fine, but the barrel exports cannot move.

For inquiries: [email protected]