agent-browser
Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling…
Yjs CRDT sync over durable streams with @durable-streams/y-durable-streams. DurableStreamsProvider setup, document stream and awareness stream config, transport modes (SSE vs long-poll), provider lifecycle (connect, disconnect, destroy), synced/status/error events, lib0
$ npx -y skills add humanlayer/humanlayer --skill durable-streams-yjs --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/durable-streams-yjsContext preview
The summary Claude sees to decide when to auto-load this skill.
Yjs CRDT sync over durable streams with @durable-streams/y-durable-streams. DurableStreamsProvider setup, document stream and awareness stream config, transport modes (SSE vs long-poll), provider lifecycle (connect, disconnect, destroy), synced/status/error events, lib0
name: durable-streams-yjs description: Yjs CRDT sync over durable streams with @durable-streams/y-durable-streams. DurableStreamsProvider setup, document stream and awareness stream config, transport modes (SSE vs long-poll), provider lifecycle (connect, disconnect, destroy), synced/status/error events, lib0 VarUint8Array framing, awareness heartbeat. Requires yjs, y-protocols, lib0 peer dependencies. Load when integrating Yjs collaborative editing with durable streams.
Sync Yjs documents over HTTP durable streams. No WebSocket infrastructure needed — uses standard HTTP with SSE or long-poll transport. Built-in persistence through stream history, presence support via awareness streams.
import { DurableStreamsProvider } from "@durable-streams/y-durable-streams"
import * as Y from "yjs"
import { Awareness } from "y-protocols/awareness"
const doc = new Y.Doc()
const awareness = new Awareness(doc)
const provider = new DurableStreamsProvider({
doc,
documentStream: {
url: "https://your-server.com/v1/stream/doc-updates",
transport: "sse",
},
awarenessStream: {
url: "https://your-server.com/v1/stream/doc-awareness",
protocol: awareness,
transport: "sse",
},
})
provider.on("synced", (synced) => {
console.log("Synced:", synced)
})
provider.on("status", (status) => {
console.log("Status:", status) // "disconnected" | "connecting" | "connected"
})import { DurableStreamsProvider } from "@durable-streams/y-durable-streams"
import * as Y from "yjs"
const doc = new Y.Doc()
const provider = new DurableStreamsProvider({
doc,
documentStream: {
url: "https://your-server.com/v1/stream/my-doc",
transport: "sse",
},
})const provider = new DurableStreamsProvider({
doc,
documentStream: { url, transport: "sse" },
connect: false, // Don't auto-connect
})
// Connect when ready
provider.connect()
// Temporarily disconnect (can reconnect later)
provider.disconnect()
// Permanently destroy (cleanup all listeners and timers)
provider.destroy()const provider = new DurableStreamsProvider({
doc,
documentStream: {
url: "https://your-server.com/v1/stream/my-doc",
transport: "sse",
headers: {
Authorization: () => `Bearer ${getAccessToken()}`,
},
},
})Wrong:
npm install @durable-streams/y-durable-streams
Correct:
npm install @durable-streams/y-durable-streams yjs y-protocols lib0
`yjs`, `y-protocols`, and `lib0` are peer dependencies. Missing them causes import errors at runtime.
Source: packages/y-durable-streams/package.json peerDependencies
Wrong:
documentStream: {
url: "https://server.com/v1/stream/doc-1",
transport: "sse",
contentType: "application/json",
}Correct:
documentStream: {
url: "https://server.com/v1/stream/doc-1",
transport: "sse",
// Content type defaults to application/octet-stream (binary)
}Yjs documents use binary encoding (lib0 VarUint8Array). The stream must use `application/octet-stream`, not `application/json`. The provider handles this automatically — don't override the content type.
Source: packages/y-durable-streams/src/y-durable-streams.ts BINARY_CONTENT_TYPE
Wrong:
useEffect(() => {
const provider = new DurableStreamsProvider({ doc, documentStream: config })
return () => provider.disconnect() // Only disconnects, doesn't clean up!
}, [])Correct:
useEffect(() => {
const provider = new DurableStreamsProvider({ doc, documentStream: config })
return () => provider.destroy() // Full cleanup
}, [])`disconnect()` only closes the connection — `destroy()` also removes doc/awareness listeners and clears the 15-second awareness heartbeat interval.
Source: packages/y-durable-streams/README.md API methods
Targets @durable-streams/y-durable-streams v0.2.1.
HumanLayer runs coding agents (Claude Code, Codex, OpenCode, Pi) on your machines and lets your team steer them from one place: tasks, sessions, plans, and reviews, synced between a desktop app, a web app, and a daemon on each host. This repo holds all of it.
Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling…
Rewrites ambiguous English into ASD-STE100 style — one meaning per word, active voice, simple tense, short sentences. Use when…
Use for 1) inspecting PR state, 2) reading review threads, or 3) debugging CI failures. Otherwise use the gh CLI.
Bump the base version of one or more packages (riptide-native, cli, linear-cli, rpi-plugin) on a PR - updates every synced file,…
Diff call stacks across git commits for agentic code review (22 languages). Run `calldiff --help` for usage details.
Use this to skill to write shell scripts or run shell commands to automate tasks in the browser or otherwise use Chrome DevTools…