@slicervm/sdk 0.1.1 → 0.1.3

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/dist/index.d.ts CHANGED
@@ -143,6 +143,42 @@ interface FSMkdirRequest {
143
143
  recursive?: boolean;
144
144
  mode?: string;
145
145
  }
146
+ type FSWatchEventType = 'create' | 'write' | 'remove' | 'rename' | 'chmod';
147
+ interface FSWatchRequest {
148
+ /** Absolute paths inside the VM to watch. At least one is required. */
149
+ paths: string[];
150
+ /** Optional glob patterns to filter event paths (e.g. `["*.go", "bin/*"]`). */
151
+ patterns?: string[];
152
+ /**
153
+ * Restrict to a subset of event types. When omitted, all types are delivered.
154
+ */
155
+ events?: FSWatchEventType[];
156
+ /** UID used by the agent to resolve `~` in paths. Default: 0 (root). */
157
+ uid?: number;
158
+ /** Watch directories recursively. */
159
+ recursive?: boolean;
160
+ /** Stop the stream after the first matching event. */
161
+ oneShot?: boolean;
162
+ /** Coalesce events arriving within this window. Go-duration string e.g. `"100ms"`. */
163
+ debounce?: string;
164
+ /** Server-side wall-clock cap on the stream. Go-duration string e.g. `"5m"`. */
165
+ timeout?: string;
166
+ /** Stop after delivering this many events. */
167
+ maxEvents?: number;
168
+ /** Forwarded as the SSE `Last-Event-ID` header for cross-connection resume. */
169
+ lastEventId?: string;
170
+ }
171
+ interface FSWatchEvent {
172
+ /** Monotonic per-stream ID (from the SSE `id:` line). */
173
+ id: number;
174
+ type: FSWatchEventType | string;
175
+ path: string;
176
+ /** RFC3339Nano string (when present). */
177
+ timestamp: string;
178
+ size: number;
179
+ isDir: boolean;
180
+ message?: string;
181
+ }
146
182
  interface ShutdownRequest {
147
183
  action?: 'shutdown' | 'reboot';
148
184
  }
@@ -261,8 +297,8 @@ interface TransportClientOptions {
261
297
  }
