cmux 0.3.6 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,73 +1,119 @@
1
- # cmux
1
+ # cmux TypeScript Client
2
2
 
3
- Cloud VMs for development - spawn isolated dev environments instantly.
3
+ The typed client library for cmux-tui frontends. It exposes every implemented
4
+ command and event in protocol v10, transport-independent request handling,
5
+ browser-safe attach streams, and Node.js Unix-socket defaults.
4
6
 
5
- ## Installation
7
+ ## Install and build
6
8
 
7
9
  ```bash
8
- npm install -g cmux
10
+ npm install cmux
11
+ npm run build
9
12
  ```
10
13
 
11
- ## Quick Start
12
-
13
- ```bash
14
- # Login
15
- cmux login
14
+ The package has no runtime dependencies. The Node entry requires Node 20 or
15
+ newer. Browser bundles resolve the root `browser` export condition, and the
16
+ same browser-safe surface is available explicitly from `cmux/browser`.
17
+
18
+ ## Building a frontend
19
+
20
+ This example uses an existing xterm.js terminal and a cmux WebSocket endpoint.
21
+ Attach payloads are decoded to `Uint8Array`, which xterm.js accepts directly.
22
+
23
+ ```ts
24
+ import { Terminal } from "@xterm/xterm";
25
+ import { CmuxClient, WebSocketTransport } from "cmux";
26
+ const terminal = new Terminal();
27
+ const transport = new WebSocketTransport("ws://127.0.0.1:9000/api/v1/ws", {
28
+ onPairingChallenge: ({ code }) => showCode(code),
29
+ });
30
+ const client = new CmuxClient({ transport });
31
+ const info = await client.identify();
32
+ console.log(`cmux protocol ${info.protocol}`);
33
+ const tree = await client.listWorkspaces();
34
+ const workspace = tree.workspaces.find(({ active }) => active);
35
+ const screen = workspace?.screens.find(({ active }) => active);
36
+ const pane = screen?.panes.find((item) => "tabs" in item);
37
+ const surface = pane && "tabs" in pane ? pane.tabs[pane.active_tab]?.surface : undefined;
38
+ if (surface === undefined) throw new Error("No active surface");
39
+ const stream = await client.attachSurface(surface);
40
+ void (async () => {
41
+ for await (const event of stream) {
42
+ if (event.event === "vt-state" || event.event === "output") terminal.write(event.data);
43
+ }
44
+ })();
45
+ await client.send(surface, { bytes: new TextEncoder().encode("ls\r") });
46
+ ```
16
47
 
17
- # Create a VM
18
- cmux start # Returns ID like cmux_abc123
48
+ Without `authToken`, the transport requests a short-lived pairing code and
49
+ holds protocol requests until a trusted TUI approves it. The approval issues a
50
+ credential through `onPairingCredential` for reconnects. For automation, a
51
+ server started with `--ws-token` accepts that static token instead:
19
52
 
20
- # Access the VM
21
- cmux code cmux_abc123 # Open VS Code in browser
22
- cmux ssh cmux_abc123 # SSH into VM
53
+ ```ts
54
+ const transport = new WebSocketTransport("ws://127.0.0.1:7681", {
55
+ authToken: "replace-with-a-secret",
56
+ });
57
+ ```
23
58
 
24
- # Run commands
25
- cmux exec cmux_abc123 "npm install"
59
+ `WebSocketTransport` uses the browser's global `WebSocket`. In Node, inject any
60
+ compatible constructor without adding a runtime dependency to this package:
26
61
 
27
- # Manage lifecycle
28
- cmux pause cmux_abc123 # Pause (preserves state)
29
- cmux resume cmux_abc123 # Resume
30
- cmux delete cmux_abc123 # Delete permanently
62
+ ```ts
63
+ import WebSocket from "ws";
64
+ import { CmuxClient, WebSocketTransport } from "cmux";
31
65
 
