@ornncompute/cli 1.0.67 → 1.0.75

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.
Files changed (39) hide show
  1. package/README.md +35 -27
  2. package/package.json +1 -1
  3. package/src/admin-capacity-reservations.mjs +2 -12
  4. package/src/admin-command-handlers.mjs +0 -1
  5. package/src/admin-credits.mjs +1 -2
  6. package/src/admin-enrollment.mjs +22 -30
  7. package/src/admin-mutations.mjs +6 -56
  8. package/src/admin-node-diagnostics.mjs +2 -36
  9. package/src/admin-node-lifecycle.mjs +25 -43
  10. package/src/admin-shell.mjs +39 -32
  11. package/src/catalog-shell.mjs +4 -18
  12. package/src/external-bucket-commands.mjs +5 -73
  13. package/src/interaction-runtime.mjs +2 -37
  14. package/src/kubernetes-commands.mjs +11 -102
  15. package/src/launch-mode-handlers.mjs +0 -1
  16. package/src/mount-commands.mjs +25 -131
  17. package/src/storage-commands.mjs +2 -87
  18. package/src/vm-commands.mjs +11 -44
  19. package/vendor/capabilities/capabilities/admin-capacity-reservations.js +12 -5
  20. package/vendor/capabilities/capabilities/admin-enrollment.js +18 -17
  21. package/vendor/capabilities/capabilities/admin-nodes-lifecycle.js +3 -101
  22. package/vendor/capabilities/capabilities/admin.js +3 -3
  23. package/vendor/capabilities/capabilities/clusters.js +3 -3
  24. package/vendor/capabilities/capabilities/commerce-market.js +9 -9
  25. package/vendor/capabilities/capabilities/compute.js +7 -7
  26. package/vendor/capabilities/capabilities/credits.js +7 -2
  27. package/vendor/capabilities/capabilities/external-buckets.js +4 -4
  28. package/vendor/capabilities/capabilities/fleet.js +109 -29
  29. package/vendor/capabilities/capabilities/listings.js +44 -16
  30. package/vendor/capabilities/capabilities/locality.js +42 -0
  31. package/vendor/capabilities/capabilities/market-shared.js +1 -1
  32. package/vendor/capabilities/capabilities/markets.js +14 -14
  33. package/vendor/capabilities/capabilities/mounts.js +4 -4
  34. package/vendor/capabilities/capabilities/native-listing.js +51 -15
  35. package/vendor/capabilities/capabilities/networks.js +5 -5
  36. package/vendor/capabilities/capabilities/observability.js +49 -14
  37. package/vendor/capabilities/capabilities/tokens.js +5 -9
  38. package/vendor/capabilities/capabilities/users.js +8 -10
  39. package/vendor/capabilities/capabilities/volumes.js +5 -5
@@ -9,9 +9,9 @@ const POLL_INTERVAL_MS = 1_000;
9
9
  const COMMAND_BY_CAPABILITY = Object.freeze({
10
10
  "nodes.reboot": "reboot",
11
11
  "nodes.hard_reset": "hard-reset",
12
- "nodes.suspend_management": "suspend-management",
13
- "nodes.resume_management": "resume-management",
14
- "nodes.terminate": "terminate",
12
+ "node.off-grid": "suspend-management",
13
+ "node.on-grid": "resume-management",
14
+ "node.terminate": "terminate",
15
15
  "nodes.assign": "assign",
16
16
  });
17
17
 
@@ -22,17 +22,17 @@ const CAPABILITY_BY_COMMAND = Object.freeze(
22
22
  );
23
23
 
