Skip to content

TypeScript/JavaScript client

The official TypeScript/JavaScript client lives in clients/js. Unlike the read-only Go client, it speaks the WebSocket mutation protocol: chat, claims, releases, board reads, presence, and receipts. It runs unchanged in the browser and in Node 20+ (both expose a global WebSocket) and has no runtime dependencies.

Install

npm install @anulum/synapse-channel

Connect and coordinate

import { SynapseClient, MessageType } from "@anulum/synapse-channel";

const client = new SynapseClient({
  uri: "ws://127.0.0.1:8876",
  name: "SYNAPSE-CHANNEL/web-agent",
  token: process.env.SYNAPSE_TOKEN,
});

client.on(MessageType.Chat, (m) => console.log(`${m.sender}: ${m.payload}`));
await client.connect();

client.chat("hello", { target: "all" });
client.claim("synapse-channel:web", ["src/web/**"]);
client.requestBoard();
client.release("synapse-channel:web");
client.close();

claim(taskId, paths, pathIdentity?) also accepts the version-1 ClaimScopeIdentity exported by the package. This is an additive transport type for bridges that already used the Python Git/filesystem resolver; the dependency-free browser client deliberately does not inspect a local repository or invent canonical values. When present, its canonical worktree_path is also sent as the ordinary worktree field so the hub validates the full display scope. Omit the third argument when no trusted local resolver is available. The hub then retains legacy literal-path comparison.

connect() opens the socket, sends the registration heartbeat (with the token when one is configured), and resolves once the hub returns its welcome; it rejects if the hub closes the socket before welcoming the identity or if no welcome arrives within readyTimeoutMs.

Scope and boundaries

The client implements the agent-side envelope and the connection lifecycle: registration, keepalive heartbeats, typed send helpers, and inbound dispatch by MessageType. It does not run the hub, does not enforce ACLs, and does not verify per-message authentication — those are hub-side. On a secured or ACL-enforcing hub, supply the connect token; namespace authorisation still depends on the hub binding the sender, so use a token (and per-message auth) on an exposed hub.

It is a separate npm package and does not ship inside the Python synapse-channel distribution.