@slicervm/sdk 0.1.4 → 0.1.5

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.cts CHANGED
@@ -131,6 +131,91 @@ interface ExecResultBinary {
131
131
  exitCode: number;
132
132
  error?: string;
133
133
  }
134
+ /**
135
+ * Launch parameters for a background exec. Mirrors the Go SDK's
136
+ * `ExecBackgroundRequest`. The child is detached at launch and survives
137
+ * client disconnect; manage it via `vm.bg.list/info/logs/kill/wait/remove`.
138
+ *
139
+ * `command` + `args` is the always-correct deterministic form (matches the
140
+ * `--cmd` / `--arg` CLI flags). For `$VAR` expansion or shell operators set
141
+ * `shell` to a shell path (e.g. `/bin/bash`) and pass the script as
142
+ * `command`; the agent runs `<shell> -lc "<command>"` in that case.
143
+ */
144
+ interface BgExecRequest {
145
+ command: string;
146
+ args?: string[];
147
+ env?: string[];
148
+ uid?: number;
149
+ gid?: number;
150
+ cwd?: string;
151
+ /**
152
+ * Empty (default): direct exec. Set to a shell path (e.g. `/bin/bash`) for
153
+ * `$VAR` expansion, globs, and shell operators. With a shell, bash auto-
154
+ * `exec`s the last simple command in `-c` scripts so the daemon is the
155
+ * tracked PID for typical cases. Multi-statement scripts that need clean
156
+ * tree should write `exec` themselves.
157
+ */
158
+ shell?: string;
159
+ /** Per-process ring buffer cap in bytes. Zero means server default (1 MiB). */
160
+ ringBytes?: number;
161
+ }
162
+ /** Returned by `vm.bg.exec` on success. */
163
+ interface BgExecResponse {
164
+ execId: string;
165
+ pid: number;
166
+ startedAt: string;
167
+ ringBytes: number;
168
+ }
169
+ /** Status of one background exec — returned by `vm.bg.list` and `vm.bg.info`. */
170
+ interface BgExecInfo {
171
+ execId: string;
172
+ pid: number;
173
+ command: string;
174
+ args?: string[];
175
+ cwd?: string;
176
+ uid?: number;
177
+ startedAt: string;
178
+ running: boolean;
179
+ /** Present once the child has exited. */
180
+ exitCode?: number;
181
+ signal?: string;
182
+ endedAt?: string;
183
+ bytesWritten: number;
184
+ bytesDropped: number;
185
+ /** Next frame id the agent will emit on this exec's log ring. */
186
+ nextId: number;
187
+ ringBytes: number;
188
+ }
189
+ interface BgKillOptions {
190
+ /** Signal name (e.g. `TERM`, `KILL`, `HUP`). Default: `TERM`. */
191
+ signal?: string;
192
+ /** Grace period before the agent escalates to `SIGKILL`. Server default 5000ms. */
193
+ graceMs?: number;
194
+ }
195
+ interface BgKillResponse {
196
+ execId: string;
197
+ pid: number;
198
+ running: boolean;
199
+ signalSent: string;
200
+ }
201
+ interface BgWaitExitResponse {
202
+ execId: string;
203
+ running: boolean;
204
+ exitCode?: number;
205
+ signal?: string;
206
+ endedAt?: string;
207
+ timedOut: boolean;
208
+ }
209
+ interface BgDeleteResponse {
210
+ execId: string;
211
+ reaped: boolean;
212
+ }
213
+ interface BgLogOptions {
214
+ /** Stream live frames after replaying ring contents. */
215
+ follow?: boolean;
216
+ /** Start cursor at frame N. Lower than the live cursor replays history; higher waits (when `follow`). */
217
+ fromId?: number;
218
+ }
134
219
  interface FSEntry {
135
220
  name: string;
136
221
  type: 'file' | 'directory' | 'symlink' | string;
@@ -456,6 +541,7 @@ declare class VM {
456
541
  readonly createdAt?: string;
457
542
  readonly arch?: string;
458
543
  readonly fs: VMFileSystem;
544
+ readonly bg: VMBg;
459
545
  private readonly transport;
460
546
  constructor(transport: TransportClient, init: VMInit);
461
547
  delete(): Promise<void>;
@@ -505,6 +591,57 @@ declare class VM {
505
591
  }): Promise<ExecResultBinary>;
506
592
  execBuffered(req: ExecRequest): Promise<ExecResult>;
507
593
  }
