@slicervm/sdk 0.1.7 → 0.1.9

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.js CHANGED
@@ -273,7 +273,72 @@ function agentHealthFromWire(w) {
273
273
  ...w.agent_uptime !== void 0 && { agentUptime: w.agent_uptime },
274
274
  ...w.agent_version !== void 0 && { agentVersion: w.agent_version },
275
275
  ...w.system_uptime !== void 0 && { systemUptime: w.system_uptime },
276
- ...w.userdata_ran !== void 0 && { userdataRan: w.userdata_ran }
276
+ ...w.userdata_ran !== void 0 && { userdataRan: w.userdata_ran },
277
+ ...w.userdata_exit_code !== void 0 && { userdataExitCode: w.userdata_exit_code }
278
+ };
279
+ }
280
+ function vmCommitFromWire(w) {
281
+ return {
282
+ hostname: w.hostname,
283
+ commitId: w.commit_id,
284
+ status: w.status,
285
+ ...w.parent_status !== void 0 && { parentStatus: w.parent_status },
286
+ mode: w.mode ?? "",
287
+ ...w.tags !== void 0 && { tags: w.tags },
288
+ ...w.labels !== void 0 && { labels: w.labels },
289
+ ...w.cache_key !== void 0 && { cacheKey: w.cache_key }
290
+ };
291
+ }
292
+ function vmCommitInfoFromWire(w) {
293
+ return {
294
+ commitId: w.commit_id,
295
+ sourceHostname: w.source_hostname,
296
+ sourceHostGroup: w.source_host_group,
297
+ createdAt: w.created_at,
298
+ mode: w.mode,
299
+ ...w.tags !== void 0 && { tags: w.tags },
300
+ ...w.labels !== void 0 && { labels: w.labels },
301
+ ...w.cache_key !== void 0 && { cacheKey: w.cache_key }
302
+ };
303
+ }
304
+ function vmCommitDeleteFromWire(w) {
305
+ return { commitId: w.commit_id, status: w.status };
306
+ }
307
+ function vmForkFromWire(w) {
308
+ return {
309
+ hostname: w.hostname,
310
+ sourceHostname: w.source_hostname,
311
+ ...w.commit_id !== void 0 && { commitId: w.commit_id },
312
+ status: w.status,
313
+ ...w.parent_status !== void 0 && { parentStatus: w.parent_status },
314
+ ...w.child_status !== void 0 && { childStatus: w.child_status },
315
+ mode: w.mode ?? "",
316
+ ...w.persistent !== void 0 && { persistent: w.persistent }
317
+ };
318
+ }
319
+ function vmDescriptionFromWire(w) {
320
+ return {
321
+ hostname: w.hostname,
322
+ ...w.hostgroup !== void 0 && { hostGroup: w.hostgroup },
323
+ ...w.ip !== void 0 && { ip: w.ip },
324
+ ...w.ram_bytes !== void 0 && { ramBytes: w.ram_bytes },
325
+ ...w.cpus !== void 0 && { cpus: w.cpus },
326
+ ...w.created_at !== void 0 && { createdAt: w.created_at },
327
+ ...w.arch !== void 0 && { arch: w.arch },
328
+ ...w.tags !== void 0 && { tags: w.tags },
329
+ ...w.status !== void 0 && { status: w.status },
330
+ ...w.persistent !== void 0 && { persistent: w.persistent },
331
+ ...w.storage !== void 0 && { storage: w.storage },
332
+ ...w.image !== void 0 && { image: w.image },
333
+ ...w.commit_id !== void 0 && { commitId: w.commit_id },
334
+ ...w.parent_commit_id !== void 0 && { parentCommitId: w.parent_commit_id },
335
+ network: {
336
+ ...w.network.mode !== void 0 && { mode: w.network.mode },
337
+ ...w.network.policy_source !== void 0 && { policySource: w.network.policy_source },
338
+ hostGroup: w.network.host_group,
339
+ ...w.network.override !== void 0 && { override: w.network.override },
340
+ effective: w.network.effective
341
+ }
277
342
  };
278
343
  }
279
344
  function fsEntryFromWire(w) {
@@ -298,6 +363,31 @@ function secretFromWire(w) {
298
363
  ...w.modified_at !== void 0 && { modifiedAt: w.modified_at }
299
364
  };
300
365
  }