32
- # List all VMs
33
- cmux ls
66
+ const client = new CmuxClient({
67
+ transport: new WebSocketTransport("ws://127.0.0.1:9000/api/v1/ws", WebSocket),
68
+ });
34
69
  ```
35
70
 
36
- ## Commands
71
+ ## Node Unix socket
37
72
 
38
- | Command | Description |
39
- |---------|-------------|
40
- | `cmux login` | Login via browser |
41
- | `cmux start [path]` | Create new VM, optionally sync directory |
42
- | `cmux ls` | List all VMs |
43
- | `cmux code <id>` | Open VS Code in browser |
44
- | `cmux vnc <id>` | Open VNC desktop in browser |
45
- | `cmux ssh <id>` | SSH into VM |
46
- | `cmux pty <id>` | Open interactive terminal |
47
- | `cmux exec <id> "cmd"` | Execute command |
48
- | `cmux sync <id> <path>` | Sync files to VM |
49
- | `cmux pause <id>` | Pause VM |
50
- | `cmux resume <id>` | Resume VM |
51
- | `cmux delete <id>` | Delete VM |
73
+ The default Node entry preserves the original zero-argument API:
52
74
 
53
- ## Browser Automation
75
+ ```ts
76
+ import { CmuxClient } from "cmux/node";
54
77
 
55
- Control Chrome in the VNC desktop:
78
+ const client = new CmuxClient();
79
+ const created = await client.newWorkspace({ name: "sdk-demo", cols: 80, rows: 24 });
80
+ await client.send(created.surface, { text: "echo hello\r" });
81
+ console.log((await client.readScreen(created.surface)).text);
82
+ await client.close();
83
+ ```
56
84
 
57
- ```bash
58
- cmux computer open cmux_abc123 https://example.com
59
- cmux computer snapshot cmux_abc123 # Get interactive elements
60
- cmux computer click cmux_abc123 @e1 # Click element
61
- cmux computer type cmux_abc123 "hello" # Type text
62
- cmux computer screenshot cmux_abc123 # Take screenshot
85
+ `new CmuxClient()` uses `CMUX_TUI_SOCKET`, then legacy `CMUX_MUX_SOCKET`, then
86
+ the default session socket. Unix subscribe and attach streams retain dedicated
87
+ connections. An injected transport can multiplex attach streams and one
88
+ subscription on its main connection; concurrent subscriptions require a
89
+ `streamTransportFactory` because overflow events are terminal to one stream.
90
+ Each stream retains at most 256 unread events, and each encoded attach payload
91
+ is limited to 16 MiB by default. `maxBufferedEvents` and
92
+ `maxAttachEncodedChars` may lower those limits for constrained clients.
93
+
94
+ ## Raw typed requests
95
+
96
+ Every command method delegates to the same generic escape hatch:
97
+
98
+ ```ts
99
+ const result = await client.request({ cmd: "copy", surface: 1, mode: "screen" });
63
100
  ```
64
101
 
65
- ## Platform Support
102
+ The `cmd` discriminator determines both required parameters and the successful
103
+ response data type. `sendRaw()` remains available for untyped forward
104
+ compatibility.
66
105
 
67
- - macOS (Apple Silicon & Intel)
68
- - Linux (x64 & ARM64)
69
- - Windows (x64)
106
+ `clearHistory(surface, fallbackKey)` accepts a typed `TerminalKeyInput` and
107
+ fails locally unless the server advertises `clear-history-key-v1`. It also
108
+ rejects fallback `utf8` fields above the 4 KiB protocol limit before sending.
109
+ `CmuxCommandError.delivery` exposes the server's `known-not-delivered` or
110
+ `ambiguous` classification when present.
70
111
 
71
- ## License
112
+ ## Verification
72
113
 
