@slicervm/sdk 0.1.8 → 0.1.10

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
@@ -36,8 +36,10 @@ await vm.delete();
36
36
  ## Cold forks
37
37
 
38
38
  A stopped persistent VM can be committed as an immutable disk parent, then
39
- forked into cold-booted children. Fork calls always wait until the child agent
40
- has finalised its guest identity.
39
+ forked into cold-booted children. Fork calls wait for agent readiness and guest
40
+ identity finalisation by default. `wait: 'none'` acknowledges launch only; if
41
+ requested asynchronous finalisation fails, the daemon removes the child rather
42
+ than expose cloned identity or secrets with partially applied policy.
41
43
 
42
44
  ```ts
43
45
  await vm.shutdown();
@@ -47,9 +49,15 @@ const parent = await vm.commit({
47
49
  });
48
50
 
49
51
  const child = await parent.fork({
52
+ wait: 'agent',
50
53
  waitTimeoutSec: 120,
54
+ persistent: false,
55
+ vcpu: 1,
56
+ ramBytes: 512 * 1024 * 1024,
51
57
  network: { allow: [], drop: ['0.0.0.0/0'] },
58
+ tagMode: 'replace',
52
59
  tags: ['job=node-build'],
60
+ secrets: [],
53
61
  });
54
62
 
55
63
  const description = await child.describe();
package/dist/index.cjs CHANGED
@@ -323,7 +323,8 @@ function vmForkFromWire(w) {
323
323
  status: w.status,
324
324
  ...w.parent_status !== void 0 && { parentStatus: w.parent_status },
325
325
  ...w.child_status !== void 0 && { childStatus: w.child_status },
326
- mode: w.mode ?? ""
326
+ mode: w.mode ?? "",
327
+ ...w.persistent !== void 0 && { persistent: w.persistent }
327
328
  };
328
329
  }
329
330
  function vmDescriptionFromWire(w) {
@@ -373,6 +374,31 @@ function secretFromWire(w) {
373
374
  ...w.modified_at !== void 0 && { modifiedAt: w.modified_at }
374
375
  };
375
376
  }
377
+
378
+ // src/fork.ts
379
+ function buildForkRequest(opts) {
380
+ const wait = opts.wait ?? "agent";
381
+ if (wait !== "agent" && wait !== "none") {
382
+ throw new Error(`invalid fork wait mode ${JSON.stringify(wait)}`);
383
+ }
384
+ const query = new URLSearchParams({ wait });
385
+ if (opts.waitTimeoutSec !== void 0 && opts.waitTimeoutSec > 0) {
386
+ query.set("timeout", `${opts.waitTimeoutSec}s`);
387
+ }
388
+ const body = {};
389
+ if (opts.network !== void 0) body.network = opts.network;
390
+ if (opts.tags !== void 0) body.tags = opts.tags;
391
+ if (opts.tagMode !== void 0) body.tag_mode = opts.tagMode;
392
+ if (opts.secrets !== void 0) body.secrets = opts.secrets;
393
+ if (opts.persistent !== void 0) body.persistent = opts.persistent;
394
+ if (opts.fixups !== void 0) body.fixups = opts.fixups;
395
+ if (opts.vcpu !== void 0) body.vcpu = opts.vcpu;
396
+ if (opts.ramBytes !== void 0) body.ram_bytes = opts.ramBytes;
397
+ return {
398
+ query: query.toString(),
399
+ ...Object.keys(body).length > 0 && { body }
400
+ };
401
+ }
376
402
  function looksLikeUnixSocketPath(s) {
377
403
  if (!s) return false;
378
404
  return s.startsWith("/") || s.startsWith("./") || s.startsWith("../") || s.includes("/");
@@ -851,6 +877,7 @@ var VM = class {
851
877
  ip;
852
878
  createdAt;
853
879
  arch;
880
+ tags;
854
881
  fs;
855
882
  bg;
856
883
  transport;
@@ -861,10 +888,37 @@ var VM = class {
861
888
  if (init.ip !== void 0) this.ip = init.ip;
862
889
  if (init.createdAt !== void 0) this.createdAt = init.createdAt;
863
890
  if (init.arch !== void 0) this.arch = init.arch;
891
+ if (init.tags !== void 0) this.tags = init.tags;
864
892
  this.fs = new VMFileSystem(transport, this.hostname);
865
893
  this.bg = new VMBg(transport, this.hostname);
866
894
  }
867
895
  // --- lifecycle --------------------------------------------------------
896
+ async getTags() {
897
+ const response = await this.transport.request(
898
+ "GET",
899
+ `/vm/${encodeURIComponent(this.hostname)}/tags`
900
+ );
901
+ this.tags = response.tags;
902
+ return response.tags;
903
+ }
904
+ async updateTags(update) {
905
+ const response = await this.transport.request(
906
+ "PATCH",
907
+ `/vm/${encodeURIComponent(this.hostname)}/tags`,
908
+ update
909
+ );
910
+ this.tags = response.tags;
911
+ return response.tags;
912
+ }
913
+ async addTags(...tags) {
914
+ return this.updateTags({ add: tags });
915
+ }
916
+ async removeTags(...tags) {
917
+ return this.updateTags({ remove: tags });
918
+ }
919
+ async replaceTags(tags) {
920
+ return this.updateTags({ replace: tags });
921
+ }
868
922
  async delete() {
869
923
  await this.transport.request(
870
924
  "DELETE",
@@ -1098,20 +1152,11 @@ function errMsg(e) {
1098
1152
  }
1099
1153
  async function forkPath(transport, commitId, opts) {
1100
1154
  const id = validateCommitId(commitId);
1101
- const q = new URLSearchParams();
1102
- q.set("wait", "agent");
1103
- if (opts.waitTimeoutSec !== void 0 && opts.waitTimeoutSec > 0) {
1104
- q.set("timeout", `${opts.waitTimeoutSec}s`);
1105
- }
1106
- const query = q.toString() ? `?${q.toString()}` : "";
1107
- const body = opts.network !== void 0 || (opts.tags?.length ?? 0) > 0 ? {
1108
- ...opts.network !== void 0 && { network: opts.network },
1109
- ...(opts.tags?.length ?? 0) > 0 && { tags: opts.tags }
1110
- } : void 0;
1155
+ const request = buildForkRequest(opts);
1111
1156
  const wire = await transport.request(
1112
1157
  "POST",
1113
- `/vm/commits/${encodeURIComponent(id)}/fork${query}`,
1114
- body
1158
+ `/vm/commits/${encodeURIComponent(id)}/fork?${request.query}`,
1159
+ request.body
1115
1160
  );
1116
1161
  return vmForkFromWire(wire);
1117
1162
  }
@@ -1330,7 +1375,8 @@ var VMsAPI = class {
1330
1375
  hostGroup: res.hostGroup ?? hostGroup,
1331
1376
  ...res.ip !== void 0 && { ip: res.ip },
1332
1377
  ...res.createdAt !== void 0 && { createdAt: res.createdAt },
1333
- ...res.arch !== void 0 && { arch: res.arch }
1378
+ ...res.arch !== void 0 && { arch: res.arch },
1379
+ ...req.tags !== void 0 && { tags: [...req.tags] }
1334
1380
  });
1335
1381
  }
1336
1382
  /**
@@ -1350,7 +1396,8 @@ var VMsAPI = class {
1350
1396
  hostGroup: found.hostGroup ?? "",
1351
1397
  ...found.ip !== void 0 && { ip: found.ip },
1352
1398
  ...found.createdAt !== void 0 && { createdAt: found.createdAt },
1353
- ...found.arch !== void 0 && { arch: found.arch }
1399
+ ...found.arch !== void 0 && { arch: found.arch },
1400
+ ...found.tags !== void 0 && { tags: found.tags }
1354
1401
  });
1355
1402
  }
1356
1403
  /** Return raw VM metadata across all host groups. */
@@ -1412,18 +1459,11 @@ var CommitsAPI = class {
1412
1459
  }
1413
1460
  async fork(commitId, opts = {}) {
1414
1461
  const id = validateCommitId2(commitId);
1415
- const qs = new URLSearchParams({ wait: "agent" });
1416
- if (opts.waitTimeoutSec !== void 0 && opts.waitTimeoutSec > 0) {
1417
- qs.set("timeout", `${opts.waitTimeoutSec}s`);
1418
- }
1419
- const body = opts.network !== void 0 || (opts.tags?.length ?? 0) > 0 ? {
1420
- ...opts.network !== void 0 && { network: opts.network },
1421
- ...(opts.tags?.length ?? 0) > 0 && { tags: opts.tags }
1422
- } : void 0;
1462
+ const request = buildForkRequest(opts);
1423
1463
  const wire = await this.transport.request(
1424
1464
  "POST",
1425
- `/vm/commits/${encodeURIComponent(id)}/fork?${qs.toString()}`,
1426
- body
1465
+ `/vm/commits/${encodeURIComponent(id)}/fork?${request.query}`,
1466
+ request.body
1427
1467
  );
1428
1468
  return vmForkFromWire(wire);
1429
1469
  }