594
+ /**
595
+ * Per-VM background-exec operations. A bg exec is detached at launch (its own
596
+ * session leader), survives client disconnect, and writes stdout/stderr into a
597
+ * per-process ring buffer on the agent. Manage one with the `execId` returned
598
+ * from `exec()` plus `info`, `logs`, `kill`, `wait`, `remove`. The ring stays
599
+ * allocated after the child exits — call `remove()` to free its budget.
600
+ */
601
+ declare class VMBg {
602
+ private readonly transport;
603
+ private readonly hostname;
604
+ constructor(transport: TransportClient, hostname: string);
605
+ /**
606
+ * Launch a long-running process. `command` + `args` is the deterministic
607
+ * exec form (no shell). Set `shell: '/bin/bash'` (or similar) to opt in
608
+ * to shell semantics — `$VAR` expansion, globs, `&&`/`||`, etc.
609
+ */
610
+ exec(req: BgExecRequest): Promise<BgExecResponse>;
611
+ /** All background execs the agent currently tracks (running + exited-not-reaped). */
612
+ list(): Promise<BgExecInfo[]>;
613
+ /** Latest status snapshot for one bg exec. Throws 404 if reaped or never existed. */
614
+ info(execId: string): Promise<BgExecInfo>;
615
+ /**
616
+ * NDJSON log stream. Yields one frame per log line — `started`, `stdout`,
617
+ * `stderr`, `exit`, plus optional `gap` frames if the ring evicted history
618
+ * before the requested cursor. Frames carry `data` base64-encoded; the SDK
619
+ * also populates `dataBytes` / `stdoutBytes` / `stderrBytes` Buffers.
620
+ *
621
+ * `follow: false` (default) replays from the cursor and ends when the ring
622
+ * is drained. `follow: true` keeps the stream open until the child exits or
623
+ * the caller breaks out.
624
+ */
625
+ logs(execId: string, opts?: BgLogOptions): AsyncGenerator<ExecFrame, void, void>;
626
+ /**
627
+ * Signal a running bg exec. Default: SIGTERM with a 5 s grace period before
628
+ * the agent escalates to SIGKILL. No-op (running=false) if the child has
629
+ * already exited.
630
+ */
631
+ kill(execId: string, opts?: BgKillOptions): Promise<BgKillResponse>;
632
+ /**
633
+ * Long-poll until the child exits or `timeoutSec` elapses. Returns
634
+ * `timedOut: true` if the deadline hit. Server default for `timeoutSec=0`
635
+ * is 30 s.
636
+ */
637
+ wait(execId: string, timeoutSec?: number): Promise<BgWaitExitResponse>;
638
+ /**
639
+ * Reap a bg exec's ring buffer + registry entry. Does NOT kill a running
640
+ * process — pair with `kill()` for "stop and clean up". After remove,
641
+ * info/logs/kill/wait return 410 Gone.
642
+ */
643
+ remove(execId: string): Promise<BgDeleteResponse>;
644
+ }
508
645
 