366
+
367
+ // src/fork.ts
368
+ function buildForkRequest(opts) {
369
+ const wait = opts.wait ?? "agent";
370
+ if (wait !== "agent" && wait !== "none") {
371
+ throw new Error(`invalid fork wait mode ${JSON.stringify(wait)}`);
372
+ }
373
+ const query = new URLSearchParams({ wait });
374
+ if (opts.waitTimeoutSec !== void 0 && opts.waitTimeoutSec > 0) {
375
+ query.set("timeout", `${opts.waitTimeoutSec}s`);
376
+ }
377
+ const body = {};
378
+ if (opts.network !== void 0) body.network = opts.network;
379
+ if (opts.tags !== void 0) body.tags = opts.tags;
380
+ if (opts.tagMode !== void 0) body.tag_mode = opts.tagMode;
381
+ if (opts.secrets !== void 0) body.secrets = opts.secrets;
382
+ if (opts.persistent !== void 0) body.persistent = opts.persistent;
383
+ if (opts.fixups !== void 0) body.fixups = opts.fixups;
384
+ if (opts.vcpu !== void 0) body.vcpu = opts.vcpu;
385
+ if (opts.ramBytes !== void 0) body.ram_bytes = opts.ramBytes;
386
+ return {
387
+ query: query.toString(),
388
+ ...Object.keys(body).length > 0 && { body }
389
+ };
390
+ }
301
391
  function looksLikeUnixSocketPath(s) {
302
392
  if (!s) return false;
303
393
  return s.startsWith("/") || s.startsWith("./") || s.startsWith("../") || s.includes("/");
@@ -728,6 +818,48 @@ var VMFileSystem = class {
728
818
  );
729
819
  }
730
820
  };
