docs › Streamer overlay (OBS)
Streamer overlay (OBS)
Put an agent session on your stream. dexterm overlay serves three transparent scenes for an OBS Browser source (agent activity, the coin card, the PAPER or LIVE PnL card) on 127.0.0.1, fed by the read-only spectator stream or a saved replay. Covers the OBS setup step by step, the three themes, what is redacted, the security model, the SAMPLE DATA tag and the limits.
Generated against dexterm/app at commit 9beaec4. dexterm overlay turns the spectator view into scenes you can drop into OBS as a Browser source: the agent's recent calls, the coin it is on, and its PnL card, over a transparent background. It watches; it never acts. Nothing on an overlay page can pause, trade, arm, size, sign or raise a cap, and the page sends nothing back to dexterm.
The three scenes#
| Scene | What it shows | Where the data comes from |
|---|---|---|
activity | The agent's last calls: when, the agent, the tool, a one-line summary, and how old that call's data was | Every call the spectator stream carries |
coin | The coin the agent is on: ticker and shortened mint, price, the deterministic verdict with the rug heuristic, the LARP evidence flags, a top-10 holder bar with the holder count, and the live holder/rug signals, each with its age | The results of the agent's own get_token, get_holders, get_dossier, analyze_token and larp_check calls, plus the signals your terminal fires for that coin while it follows the agent |
pnl | The PnL card, drawn by the same renderer as the H key (PnL cards) | The agent's PAPER fills on the coin, or one trade from your own ledger with --ledger |
--scene all puts the three scenes in one Browser source (two columns, the PnL card underneath) if you would rather crop one source than place three.
Every scene shows how old its data is (data age 12s, and … old next to each figure). The scene's age chip turns yellow once its newest figure is over two minutes old. The LARP line says "evidence, not a verdict", and every page ends with "read-only · addresses redacted · not financial advice".
Before you start#
You need an agent session to watch. Pick one:
- An agent connected over MCP (Claude Code, Cursor, Codex, …): run the app with
dexterm --spectate-mcp. Your terminal follows the agent and opens the read-only spectator stream. See follow over MCP. - An agent on the loopback bus:
dexterm agent serve --spectate. See bring your own agent. - No agent, a dry run or a rehearsal: a saved session with
--replay FILE(record one withdexterm agent serve --record FILE). Every scene then carries a yellow SAMPLE DATA · REPLAY tag.
The overlay finds the live stream on its own (the same spectator.json that dexterm spectate --info reads), waits for it if it is not up yet, and reconnects when it restarts.
Set it up in OBS, step by step#
- Start the session you want to show (see above).
- In a second terminal, run:
sh $ dexterm overlay --theme cyberspace dexterm overlay · theme cyberspace · each URL works once, for 10 min activity http://127.0.0.1:53133/overlay/activity?p=… coin http://127.0.0.1:53133/overlay/coin?p=… pnl http://127.0.0.1:53133/overlay/pnl?p=…
Leave it running for as long as you stream. q (or ctrl+c) stops it.
- In OBS, in your scene's Sources panel, click + and choose Browser. Name it (for example "dexterm coin") and click OK.
- In the properties window:
- URL: paste one of the printed URLs (the whole line after the scene name).
- Width / Height:
1240×420forcoinoractivity,1240×760forpnl,1600×1300forall. Resize the source on the canvas afterwards; the scenes scale. - Leave Use custom frame rate off.
- Leave Custom CSS as OBS fills it in (it keeps the background transparent) or empty.
- Untick Shutdown source when not visible and Refresh browser when scene becomes active: either one reloads the page, and a reload needs a fresh URL (see below).
- Click OK. The panel appears over your stream with a transparent background. Repeat steps 3 to 5 for the other scenes.
- To check the setup without a live agent, run
dexterm overlay --replay session.jsonl --loopand watch the scenes fill in with the SAMPLE DATA tag on.
Each URL works once. It is a single-use ticket: OBS's first load spends it, and the page then holds its own one-time connection. If OBS reloads the page, or you paste the URL into a second source, the page stays empty. Press n in the overlay's terminal for a fresh set of URLs and paste the new one into the source. URLs that are never loaded expire after 10 minutes (--ticket-ttl MIN changes that, 1 to 240). When you restart dexterm overlay, its port changes too, so paste fresh URLs then; --port N keeps the port fixed (the tickets still change).
Options#
| Option | What it does |
|---|---|
--scene NAME | activity, coin, pnl or all; repeat it for several. Default: the three scenes |
--theme NAME | cyberspace (phosphor green, the app's default look), ice (electric cyan) or neon (magenta). Default cyberspace |
--replay FILE | Play a saved spectator session instead of the live stream. Every scene says SAMPLE DATA |
--speed N | Replay speed (default 1); gaps between calls are capped at 5 s |
--loop | Replay again from the start; the final scenes hold for 10 s first |
--ledger TRADE_ID | The PnL scene shows one round trip from your own trade ledger (dexterm ledger trades lists the ids) instead of the agent's paper fills. --sol-usd N for a USD-booked trade |
--port N | A fixed loopback port (1024 to 65535) instead of a random one |
--ticket-ttl MIN | Minutes an unused URL stays valid (default 10) |
--json | Print the scene URLs as JSON |
The PnL scene: PAPER and LIVE#
The card is the PnL card renderer itself, so its stamp, frame colour, stamp strip, provenance block, data ages and "not financial advice" footer are drawn exactly as on a saved card and cannot be turned off.
- The agent's trades are PAPER. An agent can only paper-trade in dexterm, so a card built from the stream is always stamped PAPER · SIMULATED TRADE · NO REAL FUNDS, and the scene header says PAPER · SIMULATED. An open position is marked at the newest price the stream carried (converted to SOL at the rate the agent's own fill implies) or, without a later price, at the last fill; the card prints which, and how old the mark is.
- Your own ledger trades are PAPER or LIVE by wallet mode. With
--ledger TRADE_IDthe stamp follows the trade's wallet mode: paper is PAPER, devnet is LIVE · DEVNET (test funds, not real money) and live is LIVE · WALLET-SIGNED, on the card and in the scene header alike. The LIVE note counts the trade's wallet-signed transactions. A real-mode row gets no card (dexterm only modelled that fill; your executor's receipt is the record). The ledger is a local file, read again every 30 seconds. - Size is a band and the wallet never shows. The mint is shortened and transaction signatures are left off the overlay card.
- A replay is SAMPLE DATA. With
--replay, a yellow SAMPLE DATA band sits across the top of the card, above the card's own stamp.
What is redacted#
Redaction is always on, and the overlay applies it itself, whatever its source already did:
- Every wallet or mint address becomes its first and last four characters (
Fixt…AAAA), in every field: tool names, summaries, agent names, LARP evidence, signal text. - Key material (long base58 or hex runs) becomes
[key]. - Anything the spectator stream marks sensitive is shown as
[sensitive], and sensitive-named fields are dropped before they reach a scene. - A coin, fill or ticket whose mint is not in the shortened shape is dropped, not shown.
Security model#
The overlay uses the same model as the popup windows:
- Loopback only. The page server listens on
127.0.0.1(a random port unless--port) and refuses any connection that is not from this machine. - Single-use ticket, then a one-time token. A URL carries a random 32-byte ticket that buys exactly one page load. That page holds a second, one-time token (valid 30 seconds) for its WebSocket. A spent or expired ticket, a ticket for another scene, or a forged token gets an empty 404.
- Host and Origin checks. Every request must say
Host: 127.0.0.1:<port>(so a DNS-rebinding page cannot reach it), and the WebSocket must come from the overlay's own origin. No CORS header is ever sent. Refused probes are printed in the overlay's terminal, without the ticket. - No inbound control. The socket only pushes scene data. Whatever a page sends is counted and dropped, never parsed or acted on; the overlay has nothing it could control.
- A locked-down page. Its script and styles are inline under a per-page nonce; the content security policy allows no remote content, no fonts, no frames and no other connections. The page builds its text with
textContentonly (agent and coin text are untrusted), and the only image is the PnL card, sent over the socket. - No new network. The overlay talks to the spectator stream on loopback and reads your ledger file. It fetches nothing from the internet.
The URL is printed in your own terminal so you can paste it; treat it like the popup URLs: it is loopback-only and single-use, but don't post a screenshot of a fresh one.
Limits#
- The scenes show what the agent did. If the agent never reads holders, the holder bar stays "not read yet"; if it never runs a LARP check, there is no LARP line. Live signals appear only while your terminal follows the agent (
--spectate-mcp) and has that coin's data. - One coin at a time. The coin card follows the coin the agent touched last; the PnL card follows the agent's newest paper fill.
- A reload needs a fresh URL (see the OBS steps). This is the single-use ticket working as designed.
- The stream starts with the last 200 events when the overlay connects, then follows live.
- Not financial advice. The verdict, LARP evidence and signals are risk information, never a recommendation; paper results are simulated.