262
298
  declare class TransportClient {
263
299
  readonly transport: Transport;
264
- private readonly token?;
265
- private readonly userAgent;
300
+ readonly token?: string;
301
+ readonly userAgent: string;
266
302
  constructor(opts: TransportClientOptions);
267
303
  private agent;
268
304
  private buildRequestOptions;
@@ -271,11 +307,99 @@ declare class TransportClient {
271
307
  /** Raw-bytes request (for binary cp endpoints). */
272
308
  requestRaw(method: string, reqPath: string, body?: Buffer, contentType?: string): Promise<Buffer>;
273
309
  /** Streaming request producing a Node Readable of the response body. */
274
- requestStreamRaw(method: string, reqPath: string, body?: Buffer | Readable, contentType?: string): Promise<IncomingMessage>;
310
+ requestStreamRaw(method: string, reqPath: string, body?: Buffer | Readable, contentType?: string, extraHeaders?: Record<string, string>): Promise<IncomingMessage>;
275
311
  /** Yields decoded JSON frames from an NDJSON response (one JSON object per line). */
276
312
  requestNDJSON<Frame = unknown>(method: string, reqPath: string, body?: Buffer | Readable): AsyncGenerator<Frame, void, void>;
277
313
  }
278
314
 
315
+ /**
316
+ * Port forwarding for Slicer VMs.
317
+ *
318
+ * Per-connection WebSocket model: each accepted local TCP/Unix connection
319
+ * opens a fresh WebSocket to /vm/{hostname}/forward on the daemon. The
320
+ * WebSocket carries raw bytes both directions (binary frames, no framing
321
+ * subprotocol). The daemon uses the `X-Inlets-Upstream` header on the
322
+ * upgrade request to decide where to dial inside the VM.
323
+ */
324
+
325
+ interface AddressMapping {
326
+ rawSpec: string;
327
+ /** TCP listen address, or undefined when listening on a Unix socket. */
328
+ listenAddr?: string;
329
+ /** TCP listen port, or undefined when listening on a Unix socket. */
330
+ listenPort?: number;
331
+ /** Listen Unix socket path, or undefined when listening on TCP. */
332
+ listenUnixPath?: string;
333
+ /** Remote host inside the VM, or undefined when targeting a Unix socket. */
334
+ remoteHost?: string;
335
+ /** Remote port inside the VM, or undefined when targeting a Unix socket. */
336
+ remotePort?: number;
337
+ /** Remote Unix socket path inside the VM, or undefined when targeting TCP. */
338
+ remoteUnixPath?: string;
339
+ }
340
+ /**
341
+ * Parse a `-L`-style spec into an {@link AddressMapping}. Supported formats
342
+ * mirror the Go SDK's `slicer vm forward` CLI:
343
+ *
344
+ * - `127.0.0.1:9000` — listen and forward on the same TCP host:port
345
+ * - `9001:127.0.0.1:9000` — listen on `0.0.0.0:9001`, forward to `127.0.0.1:9000`
346
+ * - `0:127.0.0.1:9000` — listen on a random TCP port, forward as above
347
+ * - `0.0.0.0:9000:127.0.0.1:9000` — listen and forward, fully explicit
348
+ * - `127.0.0.1:9000:/var/run/docker.sock` — TCP listen, Unix socket forward
349
+ * - `9000:/var/run/docker.sock` — `0.0.0.0:9000` listen, Unix socket forward
350
+ * - `/tmp/docker.sock:/var/run/docker.sock` — Unix-to-Unix forward
351
+ * - `./docker.sock:/var/run/docker.sock` — Unix-to-Unix with relative local
352
+ */
353
+ declare function parseAddressMapping(spec: string): AddressMapping;
354
+ interface ForwarderListener {
355
+ /** The original spec string that produced this listener. */
356
+ spec: string;
357
+ /** Human-readable local address (`127.0.0.1:8080`, `/tmp/docker.sock`, etc). */
358
+ local: string;
359
+ /** Human-readable upstream target inside the VM. */
360
+ remote: string;
361
+ /** Resolved port for TCP listeners (useful when caller asked for `0`). */
362
+ port?: number;
363
+ }
364
+ interface ForwarderOptions {
365
+ /** Identifies this client to the daemon. Defaults to `os.hostname()`. */
366
+ clientId?: string;
367
+ /** WebSocket dial timeout (ms). Default 10_000. */
368
+ dialTimeoutMs?: number;
369
+ /**
370
+ * Optional logger for connection events. Receives short strings. Default: silent.
371
+ */
372
+ log?: (msg: string) => void;
373
+ }
374
+ interface ForwarderInit {
375
+ hostname: string;
376
+ transport: Transport;
377
+ token?: string;
378
+ userAgent: string;
379
+ specs: string[];
380
+ options?: ForwarderOptions;
381
+ }
382
+ /**
383
+ * A live set of port forwards for one VM. Returned by `vm.forward(...)`.
384
+ * Closing the forwarder tears down all local listeners and any in-flight
385
+ * tunnel WebSockets.
386
+ */
387
+ declare class Forwarder {
388
+ private readonly init;
389
+ private readonly mappings;
390
+ readonly listeners: ForwarderListener[];
391
+ private readonly servers;
392
+ private readonly liveSockets;
393
+ private closed;
394
+ private constructor();
395
+ static start(init: ForwarderInit): Promise<Forwarder>;
396
+ private bindAll;
397
+ private handleAccept;
398
+ /** Tear down all listeners and any in-flight tunnel sockets. */
399
+ close(): Promise<void>;
400
+ private log;
401
+ }
402
+
279
403
  /**
280
404
  * VM handle — returned from `client.vms.create()` / `client.vms.get()`.
281
405
  * Exposes per-VM operations (exec, fs, power, lifecycle).
@@ -299,6 +423,22 @@ declare class VMFileSystem {
299
423
  }): Promise<void>;
300
424
  /** Upload a tar archive, expanded into the VM at `path`. */
301
425
  tarTo(path: string, tar: Buffer | Readable): Promise<void>;
426
+ /**
427
+ * Open a Server-Sent Events stream of filesystem events from the VM.
428
+ * Yields one `FSWatchEvent` per agent-side event. The stream stays open
429
+ * until the supplied request's `timeout` / `maxEvents` is hit, the daemon
430
+ * tears it down, or the caller breaks out of the loop.
431
+ *
432
+ * Heartbeat SSE comments and named `event:` lines are silently dropped.
433
+ *
434
+ * Example:
435
+ * ```ts
436
+ * for await (const e of vm.fs.watch({ paths: ['/tmp'], recursive: true })) {
437
+ * console.log(e.type, e.path);
438
+ * }
439
+ * ```
440
+ */
441
+ watch(req: FSWatchRequest): AsyncGenerator<FSWatchEvent, void, void>;
302
442
  /** Download `path` from the VM as a tar archive. */
303
443
  tarFrom(path: string): Promise<Buffer>;
304
444
  }