509
646
  /**
510
647
  * Top-level namespaces on SlicerClient: hostGroups, vms, secrets.
@@ -575,4 +712,4 @@ declare class SlicerClient {
575
712
  getInfo(): Promise<SlicerInfo>;
576
713
  }
577
714
 
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 };
715
+ export { type AddressMapping, type AgentHealth, type BgDeleteResponse, type BgExecInfo, type BgExecRequest, type BgExecResponse, type BgKillOptions, type BgKillResponse, type BgLogOptions, type BgWaitExitResponse, 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, VMBg, VMFileSystem, type VMInfo, type VMInit, type VMLogs, type VMSnapshot, type VMStat, VMsAPI, type WaitOptions, parseAddressMapping, resolveTransport };
package/dist/index.d.ts CHANGED
@@ -131,6 +131,91 @@ interface ExecResultBinary {
131
131
  exitCode: number;
132
132
  error?: string;
133
133
  }
134
+ /**
135
+ * Launch parameters for a background exec. Mirrors the Go SDK's
136
+ * `ExecBackgroundRequest`. The child is detached at launch and survives
137
+ * client disconnect; manage it via `vm.bg.list/info/logs/kill/wait/remove`.
138
+ *
139
+ * `command` + `args` is the always-correct deterministic form (matches the
140
+ * `--cmd` / `--arg` CLI flags). For `$VAR` expansion or shell operators set
141
+ * `shell` to a shell path (e.g. `/bin/bash`) and pass the script as
142
+ * `command`; the agent runs `<shell> -lc "<command>"` in that case.
143
+ */
144
+ interface BgExecRequest {
145
+ command: string;
146
+ args?: string[];
147
+ env?: string[];
148
+ uid?: number;
149
+ gid?: number;
150
+ cwd?: string;
151
+ /**
152
+ * Empty (default): direct exec. Set to a shell path (e.g. `/bin/bash`) for
153
+ * `$VAR` expansion, globs, and shell operators. With a shell, bash auto-
154
+ * `exec`s the last simple command in `-c` scripts so the daemon is the
155
+ * tracked PID for typical cases. Multi-statement scripts that need clean
156
+ * tree should write `exec` themselves.
157
+ */
158
+ shell?: string;
159
+ /** Per-process ring buffer cap in bytes. Zero means server default (1 MiB). */
160
+ ringBytes?: number;
161
+ }
162
+ /** Returned by `vm.bg.exec` on success. */
163
+ interface BgExecResponse {
164
+ execId: string;
165
+ pid: number;
166
+ startedAt: string;
167
+ ringBytes: number;
168
+ }
169
+ /** Status of one background exec — returned by `vm.bg.list` and `vm.bg.info`. */
170
+ interface BgExecInfo {
171
+ execId: string;
172
+ pid: number;
173
+ command: string;
174
+ args?: string[];
175
+ cwd?: string;
176
+ uid?: number;
177
+ startedAt: string;
178
+ running: boolean;
179
+ /** Present once the child has exited. */
180
+ exitCode?: number;
181
+ signal?: string;
182
+ endedAt?: string;
183
+ bytesWritten: number;
184
+ bytesDropped: number;
185
+ /** Next frame id the agent will emit on this exec's log ring. */
186
+ nextId: number;
187
+ ringBytes: number;
188
+ }
189
+ interface BgKillOptions {
190
+ /** Signal name (e.g. `TERM`, `KILL`, `HUP`). Default: `TERM`. */
191
+ signal?: string;
192
+ /** Grace period before the agent escalates to `SIGKILL`. Server default 5000ms. */
193
+ graceMs?: number;
194
+ }
195
+ interface BgKillResponse {
196
+ execId: string;
197
+ pid: number;
198
+ running: boolean;
199
+ signalSent: string;
200
+ }
201
+ interface BgWaitExitResponse {
202
+ execId: string;
203
+ running: boolean;
204
+ exitCode?: number;
205
+ signal?: string;
206
+ endedAt?: string;
207
+ timedOut: boolean;
208
+ }
209
+ interface BgDeleteResponse {
210
+ execId: string;
211
+ reaped: boolean;
212
+ }
213
+ interface BgLogOptions {
214
+ /** Stream live frames after replaying ring contents. */
215
+ follow?: boolean;
216
+ /** Start cursor at frame N. Lower than the live cursor replays history; higher waits (when `follow`). */
217
+ fromId?: number;
218
+ }
134
219
  interface FSEntry {
135
220
  name: string;
136
221
  type: 'file' | 'directory' | 'symlink' | string;
@@ -456,6 +541,7 @@ declare class VM {
456
541
  readonly createdAt?: string;
457
542
  readonly arch?: string;
458
543
  readonly fs: VMFileSystem;
544
+ readonly bg: VMBg;
459
545
  private readonly transport;
460
546
  constructor(transport: TransportClient, init: VMInit);
461
547
  delete(): Promise<void>;
@@ -505,6 +591,57 @@ declare class VM {
505
591
  }): Promise<ExecResultBinary>;
506
592
  execBuffered(req: ExecRequest): Promise<ExecResult>;
507
593
  }
