@computesdk/cli 1.0.11 → 1.0.12

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
@@ -708,6 +708,76 @@ var ActionsApiError = class extends Error {
708
708
  this.name = "ActionsApiError";
709
709
  }
710
710
  };
711
+ var ActionsCliError = class extends Error {
712
+ constructor(code, message) {
713
+ super(message);
714
+ this.code = code;
715
+ this.name = "ActionsCliError";
716
+ }
717
+ };
718
+ function codeForStatus(status) {
719
+ switch (status) {
720
+ case 400:
721
+ return "bad_request";
722
+ case 401:
723
+ return "unauthenticated";
724
+ case 403:
725
+ return "forbidden";
726
+ case 404:
727
+ return "not_found";
728
+ case 409:
729
+ return "conflict";
730
+ case 413:
731
+ return "payload_too_large";
732
+ case 429:
733
+ return "rate_limited";
734
+ default:
735
+ return status >= 500 ? "server_error" : "http_error";
736
+ }
737
+ }
738
+ function errorDetails(body) {
739
+ if (body && typeof body === "object" && "details" in body) {
740
+ const details = body.details;
741
+ if (details && typeof details === "object" && !Array.isArray(details)) {
742
+ return details;
743
+ }
744
+ }
745
+ return void 0;
746
+ }
747
+ function toErrorEnvelope(error) {
748
+ if (error instanceof ActionsApiError) {
749
+ const details = errorDetails(error.body);
750
+ return {
751
+ ok: false,
752
+ error: {
753
+ code: codeForStatus(error.status),
754
+ message: error.message,
755
+ httpStatus: error.status,
756
+ retryable: error.status === 429 || error.status === 502 || error.status === 503 || error.status === 504,
757
+ ...details !== void 0 && { details }
758
+ }
759
+ };
760
+ }
761
+ if (error instanceof ActionsCliError) {
762
+ return { ok: false, error: { code: error.code, message: error.message, retryable: false } };
763
+ }
764
+ if (error instanceof TypeError && /fetch failed/i.test(error.message)) {
765
+ const cause = error.cause;
766
+ const detail = cause instanceof Error ? `: ${cause.message}` : "";
767
+ return {
768
+ ok: false,
769
+ error: { code: "network", message: `${error.message}${detail}`, retryable: true }
770
+ };
771
+ }
772
+ return {
773
+ ok: false,
774
+ error: {
775
+ code: "unknown",
776
+ message: error instanceof Error ? error.message : String(error),
777
+ retryable: false
778
+ }
779
+ };
780
+ }
711
781
  var ActionsClient = class {
712
782
  constructor(auth, fetchImpl = fetch) {
713
783
  this.auth = auth;
@@ -834,22 +904,64 @@ function encodeWatchCursor(id, jobId, step, offset) {
834
904
  const stepPart = step === null ? "-" : step === "runner" ? "runner" : String(step);
835
905
  return `${id}:${jobId}:${stepPart}:${offset}`;
836
906
  }
837
- function resolveActionsAuth(opts) {
838
- const apiKey = opts.apiKey || process.env.COMPUTE_API_KEY || process.env.BENCHMARKS_PLATFORM_API_KEY;
839
- if (!apiKey) {
840
- throw new Error(
841
- "No API key. Set COMPUTE_API_KEY or pass --api-key."
842
- );
843
- }
907
+ var NO_CREDENTIALS_HINT = "Set COMPUTE_API_KEY, pass --api-key, or run `compute bench auth login`.";
908
+ async function resolveActionsAuth(opts, resolveStored = resolveStoredPlatformAuth) {
844
909
  const baseUrl = (opts.baseUrl || process.env.COMPUTE_PLATFORM_URL || process.env.BENCHMARKS_PLATFORM_URL || // legacy name
845
910
  DEFAULT_BASE_URL).replace(/\/+$/, "");
846
911
  if (!opts.allowUntrustedHost && !isTrustedActionsHost(baseUrl)) {
847
- throw new Error(
912
+ throw new ActionsCliError(
913
+ "untrusted_host",
848
914
  `Refusing to send the API key to ${baseUrl} \u2014 it is not a computesdk.com or localhost host. If this is a self-hosted/dev deployment you trust, pass --allow-untrusted-host.`
849
915
  );
850
916
  }
917
+ if (!isSecureActionsTransport(baseUrl)) {
918
+ throw new ActionsCliError(
919
+ "insecure_transport",
920
+ `Refusing to send the API key over plaintext HTTP to ${baseUrl}. Use an https:// base URL; http:// is only allowed for localhost/loopback.`
921
+ );
922
+ }
923
+ let apiKey = opts.apiKey || process.env.COMPUTE_API_KEY || process.env.BENCHMARKS_PLATFORM_API_KEY || // legacy name
924
+ void 0;
925
+ if (!apiKey) {
926
+ if (!isTrustedActionsHost(baseUrl)) {
927
+ throw new ActionsCliError(
928
+ "untrusted_host_stored_auth",
929
+ `Refusing to use stored platform credentials with untrusted host ${baseUrl}. Pass --api-key or set COMPUTE_API_KEY to use an explicit key with --allow-untrusted-host.`
930
+ );
931
+ }
932
+ let stored;
933
+ try {
934
+ stored = await resolveStored({ baseUrl });
935
+ } catch (error) {
936
+ const reason = error instanceof Error ? error.message : String(error);
937
+ const detail = reason.startsWith("No credentials found") ? "No API key." : reason;
938
+ throw new ActionsCliError("no_credentials", `${detail} ${NO_CREDENTIALS_HINT}`);
939
+ }
940
+ apiKey = stored.apiKey || stored.token || void 0;
941
+ }
942
+ if (!apiKey) {
943
+ throw new ActionsCliError("no_credentials", `No API key. ${NO_CREDENTIALS_HINT}`);
944
+ }
851
945
  return { apiKey, baseUrl };
852
946
  }
947
+ async function resolveStoredPlatformAuth(opts) {
948
+ const { resolveAuth } = await import("@benchsdk/cli");
949
+ const auth = await resolveAuth({ baseUrl: opts.baseUrl });
950
+ return { apiKey: auth.apiKey, token: auth.token };
951
+ }
952
+ function isLoopbackHost(host) {
953
+ return host === "localhost" || host === "127.0.0.1" || host === "[::1]" || host === "::1";
954
+ }
955
+ function isSecureActionsTransport(baseUrl) {
956
+ let url;
957
+ try {
958
+ url = new URL(baseUrl);
959
+ } catch {
960
+ return false;
961
+ }
962
+ if (url.protocol === "https:") return true;
963
+ return url.protocol === "http:" && isLoopbackHost(url.hostname);
964
+ }
853
965
  function isTrustedActionsHost(baseUrl) {
854
966
  let host;
855
967
  try {
@@ -857,7 +969,7 @@ function isTrustedActionsHost(baseUrl) {
857
969
  } catch {
858
970
  return false;
859
971
  }
860
- return host === "computesdk.com" || host.endsWith(".computesdk.com") || host === "localhost" || host === "127.0.0.1" || host === "::1";
972
+ return host === "computesdk.com" || host.endsWith(".computesdk.com") || isLoopbackHost(host);
861
973
  }
862
974
 
863
975
  // src/actions.ts
@@ -866,8 +978,8 @@ function sanitizePathPart(name) {
866
978
  if (base === "" || base === "." || base === "..") return "artifact";
867
979
  return base;
868
980
  }
869
- function client(opts) {
870
- return new ActionsClient(resolveActionsAuth(opts));
981
+ async function client(opts) {
982
+ return new ActionsClient(await resolveActionsAuth(opts));
871
983
  }
872
984
  function output(opts, data, render) {
873
985
  if (opts.json) {
@@ -912,14 +1024,24 @@ async function fetchRunSummary(c, runId) {
912
1024
  return null;
913
1025
  }
914
1026
  }
915
- function fail(error) {
916
- if (error instanceof ActionsApiError) {
1027
+ function fail(error, opts = {}) {
1028
+ if (opts.json) {
1029
+ process.stderr.write(JSON.stringify(toErrorEnvelope(error)) + "\n");
1030
+ } else if (error instanceof ActionsApiError) {
917
1031
  console.error(pc.red(`Error (${error.status}): ${error.message}`));
918
1032
  } else {
919
- console.error(pc.red(`Error: ${error.message}`));
1033
+ console.error(pc.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
920
1034
  }
921
1035
  process.exit(1);
922
1036
  }
1037
+ function usageErrorOutput(str, write, argv = process.argv) {
1038
+ if (argv.includes("--json")) {
1039
+ const message = str.replace(/^error:\s*/i, "").trim();
1040
+ write(JSON.stringify(toErrorEnvelope(new ActionsCliError("invalid_argument", message))) + "\n");
1041
+ } else {
1042
+ write(str);
1043
+ }
1044
+ }
923
1045
  function formatDuration(ms) {
924
1046
  if (ms === null || ms === void 0) return "-";
925
1047
  if (ms < 1e3) return `${ms}ms`;
@@ -1085,7 +1207,7 @@ function parseInputs(pairs) {
1085
1207
  for (const pair of pairs ?? []) {
1086
1208
  const eq = pair.indexOf("=");
1087
1209
  if (eq === -1) {
1088
- throw new Error(`Invalid --inputs entry "${pair}". Expected key=value.`);
1210
+ throw new ActionsCliError("invalid_argument", `Invalid --inputs entry "${pair}". Expected key=value.`);
1089
1211
  }
1090
1212
  inputs[pair.slice(0, eq)] = pair.slice(eq + 1);
1091
1213
  }
@@ -1135,7 +1257,7 @@ function parseStep(step) {
1135
1257
  if (step === "runner") return "runner";
1136
1258
  const n = Number(step);
1137
1259
  if (!Number.isInteger(n) || n < 0) {
1138
- throw new Error(`Invalid --step "${step}". Expected a step ordinal or "runner".`);
1260
+ throw new ActionsCliError("invalid_argument", `Invalid --step "${step}". Expected a step ordinal or "runner".`);
1139
1261
  }
1140
1262
  return n;
1141
1263
  }
@@ -1233,14 +1355,43 @@ function printDiscovery(d) {
1233
1355
  }
1234
1356
  console.log(pc.dim(`discovery: ${d.workflowsFound ? "workflows found" : "no workflows yet"}${d.seeded ? ", cursors seeded" : ""}`));
1235
1357
  }
1358
+ function dispatchBody(workflow, opts) {
1359
+ if (!workflow.dispatchable && !opts.manual) {
1360
+ throw new ActionsCliError(
1361
+ "invalid_argument",
1362
+ `Workflow "${workflow.path}" does not declare workflow_dispatch. Pass --manual to run it anyway (no inputs).`
1363
+ );
1364
+ }
1365
+ if (!workflow.dispatchable && opts.inputs !== void 0 && opts.inputs.length > 0) {
1366
+ throw new ActionsCliError(
1367
+ "invalid_argument",
1368
+ `Workflow "${workflow.path}" has no workflow_dispatch inputs; --manual runs of it take no --inputs.`
1369
+ );
1370
+ }
1371
+ const ref = opts.ref ?? workflow.refs[0];
1372
+ if (!ref) throw new ActionsCliError("invalid_argument", "No --ref given and the workflow has no watched refs.");
1373
+ if (opts.providerRegion !== void 0 && opts.provider === void 0) {
1374
+ throw new ActionsCliError("invalid_argument", "--provider-region requires --provider.");
1375
+ }
1376
+ return {
1377
+ workflowId: workflow.id,
1378
+ ref,
1379
+ inputs: parseInputs(opts.inputs),
1380
+ ...opts.manual && { manual: true },
1381
+ ...opts.provider !== void 0 && {
1382
+ provider: opts.provider,
1383
+ ...opts.providerRegion !== void 0 && { providerRegion: opts.providerRegion }
1384
+ }
1385
+ };
1386
+ }
1236
1387
  function registerActionsCommands(program2) {
1237
- const actions = program2.command("actions").alias("ci").description("Drive the benchmarks-platform Actions API");
1238
- const common = (cmd) => cmd.option("--api-key <key>", "API key (default: $COMPUTE_API_KEY)").option("--base-url <url>", "API base URL (default: https://platform.computesdk.com)").option("--allow-untrusted-host", "send the API key to a non-computesdk, non-localhost --base-url").option("--json", "print machine-readable JSON");
1388
+ const actions = program2.command("actions").alias("ci").description("Drive the benchmarks-platform Actions API").configureOutput({ outputError: usageErrorOutput });
1389
+ const common = (cmd) => cmd.option("--api-key <key>", "API key (default: $COMPUTE_API_KEY)").option("--base-url <url>", "API base URL (default: https://platform.computesdk.com)").option("--allow-untrusted-host", "send an explicit --api-key/env key to a non-computesdk, non-localhost --base-url (stored login credentials are never sent)").option("--json", "print machine-readable JSON");
1239
1390
  common(
1240
- actions.command("dispatch").description("Dispatch a workflow_dispatch run").argument("<repo>", "repository in owner/repo format").requiredOption("--workflow <path|name>", "workflow path or name").option("--ref <ref>", "git ref to run (default: the workflow's first watched ref)").option("--inputs <pairs...>", "workflow inputs as key=value").option("--provider <id>", "place the run on one provider (e.g. namespace, vercel:sfo1) instead of the org provider order").option("--provider-region <region>", "region for --provider (same as --provider <id>:<region>)")
1391
+ actions.command("dispatch").description("Dispatch a workflow_dispatch run (or any workflow with --manual)").argument("<repo>", "repository in owner/repo format").requiredOption("--workflow <path|name>", "workflow path or name").option("--ref <ref>", "git ref to run (default: the workflow's first watched ref)").option("--inputs <pairs...>", "workflow inputs as key=value (workflow_dispatch inputs only)").option("--manual", "run a workflow even if it does not declare workflow_dispatch (such runs take no --inputs)").option("--provider <id>", "place the run on one provider (e.g. namespace, vercel:sfo1) instead of the org provider order").option("--provider-region <region>", "region for --provider (same as --provider <id>:<region>)")
1241
1392
  ).action(async (repo, opts) => {
1242
1393
  try {
1243
- const c = client(opts);
1394
+ const c = await client(opts);
1244
1395
  const { workflows } = await c.get(
1245
1396
  "/api/v1/actions/workflows",
1246
1397
  { repo }
@@ -1248,26 +1399,15 @@ function registerActionsCommands(program2) {
1248
1399
  const workflow = matchWorkflow(workflows, opts.workflow);
1249
1400
  if (!workflow) {
1250
1401
  const choices = workflows.map((w) => `${w.path} (${w.name})`).join(", ") || "none";
1251
- throw new Error(
1252
- `No dispatchable workflow "${opts.workflow}" in ${repo}. Available: ${choices}`
1402
+ throw new ActionsCliError(
1403
+ "workflow_not_found",
1404
+ `No workflow "${opts.workflow}" in ${repo}. Available: ${choices}`
1253
1405
  );
1254
1406
  }
1255
- const ref = opts.ref ?? workflow.refs[0];
1256
- if (!ref) throw new Error("No --ref given and the workflow has no watched refs.");
1257
- if (opts.providerRegion !== void 0 && opts.provider === void 0) {
1258
- throw new Error("--provider-region requires --provider.");
1259
- }
1407
+ const body = dispatchBody(workflow, opts);
1260
1408
  const result = await c.post(
1261
1409
  "/api/v1/actions/dispatch",
1262
- {
1263
- workflowId: workflow.id,
1264
- ref,
1265
- inputs: parseInputs(opts.inputs),
1266
- ...opts.provider !== void 0 && {
1267
- provider: opts.provider,
1268
- ...opts.providerRegion !== void 0 && { providerRegion: opts.providerRegion }
1269
- }
1270
- }
1410
+ body
1271
1411
  );
1272
1412
  const org = await c.org();
1273
1413
  const url = `${c.baseUrl}/${org.slug}/actions/runs/${result.runId}`;
@@ -1277,14 +1417,14 @@ function registerActionsCommands(program2) {
1277
1417
  console.log(`url: ${r.url}`);
1278
1418
  });
1279
1419
  } catch (e) {
1280
- fail(e);
1420
+ fail(e, opts);
1281
1421
  }
1282
1422
  });
1283
1423
  common(
1284
1424
  actions.command("runs").description("List recent runs for a repo").argument("<repo>", "repository in owner/repo format").option("--status <status...>", "filter by conclusion: passed, failed, running, cancelled, none").option("--branch <branch...>", "filter by branch/ref")
1285
1425
  ).action(async (repo, opts) => {
1286
1426
  try {
1287
- const { runs } = await client(opts).get(
1427
+ const { runs } = await (await client(opts)).get(
1288
1428
  "/api/v1/actions/runs",
1289
1429
  { repo, status: opts.status, branch: opts.branch }
1290
1430
  );
@@ -1296,14 +1436,14 @@ function registerActionsCommands(program2) {
1296
1436
  for (const run of rs) console.log(formatRunRow(run));
1297
1437
  });
1298
1438
  } catch (e) {
1299
- fail(e);
1439
+ fail(e, opts);
1300
1440
  }
1301
1441
  });
1302
1442
  common(
1303
1443
  actions.command("history").description("Recent run history for a workflow \u2014 per-job/step failure rates (is this failure flaky?)").argument("<repo>", "repository in owner/repo format").requiredOption("--workflow <path|name>", "workflow path or name").option("--branch <branch...>", "narrow the window to branches/refs").option("--job <job>", "narrow the rollup to one job name or workflow job id").option("--limit <n>", "runs in the window (default 10, max 50)")
1304
1444
  ).action(async (repo, opts) => {
1305
1445
  try {
1306
- const c = client(opts);
1446
+ const c = await client(opts);
1307
1447
  const { workflows } = await c.get(
1308
1448
  "/api/v1/actions/workflows",
1309
1449
  { repo }
@@ -1319,14 +1459,14 @@ function registerActionsCommands(program2) {
1319
1459
  });
1320
1460
  output(opts, history, (h) => console.log(formatRunHistory(h)));
1321
1461
  } catch (e) {
1322
- fail(e);
1462
+ fail(e, opts);
1323
1463
  }
1324
1464
  });
1325
1465
  common(
1326
1466
  actions.command("run").description("Show a run: jobs, provider:region placement, placement attempts").argument("<run-id>", "run ID")
1327
1467
  ).action(async (runId, opts) => {
1328
1468
  try {
1329
- const c = client(opts);
1469
+ const c = await client(opts);
1330
1470
  const run = await c.get(`/api/v1/actions/runs/${runId}`);
1331
1471
  const org = await c.org();
1332
1472
  const url = `${c.baseUrl}/${org.slug}/actions/runs/${run.id}`;
@@ -1339,37 +1479,37 @@ function registerActionsCommands(program2) {
1339
1479
  }
1340
1480
  });
1341
1481
  } catch (e) {
1342
- fail(e);
1482
+ fail(e, opts);
1343
1483
  }
1344
1484
  });
1345
1485
  common(
1346
1486
  actions.command("summary").description("Show a run's failure digest: failed jobs, failed steps, bounded log tails").argument("<run-id>", "run ID")
1347
1487
  ).action(async (runId, opts) => {
1348
1488
  try {
1349
- const summary = await client(opts).get(`/api/v1/actions/runs/${runId}/summary`);
1489
+ const summary = await (await client(opts)).get(`/api/v1/actions/runs/${runId}/summary`);
1350
1490
  output(opts, summary, (s) => console.log(formatRunSummary(s)));
1351
1491
  } catch (e) {
1352
- fail(e);
1492
+ fail(e, opts);
1353
1493
  }
1354
1494
  });
1355
1495
  common(
1356
1496
  actions.command("inspect").description("Inspect a run: resolved runner image, caches, secret names, concurrency, placement context").argument("<run-id>", "run ID")
1357
1497
  ).action(async (runId, opts) => {
1358
1498
  try {
1359
- const c = client(opts);
1499
+ const c = await client(opts);
1360
1500
  const inspection = await c.get(
1361
1501
  `/api/v1/actions/runs/${runId}/state`
1362
1502
  );
1363
1503
  output(opts, inspection, (r) => console.log(formatRunInspection(r)));
1364
1504
  } catch (e) {
1365
- fail(e);
1505
+ fail(e, opts);
1366
1506
  }
1367
1507
  });
1368
1508
  common(
1369
1509
  actions.command("logs").description("Print or follow a run's job logs").argument("<run-id>", "run ID").option("--job <job>", "job ID or name (default: all jobs)").option("--step <step>", 'step ordinal or "runner" (default: whole job)').option("--follow", "stream logs while the run is live")
1370
1510
  ).action(async (runId, opts) => {
1371
1511
  try {
1372
- const c = client(opts);
1512
+ const c = await client(opts);
1373
1513
  let jobs = await listRunJobs(c, runId);
1374
1514
  if (opts.job) {
1375
1515
  const job = matchJob(jobs, opts.job);
@@ -1420,25 +1560,25 @@ function registerActionsCommands(program2) {
1420
1560
  }
1421
1561
  }
1422
1562
  } catch (e) {
1423
- fail(e);
1563
+ fail(e, opts);
1424
1564
  }
1425
1565
  });
1426
1566
  const providers = actions.command("providers").description("List the org's registered compute providers (regions, act/usable status)");
1427
1567
  common(providers).action(async (opts) => {
1428
1568
  try {
1429
- const data = await client(opts).get("/api/v1/actions/providers");
1569
+ const data = await (await client(opts)).get("/api/v1/actions/providers");
1430
1570
  output(opts, data, (d) => {
1431
1571
  for (const p5 of d.providers) console.log(formatProviderRow(p5));
1432
1572
  });
1433
1573
  } catch (e) {
1434
- fail(e);
1574
+ fail(e, opts);
1435
1575
  }
1436
1576
  });
1437
1577
  common(
1438
1578
  providers.command("configure").description("Save the org's credential for a provider (owner/admin API key)").argument("<provider>", "provider id (e.g. tensorlake, blaxel)").option("--key <key>", "provider API key (single-field credentials)").option("--field <pair...>", "credential fields as name=value (multi-field providers)").option("--verify", "run the placement probe after saving")
1439
1579
  ).action(async (provider, opts) => {
1440
1580
  try {
1441
- const c = client(opts);
1581
+ const c = await client(opts);
1442
1582
  let body;
1443
1583
  if (opts.field !== void 0) {
1444
1584
  if (opts.key !== void 0) throw new Error("Pass either --key or --field, not both.");
@@ -1461,45 +1601,45 @@ function registerActionsCommands(program2) {
1461
1601
  });
1462
1602
  if (verification?.verified === false) process.exitCode = 1;
1463
1603
  } catch (e) {
1464
- fail(e);
1604
+ fail(e, opts);
1465
1605
  }
1466
1606
  });
1467
1607
  common(
1468
1608
  providers.command("verify").description('Probe the stored provider key with a real sandbox ("Test" in Settings)').argument("<provider>", "provider id")
1469
1609
  ).action(async (provider, opts) => {
1470
1610
  try {
1471
- const result = await client(opts).post(
1611
+ const result = await (await client(opts)).post(
1472
1612
  `/api/v1/actions/providers/${provider}/verify`
1473
1613
  );
1474
1614
  output(opts, result, (r) => console.log(formatVerifyResult(r)));
1475
1615
  if (result.verified === false) process.exitCode = 1;
1476
1616
  } catch (e) {
1477
- fail(e);
1617
+ fail(e, opts);
1478
1618
  }
1479
1619
  });
1480
1620
  common(
1481
1621
  providers.command("remove").description("Delete the org's stored credential for a provider").argument("<provider>", "provider id")
1482
1622
  ).action(async (provider, opts) => {
1483
1623
  try {
1484
- const result = await client(opts).del(
1624
+ const result = await (await client(opts)).del(
1485
1625
  `/api/v1/actions/providers/${provider}/key`
1486
1626
  );
1487
1627
  output(opts, result, (r) => {
1488
1628
  console.log(r.deleted ? `deleted ${r.provider}` : `no key stored for ${r.provider}`);
1489
1629
  });
1490
1630
  } catch (e) {
1491
- fail(e);
1631
+ fail(e, opts);
1492
1632
  }
1493
1633
  });
1494
1634
  const repos = actions.command("repos").description("List the org's connected repositories");
1495
1635
  common(repos).action(async (opts) => {
1496
1636
  try {
1497
- const data = await client(opts).get("/api/v1/actions/repos");
1637
+ const data = await (await client(opts)).get("/api/v1/actions/repos");
1498
1638
  output(opts, data, (d) => {
1499
1639
  for (const r of d.repos) console.log(formatRepoRow(r));
1500
1640
  });
1501
1641
  } catch (e) {
1502
- fail(e);
1642
+ fail(e, opts);
1503
1643
  }
1504
1644
  });
1505
1645
  common(
@@ -1529,7 +1669,7 @@ function registerActionsCommands(program2) {
1529
1669
  if (opts.knownHostsFile !== void 0 && opts.sshKeyFile === void 0) {
1530
1670
  throw new Error("--known-hosts-file requires --ssh-key-file.");
1531
1671
  }
1532
- const result = await client(opts).post("/api/v1/actions/repos", {
1672
+ const result = await (await client(opts)).post("/api/v1/actions/repos", {
1533
1673
  cloneUrl,
1534
1674
  ...body,
1535
1675
  ...opts.name !== void 0 && { name: opts.name },
@@ -1540,14 +1680,14 @@ function registerActionsCommands(program2) {
1540
1680
  printDiscovery(r.discovery);
1541
1681
  });
1542
1682
  } catch (e) {
1543
- fail(e);
1683
+ fail(e, opts);
1544
1684
  }
1545
1685
  });
1546
1686
  common(
1547
1687
  repos.command("enable").description("Enable a repo the org can already see (granted by a GitHub App install, or a connected remote)").argument("<repo>", "repository in owner/repo format").option("--repo-id <id>", "scope to one row when two installations grant the same name")
1548
1688
  ).action(async (repo, opts) => {
1549
1689
  try {
1550
- const result = await client(opts).patch("/api/v1/actions/repos", {
1690
+ const result = await (await client(opts)).patch("/api/v1/actions/repos", {
1551
1691
  fullName: repo,
1552
1692
  enabled: true,
1553
1693
  ...opts.repoId !== void 0 && { repoId: opts.repoId }
@@ -1557,42 +1697,42 @@ function registerActionsCommands(program2) {
1557
1697
  if (r.discovery) printDiscovery(r.discovery);
1558
1698
  });
1559
1699
  } catch (e) {
1560
- fail(e);
1700
+ fail(e, opts);
1561
1701
  }
1562
1702
  });
1563
1703
  common(
1564
1704
  repos.command("disable").description("Disable a repo \u2014 it stays connected but no runs are scheduled").argument("<repo>", "repository in owner/repo format").option("--repo-id <id>", "scope to one row when two installations grant the same name")
1565
1705
  ).action(async (repo, opts) => {
1566
1706
  try {
1567
- const result = await client(opts).patch("/api/v1/actions/repos", {
1707
+ const result = await (await client(opts)).patch("/api/v1/actions/repos", {
1568
1708
  fullName: repo,
1569
1709
  enabled: false,
1570
1710
  ...opts.repoId !== void 0 && { repoId: opts.repoId }
1571
1711
  });
1572
1712
  output(opts, result, (r) => console.log(`disabled ${pc.cyan(safeTerm(r.fullName))}`));
1573
1713
  } catch (e) {
1574
- fail(e);
1714
+ fail(e, opts);
1575
1715
  }
1576
1716
  });
1577
1717
  common(
1578
1718
  actions.command("cancel").description("Cancel a run").argument("<run-id>", "run ID")
1579
1719
  ).action(async (runId, opts) => {
1580
1720
  try {
1581
- const result = await client(opts).post(
1721
+ const result = await (await client(opts)).post(
1582
1722
  `/api/v1/actions/runs/${runId}/cancel`
1583
1723
  );
1584
1724
  output(opts, result, (r) => {
1585
1725
  console.log(r.cancelled ? `Cancelled ${runId}` : `Run ${runId} was already finished`);
1586
1726
  });
1587
1727
  } catch (e) {
1588
- fail(e);
1728
+ fail(e, opts);
1589
1729
  }
1590
1730
  });
1591
1731
  common(
1592
1732
  actions.command("rerun").description("Re-run a finished run at the same commit").argument("<run-id>", "run ID")
1593
1733
  ).action(async (runId, opts) => {
1594
1734
  try {
1595
- const c = client(opts);
1735
+ const c = await client(opts);
1596
1736
  const result = await c.post(
1597
1737
  `/api/v1/actions/runs/${runId}/rerun`
1598
1738
  );
@@ -1603,14 +1743,14 @@ function registerActionsCommands(program2) {
1603
1743
  console.log(`url: ${r.url}`);
1604
1744
  });
1605
1745
  } catch (e) {
1606
- fail(e);
1746
+ fail(e, opts);
1607
1747
  }
1608
1748
  });
1609
1749
  common(
1610
1750
  actions.command("artifacts").description("List or download a run's artifacts").argument("<run-id>", "run ID").option("--job <job>", "job ID or name (default: all jobs)").option("--out <dir>", "download artifacts into this directory instead of listing")
1611
1751
  ).action(async (runId, opts) => {
1612
1752
  try {
1613
- const c = client(opts);
1753
+ const c = await client(opts);
1614
1754
  let jobs = await listRunJobs(c, runId);
1615
1755
  if (opts.job) {
1616
1756
  const job = matchJob(jobs, opts.job);
@@ -1659,7 +1799,7 @@ function registerActionsCommands(program2) {
1659
1799
  if (!any) console.log("No artifacts.");
1660
1800
  });
1661
1801
  } catch (e) {
1662
- fail(e);
1802
+ fail(e, opts);
1663
1803
  }
1664
1804
  });
1665
1805
  }