Skip to content
Back to skills

Ops Obs

ASecurity

Monitor, diagnose, and optimize OBS Studio on KDE Plasma Ubuntu. Use when the user says "obs health", "obs stats", "monitor obs", "obs dropped frames", "optimize obs", "obs stream control", "start/stop obs recording", "obs doctor", "obs websocket", or wants OBS buttons on the Stream Deck.

  • 6 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added September 11, 2026
testingpythonbashnodeapi

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 9 files and shows the line behind each finding

Scanned September 11, 2026

npx -y skills add grahama1970/agent-skills --skill ops-obs --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Ops Obs?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Ops Obs
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/grahama1970-ops-obs/badge)](https://www.skillsdirectory.com/skills/grahama1970-ops-obs)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: ops-obs
description: >
  Monitor, diagnose, and optimize OBS Studio on KDE Plasma Ubuntu. Use when the
  user says "obs health", "obs stats", "monitor obs", "obs dropped frames",
  "optimize obs", "obs stream control", "start/stop obs recording", "obs doctor",
  "obs websocket", or wants OBS buttons on the Stream Deck.
triggers:
  - obs health
  - obs stats
  - monitor obs
  - obs dropped frames
  - optimize obs
  - obs stream control
  - start obs recording
  - stop obs recording
  - obs doctor
  - obs websocket
provides:
  - obs-monitoring
  - obs-control
  - obs-streamdeck-bindings
composes:
  - agentic-evals
  - ops-streamdeck
  - triage-error
  - project-watchdog
  - pi-intercom
  - ops-herdr
complies:
  - best-practices-skills
  - best-practices-python
taxonomy:
  - observability-operations
runtime_self_improvement: none
---

# ops-obs

Typer CLI that monitors and optimizes OBS Studio on KDE Plasma Ubuntu through
two surfaces:

1. **Live** (needs OBS running with its obs-websocket v5 server enabled,
   default port 4455): stats, health findings, stream/record control, scene
   switching. Flatpak and native installs both supported; the password is
   read from `--password` > `OBS_WS_PASSWORD` > the OBS websocket plugin
   config (never logged).
2. **Local** (no OBS needed): `doctor` detects the install kind, websocket
   server state, GPU encoders (NVENC/VAAPI), session/capture guidance
   (Wayland+PipeWire vs X11/XSHM), log error scan, and disk headroom.

All output is JSON on stdout. Success is `{"ok": true, ...}`; every failure is
a typed envelope `{"ok": false, "code", "cause", "next_command"}` with exit 1 —
never a bare traceback or generic timeout.

## Commands

| Command | Surface | Description |
| --- | --- | --- |
| `run.sh status [--host --port --password --timeout]` | live | Version + GetStats + stream/record state + health findings |
| `run.sh watch [--interval N] [--notify-tab TAB]` | live | Continuous NDJSON monitoring; messages TAB via the ops-herdr bridge on crit findings |
| `run.sh notify TEXT --tab TAB` | local | Send a message to a Herdr tab through the ops-herdr pi-herdr bridge |
| `run.sh stream start\|stop\|toggle\|status` | live | Stream control (start/stop tolerate wrong-state errors 500/501) |
| `run.sh record start\|stop\|toggle\|status` | live | Record control; `stop` prints the output path |
| `run.sh scene list` / `run.sh scene set NAME` | live | List scenes / switch program scene |
| `run.sh streamdeck bindings` | local | Emit `ops-obs.streamdeck_bindings.v1` button definitions |
| `run.sh streamdeck status` | live | One-token state: `OFFLINE` / `LIVE` / `REC` / `LIVE+REC` / `ERR:<code>` (exit 1) |
| `run.sh doctor` | local | Install, ws server, GPU encoder, session, disk, log scan |
| `run.sh paths` | local | Resolve config root (flatpak/native), logs dir, ws config |
| `run.sh selftest` | local | Protocol auth-vector regression check |
| `run.sh verify` | eval | Run `fixtures/agentic_eval.json` via `../agentic-evals/run.sh` |

Config roots detected in order: Flatpak
`~/.var/app/com.obsproject.Studio/config/obs-studio`, then native
`~/.config/obs-studio`.

## Health thresholds (from `status`/`watch`)

| Check | warn | crit | Hint |
| --- | --- | --- | --- |
| render skipped/total | ≥5% | ≥10% | Fewer sources/filters; Wayland+PipeWire over XSHM |
| output skipped/total | ≥1% | ≥5% | Lower resolution/fps/bitrate; hardware encoder (NVENC/VAAPI) |
| stream congestion | ≥0.05 | — | Lower bitrate; fix network |
| disk free | <5 GB | <1 GB | Clean recording target |
| active output at 0 fps | — | any | Encoder stalled; run `doctor` |

## Failure codes

| code | cause | next_command |
| --- | --- | --- |
| `obs_ws_connection_refused` | no server at host:port | start OBS; enable Tools → WebSocket Server Settings |
| `obs_ws_server_disabled` | local config says server off (port matches config) | Tools → WebSocket Server Settings → Enable |
| `obs_ws_timeout` | connect/handshake/request timeout | raise `--timeout`; restart OBS |
| `obs_ws_password_required` | auth challenge but no password | `OBS_WS_PASSWORD` / `--password` |
| `obs_ws_auth_failed` | handshake rejected | verify password in OBS settings |
| `obs_ws_request_failed` | RequestResponse result=false (code+comment surfaced) | run `stream/record status` or `doctor` |
| `obs_ws_protocol_error` | unexpected/malformed message | check obs-websocket ≥ 5.0 |
| `obs_notify_bridge_unavailable` | ops-herdr bridge CLI or node missing | verify pi-herdr-bridge and node |
| `obs_notify_failed` | bridge rejected the send (unknown tab/pane) | `bridge-cli.mjs list`, use exact tab label |

Every failure envelope also carries a `triage` block: the same signal classified
through the shared `/triage-error` catalog (`../triage-error/run.sh classify
--layer ops-obs`). The `obs_ws_*` and `obs_notify_*` codes are catalog entries,
not local inventions, so any layer can resolve them to one
`{code, cause, next_command}`.

## Self-healing loop

1. Any command failure emits the typed envelope + `triage` classification.
2. Recurring or serious failures get filed via `/ticket` (stamps `agent-work`).
3. `project-watchdog` dispatches them: the `grahama1970/agent-skills` registry
   entry already covers `skills/ops-obs` (only `skills/battle` is carved out to
   its own project), so ticks route ops-obs tickets through the creator-reviewer
   repair DAG in the primary checkout on main, with the proof gate before close.

## Intercom / Herdr addressing

The OBS lane is a pi session in a Herdr pane with tab label **`obs`**. Herdr tab
labels are not visible to plain `intercom list` — address the lane through the
ops-herdr bridge:

```bash
node ~/.pi/agent/skills/ops-herdr/pi-herdr-bridge/bridge-cli.mjs list   # shows {tab:<label>}
node ~/.pi/agent/skills/ops-herdr/pi-herdr-bridge/bridge-cli.mjs send --to obs --text "run ops-obs doctor"
```

Other pi sessions use pi-intercom (`send`/`ask` to the aliased session) once the
pane is live; the bridge is the discovery path when only the tab label is known.
Outbound: `run.sh notify` and `watch --notify-tab obs` push crit findings to that
tab through the same bridge.

## Stream Deck integration

`run.sh streamdeck bindings` emits validated button definitions whose commands
invoke this skill (runnability of `run.sh` is checked before emission). Merge
them into the ops-streamdeck daemon config (`~/.streamdeck/daemon.json`
buttons) — do NOT edit `~/.streamdeck_ui.json` while `streamdeck.service`
runs, and never embed these commands into a
`streamdeck.dynamic_page_request.v1` request (that boundary rejects raw
commands; a catalog recipe would be required first).
`run.sh streamdeck status` emits a one-token state line designed for icon
renderer widgets (exit 0 + token, or exit 1 + `ERR:<code>`).

## Evaluation

`fixtures/agentic_eval.json` (3 trials/case) proves: CLI wiring, live local
`doctor`/`paths`, the typed connection-refused path, usage validation, the
protocol auth vector, and streamdeck bindings emission. Live websocket
control is NOT proven while the local OBS has its websocket server disabled
(the optional `status-live` case reports BLOCKED with the marker). Proof
scope is stated in the fixture `claims` block.

Files in this skill

  • .gitignore26 B
  • SKILL.md7.1 KB
  • fixtures/agentic_eval.json3.5 KB
  • pyproject.toml346 B
  • run.sh421 B
  • sanity.sh2.7 KB
  • scripts/obs_protocol.py16.9 KB
  • scripts/ops_obs.py21.5 KB
  • uv.lock42 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.