24
24
  const USAGE = Object.freeze({
25
- reboot: "Usage: ornn admin nodes reboot <node-ref> [--yes] [--no-wait] [--timeout SECONDS]",
25
+ reboot: "Usage: ornn admin nodes reboot <node-ref> [--no-wait] [--timeout SECONDS]",
26
26
  "hard-reset":
27
- "Usage: ornn admin nodes hard-reset <node-ref> --erase-local-data [--yes] [--no-wait] [--timeout SECONDS]",
27
+ "Usage: ornn admin nodes hard-reset <node-ref> --erase-local-data [--no-wait] [--timeout SECONDS]",
28
28
  "suspend-management":
29
- "Usage: ornn admin nodes suspend-management <node-ref> [--reason TEXT] [--yes] [--idempotency-key KEY] [--wait|--no-wait] [--timeout SECONDS]",
29
+ "Usage: ornn admin nodes suspend-management <node-ref> [--reason TEXT] [--idempotency-key KEY] [--wait|--no-wait] [--timeout SECONDS]",
30
30
  "resume-management":
31
- "Usage: ornn admin nodes resume-management <node-ref> [--yes] [--idempotency-key KEY] [--wait|--no-wait] [--timeout SECONDS]",
31
+ "Usage: ornn admin nodes resume-management <node-ref> [--idempotency-key KEY] [--wait|--no-wait] [--timeout SECONDS]",
32
32
  terminate:
33
- "Usage: ornn admin nodes terminate <node-ref> --delete-node-record [--skip-cleanup] [--reason TEXT] [--yes] [--idempotency-key KEY]",
33
+ "Usage: ornn admin nodes terminate <node-ref> --delete-node-record [--skip-cleanup] [--reason TEXT] [--idempotency-key KEY]",
34
34
  assign:
35
- "Usage: ornn admin nodes assign <node-ref> --reservation RESERVATION [--yes] [--idempotency-key KEY] [--wait|--no-wait] [--timeout SECONDS]",
35
+ "Usage: ornn admin nodes assign <node-ref> --reservation RESERVATION [--idempotency-key KEY] [--wait|--no-wait] [--timeout SECONDS]",
36
36
  });
37
37
 