821
+ var CommittedVM = class {
822
+ constructor(transport, hostGroup, response) {
823
+ this.transport = transport;
824
+ this.hostname = response.hostname;
825
+ this.hostGroup = hostGroup;
826
+ this.commitId = response.commitId;
827
+ this.status = response.status;
828
+ if (response.parentStatus !== void 0) this.parentStatus = response.parentStatus;
829
+ this.mode = response.mode;
830
+ if (response.tags !== void 0) this.tags = response.tags;
831
+ if (response.labels !== void 0) this.labels = response.labels;
832
+ if (response.cacheKey !== void 0) this.cacheKey = response.cacheKey;
833
+ }
834
+ transport;
835
+ hostname;
836
+ hostGroup;
837
+ commitId;
838
+ status;
839
+ parentStatus;
840
+ mode;
841
+ tags;
842
+ labels;
843
+ cacheKey;
844
+ async fork(opts = {}) {
845
+ const res = await forkPath(
846
+ this.transport,
847
+ this.commitId,
848
+ opts
849
+ );
850
+ return new VM(this.transport, {
851
+ hostname: res.hostname,
852
+ hostGroup: this.hostGroup
853
+ });
854
+ }
855
+ async forkRaw(opts = {}) {
856
+ return forkPath(
857
+ this.transport,
858
+ this.commitId,
859
+ opts
860
+ );
861
+ }
862
+ };
731
863
  var VM = class {
732
864
  hostname;
733
865
  hostGroup;
@@ -767,6 +899,14 @@ var VM = class {
767
899
  async logs() {
768
900
  return this.transport.request("GET", `/vm/${encodeURIComponent(this.hostname)}/logs`);
769
901
  }
902
+ /** Return configuration, fork lineage, and effective network policy. */
903
+ async describe() {
904
+ const wire = await this.transport.request(
905
+ "GET",
906
+ `/vm/${encodeURIComponent(this.hostname)}`
907
+ );
908
+ return vmDescriptionFromWire(wire);
909
+ }
770
910
  async waitForAgent(opts = {}) {
771
911
  const timeoutMs = opts.timeoutMs ?? 12e4;
772
912
  const intervalMs = opts.intervalMs ?? 500;
@@ -793,10 +933,15 @@ var VM = class {
793
933
  while (Date.now() < deadline) {
794
934
  try {
795
935
  last = await this.health();
796
- if (last.userdataRan) return last;
797
936
  } catch (err) {
798
937
  lastErr = err;
799
938
  }
939
+ if (last?.userdataRan) {
940
+ if (last.userdataExitCode !== void 0 && last.userdataExitCode !== 0) {
941
+ throw new Error(`userdata failed with exit code ${last.userdataExitCode}`);
942
+ }
943
+ return last;
944
+ }
800
945
  await sleep(intervalMs);
801
946
  }
802
947
  throw new Error(
@@ -828,6 +973,25 @@ var VM = class {
828
973
  async restore() {
829
974
  await this.transport.request("POST", `/vm/${encodeURIComponent(this.hostname)}/restore`);
830
975
  }
976
+ /**
977
+ * Commit a stopped persistent VM disk into an immutable parent.
978
+ */
979
+ async commit(opts = {}) {
980
+ const cacheKey = opts.cacheKey?.trim();
981
+ const tags = opts.tags && opts.tags.length > 0 ? opts.tags : void 0;
982
+ const labels = opts.labels && Object.keys(opts.labels).length > 0 ? opts.labels : void 0;
983
+ const body = tags !== void 0 || labels !== void 0 || cacheKey ? {
984
+ ...tags !== void 0 && { tags },
985
+ ...labels !== void 0 && { labels },
986
+ ...cacheKey && { cache_key: cacheKey }
987
+ } : void 0;
988
+ const wire = await this.transport.request(
989
+ "POST",
990
+ `/vm/${encodeURIComponent(this.hostname)}/commit`,
991
+ body
992
+ );
993
+ return new CommittedVM(this.transport, this.hostGroup, vmCommitFromWire(wire));
994
+ }
831
995
  // --- port forwarding ---------------------------------------------------
832
996
  /**
833
997
  * Open one or more port forwards from the host to this VM. Each spec follows
@@ -947,6 +1111,23 @@ function sleep(ms) {
947
1111
  function errMsg(e) {
948
1112
  return e instanceof Error ? e.message : String(e);
949
1113
  }
1114
+ async function forkPath(transport, commitId, opts) {
1115
+ const id = validateCommitId(commitId);
1116
+ const request = buildForkRequest(opts);
1117
+ const wire = await transport.request(
1118
+ "POST",
1119
+ `/vm/commits/${encodeURIComponent(id)}/fork?${request.query}`,
1120
+ request.body
1121
+ );
1122
+ return vmForkFromWire(wire);
1123
+ }
1124
+ function validateCommitId(commitId) {
1125
+ const value = commitId.trim();
1126
+ if (!value || value === "." || value === ".." || value.includes("..") || value.includes("/") || value.includes("\\") || value.includes("\0")) {
1127
+ throw new Error(`invalid commit ID ${JSON.stringify(value)}`);
1128
+ }
1129
+ return value;
1130
+ }
950
1131
  var VMBg = class {
951
1132
  constructor(transport, hostname) {
952
1133
  this.transport = transport;
@@ -1205,6 +1386,47 @@ var VMsAPI = class {
1205
1386
  return createVMResFromWire(wire);
1206
1387
  }
1207
1388
  };
1389
+ var CommitsAPI = class {
1390
+ constructor(transport) {
1391
+ this.transport = transport;
1392
+ }
1393
+ transport;
1394
+ async list(opts = {}) {
1395
+ const qs = new URLSearchParams();
1396
+ for (const tag of opts.tags ?? []) {
1397
+ const value = tag.trim();
1398
+ if (value) qs.append("tag", value);
1399
+ }
1400
+ const cacheKey = opts.cacheKey?.trim();
1401
+ const source = opts.source?.trim();
1402
+ const mode = opts.mode?.trim();
1403
+ if (cacheKey) qs.set("cache_key", cacheKey);
1404
+ if (source) qs.set("source", source);
1405
+ if (mode) qs.set("mode", mode);
1406
+ const encoded = qs.toString();
1407
+ const query = encoded ? `?${encoded}` : "";
1408
+ const wire = await this.transport.request("GET", `/vm/commits${query}`);
1409
+ return (wire ?? []).map(vmCommitInfoFromWire);
1410
+ }
1411
+ async delete(commitId) {
1412
+ const id = validateCommitId2(commitId);
1413
+ const wire = await this.transport.request(
1414
+ "DELETE",
1415
+ `/vm/commits/${encodeURIComponent(id)}`
1416
+ );
1417
+ return vmCommitDeleteFromWire(wire);
1418
+ }
1419
+ async fork(commitId, opts = {}) {
1420
+ const id = validateCommitId2(commitId);
1421
+ const request = buildForkRequest(opts);
1422
+ const wire = await this.transport.request(
1423
+ "POST",
1424
+ `/vm/commits/${encodeURIComponent(id)}/fork?${request.query}`,
1425
+ request.body
1426
+ );
1427
+ return vmForkFromWire(wire);
1428
+ }
1429
+ };
1208
1430
  var SecretsAPI = class {
1209
1431
  constructor(transport) {
1210
1432
  this.transport = transport;
@@ -1251,10 +1473,18 @@ function buildListQuery(opts) {
1251
1473
  const s = qs.toString();
1252
1474
  return s ? `?${s}` : "";
1253
1475
  }
1476
+ function validateCommitId2(commitId) {
1477
+ const value = commitId.trim();
1478
+ if (!value || value === "." || value === ".." || value.includes("..") || value.includes("/") || value.includes("\\") || value.includes("\0")) {
1479
+ throw new Error(`invalid commit ID ${JSON.stringify(value)}`);
1480
+ }
1481
+ return value;
1482
+ }
1254
1483
 
1255
1484
  // src/proxy.ts
1256
1485
  var ProxySecretBearer = "bearer";
1257
1486
  var ProxySecretBasic = "basic";
1487
+ var ProxySecretOAuthClientCredentials = "oauth-client-creds";
1258
1488
  function clientFromWire(w) {
1259
1489
  return { name: w.name, createdAt: w.created_at };
1260
1490
  }
@@ -1411,12 +1641,14 @@ var SlicerClient = class _SlicerClient {
1411
1641
  transport;
1412
1642
  hostGroups;
1413
1643
  vms;
1644
+ commits;
1414
1645
  secrets;
1415
1646
  proxy;
1416
1647
  constructor(opts) {
1417
1648
  this.transport = new TransportClient(opts);
1418
1649
  this.hostGroups = new HostGroupsAPI(this.transport);
1419
1650
  this.vms = new VMsAPI(this.transport);
1651
+ this.commits = new CommitsAPI(this.transport);
1420
1652
  this.secrets = new SecretsAPI(this.transport);
1421
1653
  this.proxy = new ProxyAPI(this.transport);
1422
1654
  }
@@ -1575,6 +1807,6 @@ var SlicerShellSession = class {
1575
1807
  }
1576
1808
  };
1577
1809
 
1578
- export { ExecStdioBase64, ExecStdioText, FRAME_TYPE_DATA, FRAME_TYPE_HEARTBEAT, FRAME_TYPE_SESSION_CLOSE, FRAME_TYPE_SHUTDOWN, FRAME_TYPE_WINDOW_SIZE, Forwarder, GiB, HostGroupsAPI, MiB, NonRootUser, ProxyAPI, ProxyAllowsAPI, ProxyClientsAPI, ProxySecretBasic, ProxySecretBearer, ProxySecretsAPI, SecretExistsError, SecretsAPI, SlicerAPIError, SlicerClient, SlicerShellSession, VM, VMBg, VMFileSystem, VMsAPI, encodeFrame, parseAddressMapping, parseFrame, resolveTransport };
1810
+ export { CommitsAPI, CommittedVM, ExecStdioBase64, ExecStdioText, FRAME_TYPE_DATA, FRAME_TYPE_HEARTBEAT, FRAME_TYPE_SESSION_CLOSE, FRAME_TYPE_SHUTDOWN, FRAME_TYPE_WINDOW_SIZE, Forwarder, GiB, HostGroupsAPI, MiB, NonRootUser, ProxyAPI, ProxyAllowsAPI, ProxyClientsAPI, ProxySecretBasic, ProxySecretBearer, ProxySecretOAuthClientCredentials, ProxySecretsAPI, SecretExistsError, SecretsAPI, SlicerAPIError, SlicerClient, SlicerShellSession, VM, VMBg, VMFileSystem, VMsAPI, encodeFrame, parseAddressMapping, parseFrame, resolveTransport };
1579
1811
  //# sourceMappingURL=index.js.map
1580
1812
  //# sourceMappingURL=index.js.map