@@ -331,6 +471,20 @@ declare class VM {
331
471
  suspend(): Promise<void>;
332
472
  /** Mac-only on current daemons. Throws `SlicerAPIError 404` on Linux. */
333
473
  restore(): Promise<void>;
474
+ /**
475
+ * Open one or more port forwards from the host to this VM. Each spec follows
476
+ * the same syntax as `slicer vm forward -L`:
477
+ *
478
+ * `127.0.0.1:9000` — listen and forward on the same TCP port
479
+ * `8081:127.0.0.1:8080` — listen on `0.0.0.0:8081`, forward to `127.0.0.1:8080`
480
+ * `0.0.0.0:8080:127.0.0.1:8080` — fully explicit
481
+ * `9000:/var/run/docker.sock` — TCP listen, Unix socket forward
482
+ * `/tmp/docker.sock:/var/run/docker.sock` — Unix-to-Unix
483
+ *
484
+ * Returns a {@link Forwarder} handle. Call `forwarder.close()` to tear down
485
+ * all listeners and any in-flight tunnel sockets.
486
+ */
487
+ forward(specs: string | string[], options?: ForwarderOptions): Promise<Forwarder>;
334
488
  /**
335
489
  * Streaming exec — yields NDJSON frames (`started`, `stdout`, `stderr`, `exit`).
336
490
  * When `req.stdio === 'base64'`, each frame's `data`/`stdout`/`stderr` string
@@ -421,4 +575,4 @@ declare class SlicerClient {
421
575
  getInfo(): Promise<SlicerInfo>;
422
576
  }
423
577
 
424
- export { type AgentHealth, type CreateSecretRequest, type CreateVMOptions, type CreateVMRequest, type CreateVMResponse, type DeleteResponse, type ExecFrame, type ExecRequest, type ExecResult, type ExecResultBinary, type ExecStdio, ExecStdioBase64, ExecStdioText, type FSEntry, type FSMkdirRequest, GiB, type HostGroup, HostGroupsAPI, type ListOptions, MiB, NonRootUser, type Secret, SecretExistsError, SecretsAPI, type ShutdownRequest, SlicerAPIError, SlicerClient, type SlicerClientOptions, type SlicerInfo, type UpdateSecretRequest, VM, VMFileSystem, type VMInfo, type VMInit, type VMLogs, type VMSnapshot, type VMStat, VMsAPI, type WaitOptions, resolveTransport };
578
+ export { type AddressMapping, type AgentHealth, type CreateSecretRequest, type CreateVMOptions, type CreateVMRequest, type CreateVMResponse, type DeleteResponse, type ExecFrame, type ExecRequest, type ExecResult, type ExecResultBinary, type ExecStdio, ExecStdioBase64, ExecStdioText, type FSEntry, type FSMkdirRequest, type FSWatchEvent, type FSWatchEventType, type FSWatchRequest, Forwarder, type ForwarderListener, type ForwarderOptions, GiB, type HostGroup, HostGroupsAPI, type ListOptions, MiB, NonRootUser, type Secret, SecretExistsError, SecretsAPI, type ShutdownRequest, SlicerAPIError, SlicerClient, type SlicerClientOptions, type SlicerInfo, type UpdateSecretRequest, VM, VMFileSystem, type VMInfo, type VMInit, type VMLogs, type VMSnapshot, type VMStat, VMsAPI, type WaitOptions, parseAddressMapping, resolveTransport };