Skip to content
screenjson

screenjson-server

Watch a script change live

Subscribe to a screenjson-server script's event stream from Node or the browser, and see every edit as it lands, from people and agents alike.

Last updated September 2026

Every change on screenjson-server is published on a websocket channel, using the Centrifuge protocol. The server’s own web app uses it to re-render scripts as agents edit them; your code can listen to the same stream.

Channels

ChannelCarries
doc:{id}Every change to one script.
libraryScripts added, changed and removed.
pass:{label}A pass’s progress.

GET /status names the websocket (events.client_url, normally /connection/websocket).

A listener in Node

npm install centrifuge
// watch.mjs
import { Centrifuge } from 'centrifuge';

const server = process.env.S ?? 'http://127.0.0.1:8080';
const doc = process.argv[2];

const client = new Centrifuge(server.replace(/^http/, 'ws') + '/connection/websocket');
const sub = client.newSubscription(`doc:${doc}`);
sub.on('publication', ({ data }) => console.log(JSON.stringify(data)));
sub.subscribe();
client.connect();
node watch.mjs 3f64b20e-40b6-4a84-a6f2-da9ae05c11f3

The same code runs in the browser.

What an event looks like

Edit a line (by hand, over the API, or through an agent) and the listener prints:

{
  "seq": 3,
  "op": "node.updated",
  "kind": "element",
  "type": "action",
  "id": "8cd1ad2a-…",
  "path": "/documents/3f64…/scenes/0fea…/elements/action/8cd1ad2a-…",
  "rev": 2,
  "node": { "type": "action", "text": { "en": "The door opens." }, "…": "…" },
  "actor": "dialogue-polish",
  "ts": "2026-10-01T17:54:06Z"
}
  • op is node.inserted, node.updated, node.removed, node.moved, document.created, document.replaced, document.deleted or checkout.changed (someone took or released a checkout).
  • node is the changed part, as ScreenJSON.
  • actor is the token name that made the change, so you can tell agents and people apart.
  • seq counts the script’s changes. If you see a gap, you missed something: read the script again.

Uses

  • A dashboard of what a team of agents is doing, line by line.
  • Re-embedding a line the moment its text changes (or use a webhook, which includes a URL to send the vector back to).
  • Keeping a search index or cache in step with the library.

Next