Skip to main content

core

REQUIRED before any wsh terminal operation when you do NOT have wsh_* MCP tools. Contains the complete HTTP API reference with working curl examples, bootstrap sequence, and authentication guide. wsh has no CLI subcommands for programmatic use — do NOT run 'wsh <verb>' commands or guess endpoints. Load this skill first.

来源信息

仓库
deepgram/wsh
最近来源活动
2026年3月13日 11:20
检测到的 SKILL.md 语言
英语
星标
5
分支
1

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
name
core
description
REQUIRED before any wsh terminal operation when you do NOT have wsh_* MCP tools. Contains the complete HTTP API reference with working curl examples, bootstrap sequence, and authentication guide. wsh has no CLI subcommands for programmatic use — do NOT run 'wsh <verb>' commands or guess endpoints. Load this skill first.
user-invocable
false
# wsh: Terminal as a Service You have access to `wsh`, an API that gives you direct control over terminal sessions. You can see exactly what's on screen, send keystrokes, wait for commands to finish, and create visual elements — all programmatically. Think of it this way: wsh gives you **eyes** (read the screen), **hands** (send input), **patience** (wait for output to settle), and **a voice** (overlays and panels to communicate with the human). ## How It Works wsh manages terminal sessions via a server daemon and exposes everything over an HTTP API served on a Unix domain socket. The human sees their normal terminal. You see a programmatic interface to the same session. Everything is synchronized — input you send appears on their screen, output they generate appears in your API calls. All endpoints are scoped to a session via `/sessions/:name/` prefix (e.g., `/sessions/default/input`). By default, wsh serves HTTP over a Unix domain socket at `${XDG_RUNTIME_DIR}/wsh/<name>.http.sock` (default name: "default"). This is local-only and requires no authentication. TCP access is opt-in via `--bind` for remote scenarios. > **MCP also available:** wsh is also accessible as an MCP server (14 tools, > 3 resources, 9 prompts) via Streamable HTTP at `/mcp` on the same socket, > or via the `wsh mcp` stdio bridge. See the `wsh:core-mcp` prompt for > MCP-specific guidance. ## Getting Started Before using the API, make sure a wsh server is reachable. **Step 1: Check for an existing server.** A wsh server may already be running — try the default Unix socket: WSH_SOCK=${XDG_RUNTIME_DIR:-/tmp}/wsh/default.http.sock curl -sf --unix-socket $WSH_SOCK http://localhost/health If this returns `200 OK`, the server is reachable. Skip to step 3. **Step 2: Start a server (only if needed).** Use `-L` with a unique name to avoid colliding with any existing wsh instance: wsh server -L agent-$$ --ephemeral & sleep 1 WSH_SOCK=${XDG_RUNTIME_DIR:-/tmp}/wsh/agent-$$.http.sock # Wait for socket to appear while [ ! -S "$WSH_SOCK" ]; do sleep 0.1; done The socket path is deterministic from the instance name — no port discovery needed. **Step 3: Create a session.** Sessions are where commands run. Create one via the API: curl -s -X POST --unix-socket $WSH_SOCK http://localhost/sessions \ -H "Content-Type: application/json" \ -d '{"name": "work"}' Returns `{"name": "work", ...}` on success. **Step 4: Use the send/wait/read loop.** Now interact with your session using the API primitives described below. The fundamental loop: # Send a command curl -s -X POST --unix-socket $WSH_SOCK http://localhost/sessions/work/input -d $'ls -la\n' # Wait for idle curl -s --unix-socket $WSH_SOCK http://localhost/sessions/work/idle?timeout_ms=2000 # Read the screen curl -s --unix-socket $WSH_SOCK http://localhost/sessions/work/screen?format=plain ## Authentication When wsh serves over a Unix domain socket (default), no authentication is needed — all connections are local and trusted. When binding to a TCP address with `--bind` (e.g., `--bind 0.0.0.0:7368`), every request requires a Bearer token: curl -H "Authorization: Bearer <token>" http://host:7368/sessions/default/screen The token is either auto-generated on startup (printed to stderr) or set via `--token` / `WSH_TOKEN`. Retrieve it later with `wsh token`. **WebSocket connections** from browsers use a ticket exchange: first acquire a short-lived ticket via `POST /auth/ws-ticket` with your Bearer token, then pass `?ticket=<nonce>` on the WebSocket URL. Non-browser clients can use the `Authorization` header directly on the upgrade request. ## The Fundamental Loop Almost everything you do with wsh follows this pattern: 1. **Send** — inject input into the terminal 2. **Wait** — let the command run until output settles 3. **Read** — see what's on screen now 4. **Decide** — based on what you see, choose what to do next This is your heartbeat. Learn it. A `drive-process` interaction is just this loop repeated until the task is done. ## API Primitives These are the building blocks. Every specialized skill builds on these. ### Send Input Inject keystrokes into the terminal. Supports raw bytes — use bash `$'...'` quoting for control characters. curl -s -X POST --unix-socket $WSH_SOCK http://localhost/sessions/default/input -d 'ls -la' curl -s -X POST --unix-socket $WSH_SOCK http://localhost/sessions/default/input -d $'ls -la\n' curl -s -X POST --unix-socket $WSH_SOCK http://localhost/sessions/default/input -d $'\x03' # Ctrl+C curl -s -X POST --unix-socket $WSH_SOCK http://localhost/sessions/default/input -d $'\x1b' # Escape curl -s -X POST --unix-socket $WSH_SOCK http://localhost/sessions/default/input -d $'\x1b[A' # Arrow Up curl -s -X POST --unix-socket $WSH_SOCK http://localhost/sessions/default/input -d $'\t' # Tab Returns 204 (no content) on success. ### Wait for Idle Block until the terminal has been idle for `timeout_ms` milliseconds. This is a hint that the program may be idle — it could also just be working without producing output. curl -s --unix-socket $WSH_SOCK http://localhost/sessions/default/idle?timeout_ms=2000 Returns the current screen snapshot plus a `generation` counter once idle. Returns 408 if the terminal doesn't settle within 30 seconds (configurable via `max_wait_ms`). When polling repeatedly, pass back the `generation` from the previous response as `last_generation` to avoid busy-loop storms: curl -s --unix-socket $WSH_SOCK 'http://localhost/sessions/default/idle?timeout_ms=2000&last_generation=42' Or use `fresh=true` to always observe real silence (simpler, but always waits at least `timeout_ms`): curl -s --unix-socket $WSH_SOCK 'http://localhost/sessions/default/idle?timeout_ms=2000&fresh=true' ### Read the Screen Get the current visible screen contents. curl -s --unix-socket $WSH_SOCK http://localhost/sessions/default/screen?format=plain curl -s --unix-socket $WSH_SOCK http://localhost/sessions/default/screen?format=styled `plain` returns simple text lines. `styled` returns spans with color and formatting attributes. ### Read Scrollback Get historical output that has scrolled off screen. curl -s --unix-socket $WSH_SOCK http://localhost/sessions/default/scrollback?format=plain&offset=0&limit=100 Use `offset` and `limit` to page through history. ### Health Check Verify wsh is running. curl -s --unix-socket $WSH_SOCK http://localhost/health ### Real-Time Events (WebSocket) For monitoring and input capture, you need real-time event streaming. Connect to the JSON WebSocket: websocat --ws-c-uri=ws://localhost/sessions/default/ws/json - ws-c:unix:$WSH_SOCK After connecting, subscribe to the events you care about: {"id": 1, "method": "subscribe", "params": { "events": ["lines", "input"], "format": "plain", "idle_timeout_ms": 1000 }} Available event types: - `lines` — new lines of output - `cursor` — cursor movement - `mode` — alternate screen toggled - `diffs` — batched screen changes - `input` — keyboard input (essential for input capture) The server pushes events as they happen. It also sends periodic `sync` snapshots when the terminal goes idle (controlled by `idle_timeout_ms`). Under high output, the server coalesces events automatically: instead of individual updates, you get periodic `sync` snapshots at `interval_ms` intervals (default 100ms). This is transparent — handle `sync` events the same way you handle the initial sync after subscribing. For a different session, replace `default` with the session name: websocat --ws-c-uri=ws://localhost/sessions/build/ws/json - ws-c:unix:$WSH_SOCK You can also send requests over the WebSocket instead of HTTP — `get_screen`, `send_input`, `resize`, `capture_input`, `release_input`, `focus`, `unfocus`, `get_focus`, `get_screen_mode`, `enter_alt_screen`, `exit_alt_screen`, etc. Same capabilities, persistent connection. ## Visual Elements ### Overlays Floating text positioned on top of terminal content. They don't affect the terminal — they're a layer on top. # Create an overlay at position (0, 0) with explicit size curl -s -X POST --unix-socket $WSH_SOCK http://localhost/sessions/default/overlay \ -H "Content-Type: application/json" \ -d '{"x": 0, "y": 0, "width": 20, "height": 1, "spans": [{"text": "Hello!", "bold": true}]}' # Returns {"id": "uuid"} — use this to update or delete it curl -s -X DELETE --unix-socket $WSH_SOCK http://localhost/sessions/default/overlay/{id} curl -s -X DELETE --unix-socket $WSH_SOCK http://localhost/sessions/default/overlay # clear all **Opaque overlays:** Add `background` to fill the rectangle with a solid color, making it a window-like element: curl -s -X POST --unix-socket $WSH_SOCK http://localhost/sessions/default/overlay \ -H "Content-Type: application/json" \ -d '{"x": 10, "y": 5, "width": 40, "height": 10, "background": {"bg": "black"}, "spans": [{"text": "Window content"}]}' Background accepts named colors (`"bg": "blue"`) or RGB (`"bg": {"r": 30, "g": 30, "b": 30}`). **Named spans:** Give spans an `id` for targeted updates: curl -s -X POST --unix-socket $WSH_SOCK http://localhost/sessions/default/overlay \ -H "Content-Type: application/json" \ -d '{"x": 0, "y": 0, "width": 30, "height": 1, "spans": [ {"id": "label", "text": "Status: ", "bold": true}, {"id": "value", "text": "running", "fg": "green"} ]}' # Update named spans by id (POST with array of span updates) curl -s -X POST --unix-socket $WSH_SOCK http://localhost/sessions/default/overlay/{id}/spans \ -H "Content-Type: application/json" \ -d '{"spans": [{"id": "value", "text": "stopped", "fg": "red"}]}' **Region writes:** Place styled text at specific (row, col) offsets: curl -s -X POST --unix-socket $WSH_SOCK http://localhost/sessions/default/overlay/{id}/write \ -H "Content-Type: application/json" \ -d '{"writes": [{"row": 2, "col": 5, "text": "Hello", "bold": true}]}' **Focusable:** Add `focusable: true` to allow focus routing during input capture (see Input Capture below). Use overlays for: tooltips, status indicators, annotations, notifications — anything that should appear *on top of* the terminal without disrupting it. With explicit dimensions: windows, dialogs, cards. ### Panels Agent-owned screen regions at the top or bottom of the terminal. Unlike overlays, panels **shrink the PTY** — they carve out dedicated space. curl -s -X POST --unix-socket $WSH_SOCK http://localhost/sessions/default/panel \ -H "Content-Type: application/json" \ -d '{"position": "bottom", "height": 3, "spans": [{"text": "Status: running"}]}' **Background:** Add `background` to fill the panel with a solid color: curl -s -X POST --unix-socket $WSH_SOCK http://localhost/sessions/default/panel \ -H "Content-Type: application/json" \ -d '{"position": "bottom", "height": 2, "background": {"bg": "blue"}, "spans": [{"text": "Status: ok"}]}' **Named spans:** Same as overlays — give spans an `id` for targeted updates via POST with an array of span updates: curl -s -X POST --unix-socket $WSH_SOCK http://localhost/sessions/default/panel/{id}/spans \ -H "Content-Type: application/json" \ -d '{"spans": [{"id": "status", "text": "3 errors", "fg": "red"}]}' **Region writes:** Place text at specific (row, col) offsets: curl -s -X POST --unix-socket $WSH_SOCK http://localhost/sessions/default/panel/{id}/write \ -H "Content-Type: application/json" \ -d '{"writes": [{"row": 0, "col": 10, "text": "updated", "bold": true}]}' **Focusable:** Add `focusable: true` to allow focus routing during input capture. Use panels for: persistent status bars, progress displays, context summaries — anything that deserves its own screen real estate. ### Input Capture Intercept keyboard input so it comes to you instead of the shell. curl -s -X POST --unix-socket $WSH_SOCK http://localhost/sessions/default/input/capture # grab input curl -s -X POST --unix-socket $WSH_SOCK http://localhost/sessions/default/input/release # release back While captured, keystrokes are available via WebSocket subscription instead of going to the PTY. The human can press Ctrl+\ to toggle capture mode (it switches between passthrough and capture). **Focus routing:** Direct captured input to a specific focusable overlay or panel. At most one element has focus at a time.
在 GitHub 查看
这个 SKILL.md 很大,SkillsMP 这里只预览前一段内容。 在 GitHub 查看