594
+ /**
595
+ * Per-VM background-exec operations. A bg exec is detached at launch (its own
596
+ * session leader), survives client disconnect, and writes stdout/stderr into a
597
+ * per-process ring buffer on the agent. Manage one with the `execId` returned
598
+ * from `exec()` plus `info`, `logs`, `kill`, `wait`, `remove`. The ring stays
599
+ * allocated after the child exits — call `remove()` to free its budget.
600
+ */
601
+ declare class VMBg {
602
+ private readonly transport;
603
+ private readonly hostname;
604
+ constructor(transport: TransportClient, hostname: string);
605
+ /**
606
+ * Launch a long-running process. `command` + `args` is the deterministic
607
+ * exec form (no shell). Set `shell: '/bin/bash'` (or similar) to opt in
608
+ * to shell semantics — `$VAR` expansion, globs, `&&`/`||`, etc.
609
+ */
610
+ exec(req: BgExecRequest): Promise<BgExecResponse>;
611
+ /** All background execs the agent currently tracks (running + exited-not-reaped). */
612
+ list(): Promise<BgExecInfo[]>;
613
+ /** Latest status snapshot for one bg exec. Throws 404 if reaped or never existed. */
614
+ info(execId: string): Promise<BgExecInfo>;
615
+ /**
616
+ * NDJSON log stream. Yields one frame per log line — `started`, `stdout`,
617
+ * `stderr`, `exit`, plus optional `gap` frames if the ring evicted history
618
+ * before the requested cursor. Frames carry `data` base64-encoded; the SDK
619
+ * also populates `dataBytes` / `stdoutBytes` / `stderrBytes` Buffers.
620
+ *
621
+ * `follow: false` (default) replays from the cursor and ends when the ring
622
+ * is drained. `follow: true` keeps the stream open until the child exits or
623
+ * the caller breaks out.
624
+ */
625
+ logs(execId: string, opts?: BgLogOptions): AsyncGenerator<ExecFrame, void, void>;
626
+ /**
627
+ * Signal a running bg exec. Default: SIGTERM with a 5 s grace period before
628
+ * the agent escalates to SIGKILL. No-op (running=false) if the child has
629
+ * already exited.
630
+ */
631
+ kill(execId: string, opts?: BgKillOptions): Promise<BgKillResponse>;
632
+ /**
633
+ * Long-poll until the child exits or `timeoutSec` elapses. Returns
634
+ * `timedOut: true` if the deadline hit. Server default for `timeoutSec=0`
635
+ * is 30 s.
636
+ */
637
+ wait(execId: string, timeoutSec?: number): Promise<BgWaitExitResponse>;
638
+ /**
639
+ * Reap a bg exec's ring buffer + registry entry. Does NOT kill a running
640
+ * process — pair with `kill()` for "stop and clean up". After remove,
641
+ * info/logs/kill/wait return 410 Gone.
642
+ */
643
+ remove(execId: string): Promise<BgDeleteResponse>;
644
+ }
508
645
 