38
38
  const BOOLEAN_OPTIONS = new Set([
@@ -41,16 +41,15 @@ const BOOLEAN_OPTIONS = new Set([
41
41
  "no-wait",
42
42
  "skip-cleanup",
43
43
  "wait",
44
- "yes",
45
44
  ]);
46
45
  const VALUE_OPTIONS = new Set(["idempotency-key", "reason", "reservation", "timeout"]);
47
46
  const ALLOWED_OPTIONS = Object.freeze({
48
- reboot: new Set(["yes", "wait", "no-wait", "timeout"]),
49
- "hard-reset": new Set(["erase-local-data", "yes", "wait", "no-wait", "timeout"]),
50
- "suspend-management": new Set(["reason", "yes", "idempotency-key", "wait", "no-wait", "timeout"]),
51
- "resume-management": new Set(["yes", "idempotency-key", "wait", "no-wait", "timeout"]),
52
- terminate: new Set(["delete-node-record", "skip-cleanup", "reason", "yes", "idempotency-key"]),
53
- assign: new Set(["reservation", "yes", "idempotency-key", "wait", "no-wait", "timeout"]),
47
+ reboot: new Set(["wait", "no-wait", "timeout"]),
48
+ "hard-reset": new Set(["erase-local-data", "wait", "no-wait", "timeout"]),
49
+ "suspend-management": new Set(["reason", "idempotency-key", "wait", "no-wait", "timeout"]),
50
+ "resume-management": new Set(["idempotency-key", "wait", "no-wait", "timeout"]),
51
+ terminate: new Set(["delete-node-record", "skip-cleanup", "reason", "idempotency-key"]),
52
+ assign: new Set(["reservation", "idempotency-key", "wait", "no-wait", "timeout"]),
54
53
  });
55
54
 
56
55
  function mutationError(message, { code = "usage_error", field } = {}) {
@@ -135,22 +134,16 @@ export function parseAdminNodeLifecycleInput(command, argv) {
135
134
  });
136
135
  }
137
136
  if (name === "hard-reset" && options["erase-local-data"] !== true) {
138
- throw mutationError(
139
- `${usage}\nHard reset requires --erase-local-data; --yes cannot imply data loss.`,
140
- {
141
- code: "erase_local_data_required",
142
- field: "erase-local-data",
143
- }
144
- );
137
+ throw mutationError(`${usage}\nHard reset requires --erase-local-data.`, {
138
+ code: "erase_local_data_required",
139
+ field: "erase-local-data",
140
+ });
145
141
  }
146
142
  if (name === "terminate" && options["delete-node-record"] !== true) {
147
- throw mutationError(
148
- `${usage}\nTermination requires --delete-node-record; --yes cannot imply deletion.`,
149
- {
150
- code: "delete_node_record_required",
151
- field: "delete-node-record",
152
- }
153
- );
143
+ throw mutationError(`${usage}\nTermination requires --delete-node-record.`, {
144
+ code: "delete_node_record_required",
145
+ field: "delete-node-record",
146
+ });
154
147
  }
155
148
  if (name === "assign" && !options.reservation) {
156
149
  throw mutationError(`${usage}\nAssignment requires --reservation.`, {
@@ -170,12 +163,11 @@ export function parseAdminNodeLifecycleInput(command, argv) {
170
163
  const idempotencyKey = options["idempotency-key"]?.trim();
171
164
  const safety =
172
165
  name === "reboot" || name === "hard-reset"
173
- ? ADMIN_MUTATION_SAFETY.eligibleHumanOnly
166
+ ? ADMIN_MUTATION_SAFETY.direct
174
167
  : ADMIN_MUTATION_SAFETY.reconcile;
175
168
  return {
176
169
  input: {
177
170
  node_ref: nodeRef,
178
- ...(options.yes ? { yes: true } : {}),
179
171
  ...(idempotencyKey ? { idempotency_key: idempotencyKey } : {}),
180
172
  ...(options.reason ? { reason: options.reason } : {}),
181
173
  ...(options.wait ? { wait: true } : options["no-wait"] ? { wait: false } : {}),
@@ -192,7 +184,6 @@ export function parseAdminNodeLifecycleInput(command, argv) {
192
184
  mutation: {
193
185
  idempotencyKey,
194
186
  safety,
195
- yes: options.yes === true,
196
187
  },
197
188
  };
198
189
  }
@@ -900,15 +891,6 @@ export async function runAdminNodeLifecycle({
900
891
  },
901
892
  });
902
893
 
903
- if (result.status === "declined") {
904
- return {
905
- ...result,
906
- action: null,
907
- resume: null,
908
- errors: [],
909
- };
910
- }
911
-
912
894
  const accepted = {
913
895
  operation: command,
914
896
  reconciled: result.reconciled === true || lateReconciled,
@@ -939,7 +921,7 @@ export const adminNodeLifecycleHandlers = Object.keys(COMMAND_BY_CAPABILITY).map
939
921
  safety:
940
922
  COMMAND_BY_CAPABILITY[capabilityId] === "reboot" ||
941
923
  COMMAND_BY_CAPABILITY[capabilityId] === "hard-reset"
942
- ? ADMIN_MUTATION_SAFETY.eligibleHumanOnly
924
+ ? ADMIN_MUTATION_SAFETY.direct
943
925
  : ADMIN_MUTATION_SAFETY.reconcile,
944
926
  run: runAdminNodeLifecycle,
945
927
  })
@@ -185,13 +185,21 @@ function parseAdminInput(capability, argv) {
185
185
  throw new AdminUsageError(usage);
186
186
  }
187
187
 
188
- const offsetPagination = ["users.list", "organization.list"].includes(capability.id);
188
+ const offsetPagination = ["users.list", "organization.list", "supplier.list"].includes(
189
+ capability.id
190
+ );
191
+ const directoryPagination = ["users.list", "organization.list"].includes(capability.id);
189
192
  const reservationList = capability.id === "reservation.list";
190
- const limit = positiveInteger(
191
- options.limit,
192
- "limit",
193
- offsetPagination || reservationList ? 100 : MAX_PAGE_LIMIT
194
- ) ?? (offsetPagination ? 25 : DEFAULT_PAGE_LIMIT);
193
+ const maxLimit = directoryPagination
194
+ ? 100
195
+ : capability.id === "supplier.list"
196
+ ? 1000
197
+ : reservationList
198
+ ? 100
199
+ : MAX_PAGE_LIMIT;
200
+ const limit =
201
+ positiveInteger(options.limit, "limit", maxLimit) ??
202
+ (directoryPagination ? 25 : DEFAULT_PAGE_LIMIT);
195
203
  const input = {};
196
204
  if (nodeCommand) input.node_id = positionals[0];
197
205
  if (options.supplier) input.organization_id = options.supplier;
@@ -232,13 +240,8 @@ function parseAdminInput(capability, argv) {
232
240
  if (options.cursor) input.cursor = options.cursor;
233
241
  }
234
242
  if (offsetPagination) {
235
- if (explicitOffset !== undefined && options.cursor) {
236
- throw new AdminUsageError("--offset and --cursor cannot be used together.", {
237
- field: "offset",
238
- });
239
- }
240
243
  input.limit = limit;
241
- input.offset = explicitOffset ?? decodeCursor(command, options.cursor);
244
+ input.offset = explicitOffset ?? 0;
242
245
  }
243
246
 
244
247
  return {
@@ -328,14 +331,9 @@ function collectionKey(capability) {
328
331
  if (root === "nodes" && leaf === "logs") return "logs";
329
332
  if (!["list", "search"].includes(leaf)) return null;
330
333
  if (root === "enrollment-tokens") return "enrollment_tokens";
331
- return [
332
- "facilities",
333
- "nodes",
334
- "organizations",
335
- "reservations",
336
- "suppliers",
337
- "users",
338
- ].includes(root)
334
+ return ["facilities", "nodes", "organizations", "reservations", "suppliers", "users"].includes(
335
+ root
336
+ )
339
337
  ? root
340
338
  : null;
341
339
  }
@@ -445,14 +443,19 @@ export function finalizeAdminResult(capability, payload, pagination) {
445
443
  pagination.ownerOffsetPagination && payload && !Array.isArray(payload)
446
444
  ? payload.next_offset
447
445
  : undefined;
446
+ const nextOffset = pagination.ownerOffsetPagination
447
+ ? Number.isSafeInteger(ownerNextOffset) && ownerNextOffset > offset
448
+ ? ownerNextOffset
449
+ : selected.length === pagination.limit
450
+ ? offset + selected.length
451
+ : null
452
+ : undefined;
448
453
  const ownerNextCursor =
449
454
  payload && !Array.isArray(payload)
450
455
  ? (payload.next_cursor ?? payload.nextCursor ?? payload.page?.next_cursor ?? null)
451
456
  : null;
452
457
  let nextCursor = pagination.ownerOffsetPagination
453
- ? Number.isSafeInteger(ownerNextOffset) && ownerNextOffset > offset
454
- ? encodeCursor(command, ownerNextOffset)
455
- : null
458
+ ? null
456
459
  : !pagination.ownerPagination && offset + selected.length < rows.length
457
460
  ? encodeCursor(command, offset + selected.length)
458
461
  : (ownerNextCursor ?? null);
@@ -480,11 +483,9 @@ export function finalizeAdminResult(capability, payload, pagination) {
480
483
  }
481
484
  return {
482
485
  data: { [key]: selected },
483
- page: {
484
- limit: pagination.limit,
485
- returned: selected.length,
486
- next_cursor: nextCursor,
487
- },
486
+ page: pagination.ownerOffsetPagination
487
+ ? { limit: pagination.limit, returned: selected.length, next_offset: nextOffset }
488
+ : { limit: pagination.limit, returned: selected.length, next_cursor: nextCursor },
488
489
  };
489
490
  }
490
491
 
@@ -515,7 +516,15 @@ export function writeAdminResultHuman(stdout, command, result, input = {}) {
515
516
  } else {
516
517
  for (const row of rows) stdout.write(`${JSON.stringify(row)}\n`);
517
518
  }
518
- if (result.page.next_cursor) {
519
+ const nextPage =
520
+ result.page.next_offset !== undefined
521
+ ? result.page.next_offset === null
522
+ ? null
523
+ : `--offset ${result.page.next_offset}`
524
+ : result.page.next_cursor
525
+ ? `--cursor ${shellSingleQuote(result.page.next_cursor)}`
526
+ : null;
527
+ if (nextPage) {
519
528
  const target = command === "admin nodes logs" ? ` ${shellSingleQuote(input.node_id)}` : "";
520
529
  const filters = [
521
530
  ["supplier", command === "admin users list" ? undefined : input.organization_id],
@@ -535,8 +544,6 @@ export function writeAdminResultHuman(stdout, command, result, input = {}) {
535
544
  .filter(([, value]) => value !== undefined)
536
545
  .map(([name, value]) => ` --${name} ${shellSingleQuote(String(value))}`)
537
546
  .join("");
538
- stdout.write(
539
- `Next: ornn ${command}${target} --cursor ${shellSingleQuote(result.page.next_cursor)}${filters}\n`
540
- );
547
+ stdout.write(`Next: ornn ${command}${target} ${nextPage}${filters}\n`);
541
548
  }
542
549
  }
@@ -236,17 +236,11 @@ function retiredSyntaxError(argv, findLegacyCliMigration, migrationGuideUrl) {
236
236
  );
237
237
  }
238
238
 
239
- function resolveRequest(catalog, argv, findLegacyCliMigration, migrationGuideUrl) {
240
- if (argv.length === 0 || (argv.length === 1 && (argv[0] === "--help" || argv[0] === "-h"))) {
239
+ function resolveRequest(catalog, argvIn, findLegacyCliMigration, migrationGuideUrl) {
240
+ const argv = argvIn[0] === "--help" || argvIn[0] === "-h" ? ["help", ...argvIn.slice(1)] : argvIn;
241
+ if (argv.length === 0) {
241
242
  return { kind: "root", command: "help" };
242
243
  }
243
- if (argv[0] === "--help" || argv[0] === "-h") {
244
- return {
245
- kind: "error",
246
- command: "help",
247
- error: new VnextUsageError("Usage: ornn [--format human|json|ndjson]"),
248
- };
249
- }
250
244
 
251
245
  const retired = retiredSyntaxError(argv, findLegacyCliMigration, migrationGuideUrl);
252
246
  if (retired) {
@@ -311,15 +305,7 @@ function resolveRequest(catalog, argv, findLegacyCliMigration, migrationGuideUrl
311
305
  if (capability) {
312
306
  const command = vnextCommand(capability);
313
307
  const rest = argv.slice(command.length);
314
- const helpFlags = rest.filter((argument) => argument === "--help" || argument === "-h");
315
- if (helpFlags.length) {
316
- if (rest.length !== 1) {
317
- return {
318
- kind: "error",
319
- command: command.join(" "),
320
- error: new VnextUsageError(`Usage: ${capability.cli.vnext.human}`),
321
- };
322
- }
308
+ if (rest.some((argument) => argument === "--help" || argument === "-h")) {
323
309
  return { kind: "help", command: `help ${command.join(" ")}`, capability };
324
310
  }
325
311
  if (rest.length && capability.cli.vnext.arguments !== "semantic") {
@@ -402,7 +402,7 @@ function connectionEquivalent(drive, intent) {
402
402
  );
403
403
  }
404
404
 
405
- function requireMutationPreflight(input, runtime, { consent = false } = {}) {
405
+ function requireMutationPreflight(input, runtime) {
406
406
  const noninteractive = runtime.interaction.machine || runtime.interaction.redirected;
407
407
  if (noninteractive && !String(input.idempotencyKey ?? "").trim()) {
408
408
  usage(
@@ -410,23 +410,6 @@ function requireMutationPreflight(input, runtime, { consent = false } = {}) {
410
410
  "idempotency-key"
411
411
  );
412
412
  }
413
- if (noninteractive && consent && input.yes !== true) {
414
- usage(
415
- "Consent is required. Review the exact intent and supply --yes.",
416
- "yes",
417
- "consent_required"
418
- );
419
- }
420
- }
421
-
422
- async function reviewed(runtime, options) {
423
- const accepted = await runtime.interaction.review(options);
424
- if (accepted) return null;
425
- return runtime.interaction.result({
426
- data: null,
427
- exitCode: 1,
428
- outcome: { class: "ended", phase: "declined" },
429
- });
430
413
  }
431
414
 
432
415
  const SAFE_EXTERNAL_ERRORS = {
@@ -493,28 +476,11 @@ async function showBucket(input, runtime) {
493
476
 
494
477
  async function connectBucket(input, runtime) {
495
478
  const intent = await connectionIntent(input);
496
- requireMutationPreflight(input, runtime, { consent: true });
479
+ requireMutationPreflight(input, runtime);
497
480
  const fingerprint =
498
481
  intent.accessKeyId && intent.secretAccessKey
499
482
  ? credentialFingerprint(intent.accessKeyId, intent.secretAccessKey)
500
483
  : null;
501
- const declined = await reviewed(runtime, {
502
- title: "Connect external bucket",
503
- terms: [
504
- { label: "Kind", value: providerName(intent.kind) },
505
- { label: "Name", value: intent.name },
506
- { label: "Bucket", value: intent.bucket },
507
- { label: "Prefix", value: intent.prefix ?? "(bucket root)" },
508
- { label: "Access", value: intent.readOnly ? "read-only" : "read-write" },
509
- {
510
- label: "Credentials",
511
- value: fingerprint ? `fingerprint ${fingerprint.slice(0, 12)}` : "ambient GCS access",
512
- },
513
- { label: "Verification", value: "separate command required" },
514
- ],
515
- prompt: "Connect this external bucket?",
516
- });
517
- if (declined) return declined;
518
484
 
519
485
  const rows = await fetchDrives(runtime);
520
486
  const sameName = bucketRows(rows).filter(
@@ -644,7 +610,7 @@ async function updateCredentials(input, runtime) {
644
610
  );
645
611
  const accessKeyId = requiredText(input.accessKeyId, "--access-key-id", "access-key-id");
646
612
  const secret = await readCredentialFile(input.secretAccessKeyFile);
647
- requireMutationPreflight(input, runtime, { consent: true });
613
+ requireMutationPreflight(input, runtime);
648
614
  const fingerprint = credentialFingerprint(accessKeyId, secret);
649
615
  const source = resolveExternalBucket(await fetchDrives(runtime), reference);
650
616
  const kind = externalKind(source);
@@ -655,17 +621,6 @@ async function updateCredentials(input, runtime) {
655
621
  );
656
622
  }
657
623
  const id = safeIdentifier(source.id);
658
- const declined = await reviewed(runtime, {
659
- title: "Update external bucket credentials",
660
- terms: [
661
- { label: "External bucket", value: `${safeName(source.name)} (${id})` },
662
- { label: "Kind", value: providerName(kind) },
663
- { label: "Credential fingerprint", value: fingerprint.slice(0, 12) },
664
- { label: "Verification", value: "must be run again" },
665
- ],
666
- prompt: "Replace these credentials?",
667
- });
668
- if (declined) return declined;
669
624
  let updated;
670
625
  try {
671
626
  updated = await runtime.fetch(
@@ -698,20 +653,9 @@ async function updateCredentials(input, runtime) {
698
653
 
699
654
  async function disconnectBucket(input, runtime) {
700
655
  const [reference] = positions(input, 1, "ornn external-buckets disconnect <external-bucket>");
701
- requireMutationPreflight(input, runtime, { consent: true });
656
+ requireMutationPreflight(input, runtime);
702
657
  const source = resolveExternalBucket(await fetchDrives(runtime), reference);
703
658
  const safe = safeExternalBucket(source);
704
- const declined = await reviewed(runtime, {
705
- title: "Disconnect external bucket",
706
- terms: [
707
- { label: "External bucket", value: `${safe.name} (${safe.id})` },
708
- { label: "Kind", value: providerName(safe.kind) },
709
- { label: "Source writeback", value: "disabled" },
710
- { label: "Consequence", value: "source access is removed after all mounts are detached" },
711
- ],
712
- prompt: "Disconnect this external bucket?",
713
- });
714
- if (declined) return declined;
715
659
  const attachedReservations = activeMountReservations(source);
716
660
  if (attachedReservations.length > 0) {
717
661
  throw new StorageCommandError(
@@ -1159,7 +1103,7 @@ async function importBucket(input, runtime) {
1159
1103
  usage("Noninteractive --wait requires --timeout <duration>.", "timeout");
1160
1104
  }
1161
1105
  const timeoutMs = parseTimeout(input.timeout);
1162
- requireMutationPreflight(input, runtime, { consent: true });
1106
+ requireMutationPreflight(input, runtime);
1163
1107
 
1164
1108
  const source = resolveExternalBucket(await fetchDrives(runtime), reference);
1165
1109
  const bucket = safeExternalBucket(source);
@@ -1229,18 +1173,6 @@ async function importBucket(input, runtime) {
1229
1173
  : null;
1230
1174
  const replayed = attachment !== null;
1231
1175
  if (!attachment) {
1232
- const declined = await reviewed(runtime, {
1233
- title: "Import external bucket",
1234
- terms: [
1235
- { label: "Source", value: `${providerName(bucket.kind)} ${bucket.location.bucket}` },
1236
- { label: "Working volume", value: `${bucket.name} (${bucket.id})` },
1237
- { label: "Reservation", value: reservationId },
1238
- { label: "Isolation", value: "one Ornn-managed working copy" },
1239
- { label: "Source writeback", value: "disabled" },
1240
- ],
1241
- prompt: "Create this managed working copy?",
1242
- });
1243
- if (declined) return declined;
1244
1176
  try {
1245
1177
  const payload = await runtime.fetch(
1246
1178
  computeEndpoint(
@@ -18,7 +18,6 @@ const BOOLEAN_OPTIONS = new Set([
18
18
  "read-write",
19
19
  "recursive",
20
20
  "wait",
21
- "yes",
22
21
  ]);
23
22
 
24
23
  const OPTIONAL_VALUE_OPTIONS = new Set(["resume"]);
@@ -230,42 +229,8 @@ export function createInteractionRuntime({
230
229
  return answer;
231
230
  }
232
231
 
233
- async function review({ prompt = "Continue?", requireLive = false, terms, title }) {
234
- if (machine) {
235
- if (!requireLive && options.yes === true) return true;
236
- usage(
237
- requireLive
238
- ? "This operation is supported only in an eligible interactive terminal."
239
- : "Consent is required. Review the terms and supply --yes to continue.",
240
- {
241
- code: requireLive ? "unsupported_in_machine_mode" : "consent_required",
242
- ...(!requireLive ? { field: "yes" } : {}),
243
- }
244
- );
245
- }
246
- if (requireLive && !eligibleHuman) {
247
- usage("This operation is supported only in an eligible interactive terminal.", {
248
- code: "unsupported_in_machine_mode",
249
- });
250
- }
251
- stderr.write(`${title}\n`);
252
- for (const term of terms) stderr.write(` ${term.label}: ${term.value}\n`);
253
-
254
- if (!requireLive && options.yes === true) return true;
255
- if (!eligibleHuman) {
256
- usage("Consent is required. Review the terms and supply --yes to continue.", {
257
- code: "consent_required",
258
- field: "yes",
259
- });
260
- }
261
- let answer;
262
- try {
263
- answer = await readline().question(`${prompt} [y/N] `);
264
- } catch (caught) {
265
- if (caught?.code === "ERR_USE_AFTER_CLOSE") return false;
266
- throw caught;
267
- }
268
- return /^(y|yes)$/i.test(String(answer ?? "").trim());
232
+ async function review() {
233
+ return true;
269
234
  }
270
235
 
271
236
  function webUrl(path) {