73
- MIT
114
+ ```bash
115
+ npm ci
116
+ npm run build
117
+ npm test
118
+ CMUX_TUI_SOCKET=/path/to/session.sock npm run e2e
119
+ ```
@@ -0,0 +1,4 @@
1
+ /** Decodes standard base64 without requiring Node's `Buffer`. */
2
+ export declare function decodeBase64(value: string): Uint8Array;
3
+ /** Encodes bytes as standard base64 without requiring Node's `Buffer`. */
4
+ export declare function encodeBase64(value: Uint8Array): string;
@@ -0,0 +1,38 @@
1
+ function nodeBuffer() {
2
+ return globalThis.Buffer;
3
+ }
4
+ /** Decodes standard base64 without requiring Node's `Buffer`. */
5
+ export function decodeBase64(value) {
6
+ if (typeof globalThis.atob === "function") {
7
+ const decoded = globalThis.atob(value);
8
+ const bytes = new Uint8Array(decoded.length);
9
+ for (let index = 0; index < decoded.length; index += 1)
10
+ bytes[index] = decoded.charCodeAt(index);
11
+ return bytes;
12
+ }
13
+ const Buffer = nodeBuffer();
14
+ if (!Buffer)
15
+ throw new Error("base64 decoding is not available in this runtime");
16
+ const decoded = Buffer.from(value, "base64");
17
+ const bytes = new Uint8Array(decoded.length);
18
+ for (let index = 0; index < decoded.length; index += 1)
19
+ bytes[index] = decoded[index];
20
+ return bytes;
21
+ }
22
+ /** Encodes bytes as standard base64 without requiring Node's `Buffer`. */
23
+ export function encodeBase64(value) {
24
+ if (typeof globalThis.btoa === "function") {
25
+ let binary = "";
26
+ const chunkSize = 0x8000;
27
+ for (let offset = 0; offset < value.length; offset += chunkSize) {
28
+ const chunk = value.subarray(offset, Math.min(offset + chunkSize, value.length));
29
+ for (const byte of chunk)
30
+ binary += String.fromCharCode(byte);
31
+ }
32
+ return globalThis.btoa(binary);
33
+ }
34
+ const Buffer = nodeBuffer();
35
+ if (!Buffer)
36
+ throw new Error("base64 encoding is not available in this runtime");
37
+ return Buffer.from(value).toString("base64");
38
+ }
@@ -0,0 +1,6 @@
1
+ export { CmuxClient, CmuxStream, TERMINAL_KEY_TEXT_MAX_BYTES, type CmuxClientOptions, type CmuxClientOptions as ClientOptions, type AttachSurfaceOptions, type NewBrowserTabOptions, type NewPaneRightOptions, type NewScreenOptions, type NewTabOptions, type NewWorkspaceOptions, type ResizeTransactionOptions, type SelectOptions, type SelectTabOptions, type SendOptions, type SplitOptions, type SubscribeOptions, } from "./client.js";
2
+ export * from "./base64.js";
3
+ export * from "./errors.js";
4
+ export * from "./protocol/index.js";
5
+ export * from "./transport.js";
6
+ export * from "./websocket-transport.js";
@@ -0,0 +1,6 @@
1
+ export { CmuxClient, CmuxStream, TERMINAL_KEY_TEXT_MAX_BYTES, } from "./client.js";
2
+ export * from "./base64.js";
3
+ export * from "./errors.js";
4
+ export * from "./protocol/index.js";
5
+ export * from "./transport.js";
6
+ export * from "./websocket-transport.js";
@@ -0,0 +1,202 @@
1
+ import type { ApplyLayoutResult, CmuxCommand, CmuxRequest, CmuxRequestParams, CmuxResponse, CmuxResponseData, CmuxResponseDataFor, ColorHex, CopyMode, CopyResult, DecodedAttachEvent, EmptyResult, ExportLayoutResult, Id, IdKind, IdRef, IdsResult, IdentifyResult, JsonObject, ListAgentsResult, ListClientsResult, ListTerminalsResult, LayoutUndoResult, MoveTerminalResult, NotificationLevel, NotifyResult, PaneDirection, PaneNeighborResult, PingResult, ProcessInfoResult, ReadScrollbackResult, ReadScreenResult, ReloadConfigResult, ResizeSurfaceResult, ReportAgentResult, ResolveTerminalResult, RunResult, RenderAttachEvent, SidebarPluginResult, SplitDirection, SubscribeEvent, SurfaceResult, TerminalKeyInput, TerminalPlacement, TerminalEventsResult, Tree, WorkspacePlacement, WorkspaceMutation, VtStateResult, WaitForResult, ZoomPaneResult, AgentReportSource, AgentState, CloseTerminalResult, DeclarativeLayout, FocusDirectionResult } from "./protocol/index.js";
2
+ import type { Transport } from "./transport.js";
3
+ export interface CmuxClientOptions {
4
+ transport: Transport;
5
+ timeoutMs?: number;
6
+ allowProtocolV6Attach?: boolean;
7
+ /** Maximum events retained for a stream whose consumer falls behind. */
8
+ maxBufferedEvents?: number;
9
+ /** Maximum encoded characters per attach payload and retained bytes across buffered attach events. */
10
+ maxAttachEncodedChars?: number;
11
+ /** Creates dedicated subscribe/attach transports when supplied. */
12
+ streamTransportFactory?: () => Transport;
13
+ }
14
+ export declare const DEFAULT_MAX_BUFFERED_EVENTS = 256;
15
+ export declare const DEFAULT_MAX_ATTACH_ENCODED_CHARS: number;
16
+ export declare const TERMINAL_KEY_TEXT_MAX_BYTES: number;
17
+ export interface ResizeTransactionOptions {
18
+ /** Reuse across one continuous drag, then choose a new value for the next drag. */
19
+ transaction?: number | null;
20
+ }
21
+ export type NewTabOptions = CmuxRequestParams<"new-tab">;
22
+ export type NewBrowserTabOptions = Omit<CmuxRequestParams<"new-browser-tab">, "url">;
23
+ export type NewWorkspaceOptions = CmuxRequestParams<"new-workspace">;
24
+ export type CreateWorkspaceOptions = CmuxRequestParams<"create-workspace">;
25
+ export type CreateTerminalOptions = CmuxRequestParams<"create-terminal">;
26
+ export type CloseTerminalOptions = Omit<CmuxRequestParams<"close-terminal">, "terminal_id" | "terminal_incarnation">;
27
+ export type CloseWorkspaceOptions = CmuxRequestParams<"close-workspace">;
28
+ export type RenameWorkspaceOptions = CmuxRequestParams<"rename-workspace">;
29
+ export type MoveWorkspaceOptions = CmuxRequestParams<"move-workspace">;
30
+ export type NewScreenOptions = CmuxRequestParams<"new-screen">;
31
+ export type NewPaneOptions = Omit<CmuxRequestParams<"new-pane">, "pane">;
32
+ export type NewPaneRightOptions = Omit<CmuxRequestParams<"new-pane-right">, "pane">;
33
+ export type SplitOptions = Omit<CmuxRequestParams<"split">, "pane" | "dir">;
34
+ export type SelectOptions = CmuxRequestParams<"select-screen">;
35
+ export type SelectTabOptions = CmuxRequestParams<"select-tab">;
36
+ export interface SendOptions {
37
+ text?: string | null;
38
+ /** Standard base64-encoded raw bytes sent in the wire `bytes` field. */
39
+ base64?: string | null;
40
+ /** @deprecated Use `base64`, or pass text for UTF-8 input. */
41
+ bytes?: string | Uint8Array | null;
42
+ /** Request bracketed-paste wrapping when terminal mode 2004 is enabled. */
43
+ paste?: boolean;
44
+ }
45
+ export interface SubscribeOptions {
46
+ treeEvents?: "coarse" | "deltas";
47
+ }
48
+ export type AttachSurfaceOptions = {
49
+ mode?: "bytes" | "render";
50
+ } & ({
51
+ cols: number;
52
+ rows: number;
53
+ } | {
54
+ cols?: never;
55
+ rows?: never;
56
+ });
57
+ /** A closeable async event stream with optional per-read timeouts. */
58
+ export declare class CmuxStream<T extends {
59
+ event: string;
60
+ }> implements AsyncIterable<T> {
61
+ private readonly timeoutMs;
62
+ private readonly cleanup;
63
+ private readonly maxBufferedEvents;
64
+ private readonly maxBufferedBytes;
65
+ private readonly retainedBytes;
66
+ private readonly buffered;
67
+ private bufferedBytes;
68
+ private readonly waiters;
69
+ private closed;
70
+ private endsAfterDrain;
71
+ private terminalError;
72
+ constructor(timeoutMs: number, cleanup: () => void, maxBufferedEvents?: number, maxBufferedBytes?: number, retainedBytes?: (event: T) => number);
73
+ next(timeoutMs?: number): Promise<T>;
74
+ close(): void;
75
+ push(event: T, terminal?: boolean): void;
76
+ fail(error: Error): void;
77
+ get error(): Error | null;
78
+ [Symbol.asyncIterator](): AsyncIterator<T>;
79
+ private finish;
80
+ private rejectWaiters;
81
+ }
82
+ /** Promise-based typed client for any cmux JSON transport. */
83
+ export declare class CmuxClient {
84
+ readonly timeoutMs: number;
85
+ readonly allowProtocolV6Attach: boolean;
86
+ readonly maxBufferedEvents: number;
87
+ readonly maxAttachEncodedChars: number;
88
+ private readonly transport;
89
+ private readonly router;
90
+ private readonly streamTransportFactory?;
91
+ private nextRequestId;
92
+ private identifiedProtocol;
93
+ private identifiedCapabilities;
94
+ private sharedSubscriptionActive;
95
+ constructor(options: CmuxClientOptions);
96
+ close(): Promise<void>;
97
+ sendRaw(obj: JsonObject): Promise<CmuxResponse<unknown>>;
98
+ request<C extends CmuxRequest>(request: C): Promise<CmuxResponseData<C>>;
99
+ request<C extends CmuxCommand>(cmd: C, ...args: Record<string, never> extends CmuxRequestParams<C> ? [params?: CmuxRequestParams<C>] : [params: CmuxRequestParams<C>]): Promise<CmuxResponseDataFor<C>>;
100
+ identify(): Promise<IdentifyResult>;
101
+ /** The protocol reported by the latest `identify()`, or null before identification. */
102
+ get protocol(): number | null;
103
+ ping(): Promise<PingResult>;
104
+ setClientInfo(name?: string, kind?: string): Promise<EmptyResult>;
105
+ listClients(): Promise<ListClientsResult>;
106
+ detachClient(client: Id): Promise<EmptyResult>;
107
+ setClientSizing(surface: Id, client: Id, enabled: boolean): Promise<EmptyResult>;
108
+ useOnlyClientSizing(surface: Id, client: Id): Promise<EmptyResult>;
109
+ useAllClientSizing(surface: Id): Promise<EmptyResult>;
110
+ reloadConfig(): Promise<ReloadConfigResult>;
111
+ setWindowTitle(title: string): Promise<EmptyResult>;
112
+ clearWindowTitle(): Promise<EmptyResult>;
113
+ listWorkspaces(): Promise<Tree>;
114
+ listTerminals(): Promise<ListTerminalsResult>;
115
+ terminalEvents(afterRevision?: number): Promise<TerminalEventsResult>;
116
+ exportLayout(screen?: Id | null): Promise<ExportLayoutResult>;
117
+ applyLayout(layout: DeclarativeLayout, options?: Omit<CmuxRequestParams<"apply-layout">, "layout">): Promise<ApplyLayoutResult>;
118
+ send(surface: Id, options?: SendOptions): Promise<EmptyResult>;
119
+ clearHistory(surface: Id, fallbackKey?: TerminalKeyInput): Promise<EmptyResult>;
120
+ readScreen(surface: Id): Promise<ReadScreenResult>;
121
+ readScrollback(surface: Id, start: number, count: number): Promise<ReadScrollbackResult>;
122
+ sidebarPlugin(cols: number, rows: number, relaunch?: boolean | null): Promise<SidebarPluginResult>;
123
+ vtState(surface: Id): Promise<VtStateResult>;
124
+ resolveTerminal(terminalId: string): Promise<ResolveTerminalResult>;
125
+ closeTerminal(terminalId: string, terminalIncarnation?: string | null, options?: CloseTerminalOptions): Promise<CloseTerminalResult>;
126
+ newTab(options?: NewTabOptions): Promise<SurfaceResult>;
127
+ newBrowserTab(url: string, options?: NewBrowserTabOptions): Promise<SurfaceResult>;
128
+ newWorkspace(options?: NewWorkspaceOptions): Promise<SurfaceResult>;
129
+ createWorkspace(options?: CreateWorkspaceOptions): Promise<WorkspacePlacement>;
130
+ createTerminal(options: CreateTerminalOptions): Promise<TerminalPlacement>;
131
+ moveTerminal(terminalId: string, workspaceKey: string, options?: Omit<CmuxRequestParams<"move-terminal">, "terminal_id" | "workspace_key">): Promise<MoveTerminalResult>;
132
+ newScreen(options?: NewScreenOptions): Promise<SurfaceResult>;
133
+ newPane(pane: Id, options?: NewPaneOptions): Promise<SurfaceResult>;
134
+ newPaneRight(pane: Id, options?: NewPaneRightOptions): Promise<SurfaceResult>;
135
+ split(pane: Id, dir: SplitDirection, options?: SplitOptions): Promise<SurfaceResult>;
136
+ setRatio(pane: Id, dir: SplitDirection, ratio: number): Promise<EmptyResult>;
137
+ setSplitRatio(split: Id, ratio: number, options?: ResizeTransactionOptions): Promise<EmptyResult>;
138
+ setViewportPaneWidth(pane: Id, width: number, options?: ResizeTransactionOptions): Promise<EmptyResult>;
139
+ undoLayout(pane: Id, confirmationRevision?: number): Promise<LayoutUndoResult>;
140
+ paneNeighbor(pane: Id, dir: PaneDirection): Promise<PaneNeighborResult>;
141
+ focusDirection(dir: PaneDirection, pane?: Id | null): Promise<FocusDirectionResult>;
142
+ swapPane(params: CmuxRequestParams<"swap-pane">): Promise<EmptyResult>;
143
+ zoomPane(params?: CmuxRequestParams<"zoom-pane">): Promise<ZoomPaneResult>;
144
+ processInfo(surface: Id): Promise<ProcessInfoResult>;
145
+ setDefaultColors(fg?: ColorHex | null, bg?: ColorHex | null): Promise<EmptyResult>;
146
+ closeSurface(surface: Id): Promise<EmptyResult>;
147
+ closePane(pane: Id): Promise<EmptyResult>;
148
+ closeScreen(screen: Id): Promise<EmptyResult>;
149
+ closeWorkspace(workspace: Id): Promise<EmptyResult>;
150
+ closeWorkspaceRegistry(options: CloseWorkspaceOptions): Promise<WorkspaceMutation>;
151
+ renamePane(pane: Id, name: string): Promise<EmptyResult>;
152
+ renameSurface(surface: Id, name: string): Promise<EmptyResult>;
153
+ renameScreen(screen: Id, name: string): Promise<EmptyResult>;
154
+ renameWorkspace(workspace: Id, name: string): Promise<EmptyResult>;
155
+ renameWorkspaceRegistry(options: RenameWorkspaceOptions): Promise<WorkspaceMutation>;
156
+ resizeSurface(surface: Id, cols: number, rows: number): Promise<ResizeSurfaceResult>;
157
+ releaseSurfaceSize(surface: Id): Promise<EmptyResult>;
158
+ focusPane(pane: Id): Promise<EmptyResult>;
159
+ selectTab(options?: SelectTabOptions): Promise<EmptyResult>;
160
+ selectScreen(options?: SelectOptions): Promise<EmptyResult>;
161
+ selectWorkspace(options?: SelectOptions): Promise<EmptyResult>;
162
+ moveTab(surface: Id, pane: Id, index: number): Promise<EmptyResult>;
163
+ moveWorkspace(workspace: Id, index: number): Promise<EmptyResult>;
164
+ moveWorkspaceRegistry(options: MoveWorkspaceOptions): Promise<WorkspaceMutation>;
165
+ scrollSurface(surface: Id, delta: number): Promise<EmptyResult>;
166
+ subscribe(options?: SubscribeOptions): Promise<CmuxStream<SubscribeEvent>>;
167
+ attachSurface(surface: Id, options?: AttachSurfaceOptions & {
168
+ mode?: "bytes";
169
+ }): Promise<CmuxStream<DecodedAttachEvent>>;
170
+ attachSurface(surface: Id, options: AttachSurfaceOptions & {
171
+ mode: "render";
172
+ }): Promise<CmuxStream<RenderAttachEvent>>;
173
+ attachSurface(surface: Id, options: AttachSurfaceOptions): Promise<CmuxStream<DecodedAttachEvent> | CmuxStream<RenderAttachEvent>>;
174
+ private requireCapability;
175
+ private requireProtocol;
176
+ waitFor(surface: IdRef, pattern: string, timeoutMs: number): Promise<WaitForResult>;
177
+ run(options: CmuxRequestParams<"run">): Promise<RunResult>;
178
+ sendKey(surface: IdRef, keys: string[]): Promise<EmptyResult>;
179
+ copy(surface: IdRef, mode: CopyMode): Promise<CopyResult>;
180
+ ids(kind?: IdKind | null): Promise<IdsResult>;
181
+ notify(title: string, body: string, options?: {
182
+ level?: NotificationLevel | null;
183
+ surface?: IdRef | null;
184
+ }): Promise<NotifyResult>;
185
+ listAgents(options?: CmuxRequestParams<"list-agents">): Promise<ListAgentsResult>;
186
+ reportAgent(surface: IdRef, state: AgentState, source: AgentReportSource, session?: string | null): Promise<ReportAgentResult>;
187
+ private openStream;
188
+ private decodeAttachEvent;
189
+ private decodeAttachData;
190
+ private decodeBrowserFrame;
191
+ private validateFrameSequence;
192
+ private validateFrameCssDimension;
193
+ private validateFrameDimension;
194
+ private validateAttachEncodedData;
195
+ private attachEventRetainedBytes;
196
+ private matchesAttachEvent;
197
+ private isSurfaceOverflow;
198
+ private attachOnlyEvent;
199
+ private dropUndefined;
200
+ private securityLimit;
201
+ private nextId;
202
+ }