509
646
  /**
510
647
  * Top-level namespaces on SlicerClient: hostGroups, vms, secrets.
@@ -575,4 +712,4 @@ declare class SlicerClient {
575
712
  getInfo(): Promise<SlicerInfo>;
576
713
  }
577
714
 
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 };
715
+ export { type AddressMapping, type AgentHealth, type BgDeleteResponse, type BgExecInfo, type BgExecRequest, type BgExecResponse, type BgKillOptions, type BgKillResponse, type BgLogOptions, type BgWaitExitResponse, 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, VMBg, VMFileSystem, type VMInfo, type VMInit, type VMLogs, type VMSnapshot, type VMStat, VMsAPI, type WaitOptions, parseAddressMapping, resolveTransport };
package/dist/index.js CHANGED
@@ -734,6 +734,7 @@ var VM = class {
734
734
  createdAt;
735
735
  arch;
736
736
  fs;
737
+ bg;
737
738
  transport;
738
739
  constructor(transport, init) {
739
740
  this.transport = transport;
@@ -743,6 +744,7 @@ var VM = class {
743
744
  if (init.createdAt !== void 0) this.createdAt = init.createdAt;
744
745
  if (init.arch !== void 0) this.arch = init.arch;
745
746
  this.fs = new VMFileSystem(transport, this.hostname);
747
+ this.bg = new VMBg(transport, this.hostname);
746
748
  }
747
749
  // --- lifecycle --------------------------------------------------------
748
750
  async delete() {
@@ -944,6 +946,169 @@ function sleep(ms) {
944
946
  function errMsg(e) {
945
947
  return e instanceof Error ? e.message : String(e);
946
948
  }
949
+ var VMBg = class {
950
+ constructor(transport, hostname) {
951
+ this.transport = transport;
952
+ this.hostname = hostname;
953
+ }
954
+ transport;
955
+ hostname;
956
+ /**
957
+ * Launch a long-running process. `command` + `args` is the deterministic
958
+ * exec form (no shell). Set `shell: '/bin/bash'` (or similar) to opt in
959
+ * to shell semantics — `$VAR` expansion, globs, `&&`/`||`, etc.
960
+ */
961
+ async exec(req) {
962
+ if (!req.command) throw new Error("vm.bg.exec: command is required");
963
+ const q = new URLSearchParams();
964
+ q.set("background", "true");
965
+ q.set("cmd", req.command);
966
+ for (const a of req.args ?? []) q.append("args", a);
967
+ for (const e of req.env ?? []) q.append("env", e);
968
+ if (req.uid !== void 0 && req.uid !== 0) q.set("uid", String(req.uid));
969
+ if (req.gid !== void 0 && req.gid !== 0) q.set("gid", String(req.gid));
970
+ if (req.shell) q.set("shell", req.shell);
971
+ if (req.cwd) q.set("cwd", req.cwd);
972
+ if (req.ringBytes !== void 0 && req.ringBytes > 0) {
973
+ q.set("ring_bytes", String(req.ringBytes));
974
+ }
975
+ q.set("stdio", "base64");
976
+ const path3 = `/vm/${encodeURIComponent(this.hostname)}/exec?${q.toString()}`;
977
+ const wire = await this.transport.request("POST", path3);
978
+ return bgExecResponseFromWire(wire);
979
+ }
980
+ /** All background execs the agent currently tracks (running + exited-not-reaped). */
981
+ async list() {
982
+ const wire = await this.transport.request(
983
+ "GET",
984
+ `/vm/${encodeURIComponent(this.hostname)}/exec`
985
+ );
986
+ return (wire ?? []).map(bgExecInfoFromWire);
987
+ }
988
+ /** Latest status snapshot for one bg exec. Throws 404 if reaped or never existed. */
989
+ async info(execId) {
990
+ const wire = await this.transport.request(
991
+ "GET",
992
+ `/vm/${encodeURIComponent(this.hostname)}/exec/${encodeURIComponent(execId)}`
993
+ );
994
+ return bgExecInfoFromWire(wire);
995
+ }
996
+ /**
997
+ * NDJSON log stream. Yields one frame per log line — `started`, `stdout`,
998
+ * `stderr`, `exit`, plus optional `gap` frames if the ring evicted history
999
+ * before the requested cursor. Frames carry `data` base64-encoded; the SDK
1000
+ * also populates `dataBytes` / `stdoutBytes` / `stderrBytes` Buffers.
1001
+ *
1002
+ * `follow: false` (default) replays from the cursor and ends when the ring
1003
+ * is drained. `follow: true` keeps the stream open until the child exits or
1004
+ * the caller breaks out.
1005
+ */
1006
+ async *logs(execId, opts = {}) {
1007
+ const q = new URLSearchParams();
1008
+ if (opts.follow) q.set("follow", "true");
1009
+ if (opts.fromId !== void 0 && opts.fromId > 0) q.set("from_id", String(opts.fromId));
1010
+ const path3 = `/vm/${encodeURIComponent(this.hostname)}/exec/${encodeURIComponent(execId)}/logs` + (q.toString() ? `?${q.toString()}` : "");
1011
+ for await (const raw of this.transport.requestNDJSON("GET", path3)) {
1012
+ const frame = normalizeExecFrame(raw);
1013
+ if (frame.encoding === "base64") {
1014
+ if (frame.data) frame.dataBytes = Buffer.from(frame.data, "base64");
1015
+ if (frame.stdout) frame.stdoutBytes = Buffer.from(frame.stdout, "base64");
1016
+ if (frame.stderr) frame.stderrBytes = Buffer.from(frame.stderr, "base64");
1017
+ }
1018
+ yield frame;
1019
+ }
1020
+ }
1021
+ /**
1022
+ * Signal a running bg exec. Default: SIGTERM with a 5 s grace period before
1023
+ * the agent escalates to SIGKILL. No-op (running=false) if the child has
1024
+ * already exited.
1025
+ */
1026
+ async kill(execId, opts = {}) {
1027
+ const body = {};
1028
+ if (opts.signal) body.signal = opts.signal;
1029
+ if (opts.graceMs !== void 0) body.grace_ms = opts.graceMs;
1030
+ const wire = await this.transport.request(
1031
+ "POST",
1032
+ `/vm/${encodeURIComponent(this.hostname)}/exec/${encodeURIComponent(execId)}/kill`,
1033
+ body
1034
+ );
1035
+ return bgKillResponseFromWire(wire);
1036
+ }
1037
+ /**
1038
+ * Long-poll until the child exits or `timeoutSec` elapses. Returns
1039
+ * `timedOut: true` if the deadline hit. Server default for `timeoutSec=0`
1040
+ * is 30 s.
1041
+ */
1042
+ async wait(execId, timeoutSec = 0) {
1043
+ const q = new URLSearchParams();
1044
+ if (timeoutSec > 0) q.set("timeout", String(timeoutSec));
1045
+ const path3 = `/vm/${encodeURIComponent(this.hostname)}/exec/${encodeURIComponent(execId)}/wait-exit` + (q.toString() ? `?${q.toString()}` : "");
1046
+ const wire = await this.transport.request("GET", path3);
1047
+ return bgWaitExitFromWire(wire);
1048
+ }
1049
+ /**
1050
+ * Reap a bg exec's ring buffer + registry entry. Does NOT kill a running
1051
+ * process — pair with `kill()` for "stop and clean up". After remove,
1052
+ * info/logs/kill/wait return 410 Gone.
1053
+ */
1054
+ async remove(execId) {
1055
+ const wire = await this.transport.request(
1056
+ "DELETE",
1057
+ `/vm/${encodeURIComponent(this.hostname)}/exec/${encodeURIComponent(execId)}`
1058
+ );
1059
+ return bgDeleteFromWire(wire);
1060
+ }
1061
+ };
1062
+ function bgExecResponseFromWire(w) {
1063
+ return {
1064
+ execId: w.exec_id,
1065
+ pid: w.pid,
1066
+ startedAt: w.started_at,
1067
+ ringBytes: w.ring_bytes
1068
+ };
1069
+ }
1070
+ function bgExecInfoFromWire(w) {
1071
+ const out = {
1072
+ execId: w.exec_id,
1073
+ pid: w.pid,
1074
+ command: w.command,
1075
+ startedAt: w.started_at,
1076
+ running: w.running,
1077
+ bytesWritten: w.bytes_written,
1078
+ bytesDropped: w.bytes_dropped,
1079
+ nextId: w.next_id,
1080
+ ringBytes: w.ring_bytes
1081
+ };
1082
+ if (w.args !== void 0) out.args = w.args;
1083
+ if (w.cwd !== void 0) out.cwd = w.cwd;
1084
+ if (w.uid !== void 0) out.uid = w.uid;
1085
+ if (w.exit_code !== void 0) out.exitCode = w.exit_code;
1086
+ if (w.signal !== void 0) out.signal = w.signal;
1087
+ if (w.ended_at !== void 0) out.endedAt = w.ended_at;
1088
+ return out;
1089
+ }
1090
+ function bgKillResponseFromWire(w) {
1091
+ return {
1092
+ execId: w.exec_id,
1093
+ pid: w.pid,
1094
+ running: w.running,
1095
+ signalSent: w.signal_sent
1096
+ };
1097
+ }
1098
+ function bgWaitExitFromWire(w) {
1099
+ const out = {
1100
+ execId: w.exec_id,
1101
+ running: w.running,
1102
+ timedOut: w.timed_out
1103
+ };
1104
+ if (w.exit_code !== void 0) out.exitCode = w.exit_code;
1105
+ if (w.signal !== void 0) out.signal = w.signal;
1106
+ if (w.ended_at !== void 0) out.endedAt = w.ended_at;
1107
+ return out;
1108
+ }
1109
+ function bgDeleteFromWire(w) {
1110
+ return { execId: w.exec_id, reaped: w.reaped };
1111
+ }
947
1112
 
948
1113
  // src/namespaces.ts
949
1114
  var HostGroupsAPI = class {
@@ -1113,6 +1278,6 @@ var SlicerClient = class _SlicerClient {
1113
1278
  }
1114
1279
  };
1115
1280
 
1116
- export { ExecStdioBase64, ExecStdioText, Forwarder, GiB, HostGroupsAPI, MiB, NonRootUser, SecretExistsError, SecretsAPI, SlicerAPIError, SlicerClient, VM, VMFileSystem, VMsAPI, parseAddressMapping, resolveTransport };
1281
+ export { ExecStdioBase64, ExecStdioText, Forwarder, GiB, HostGroupsAPI, MiB, NonRootUser, SecretExistsError, SecretsAPI, SlicerAPIError, SlicerClient, VM, VMBg, VMFileSystem, VMsAPI, parseAddressMapping, resolveTransport };
1117
1282
  //# sourceMappingURL=index.js.map
1118
1283
  //# sourceMappingURL=index.js.map