trainfabric 0.1.34 → 0.1.36

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 (2) hide show
  1. package/dist/index.cjs +38 -19
  2. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -8137,6 +8137,13 @@ var BillingClient = class extends ResourceClient {
8137
8137
  const query = params.toString();
8138
8138
  return this.requestGet(`/v1/billing/usage${query ? `?${query}` : ""}`);
8139
8139
  }
8140
+ async getRunUsage(runId) {
8141
+ const [summary, records] = await Promise.all([
8142
+ this.requestGet(`/v1/runs/${encodeURIComponent(runId)}/usage`),
8143
+ this.getUsage(void 0, runId)
8144
+ ]);
8145
+ return { ...summary, usage: records };
8146
+ }
8140
8147
  listInvoices() {
8141
8148
  return this.requestGet("/v1/billing/invoices");
8142
8149
  }
@@ -9255,7 +9262,7 @@ function buildComputeSpec(options) {
9255
9262
 
9256
9263
  // src/index.ts
9257
9264
  var DEFAULT_TRAINFABRIC_API_URL2 = "https://api.trainfabric.com";
9258
- var CLI_VERSION = "0.1.34";
9265
+ var CLI_VERSION = "0.1.36";
9259
9266
  var CONFIG_DIR = import_node_path3.default.join(import_node_os2.default.homedir(), ".trainfabric");
9260
9267
  var CONFIG_PATH = import_node_path3.default.join(CONFIG_DIR, "config.json");
9261
9268
  var FALLBACK_SECRET_PATH = import_node_path3.default.join(CONFIG_DIR, "session.enc");
@@ -9425,7 +9432,7 @@ function ensureConfigDir() {
9425
9432
  import_node_fs2.default.chmodSync(CONFIG_DIR, 448);
9426
9433
  }
9427
9434
  function canUseMacKeychain() {
9428
- return process.platform === "darwin" && process.env.TRAINFABRIC_DISABLE_KEYCHAIN !== "1" && process.env.CI !== "1" && (0, import_node_child_process.spawnSync)("security", ["-h"]).status === 0;
9435
+ return process.platform === "darwin" && process.stdin.isTTY === true && process.env.TRAINFABRIC_DISABLE_KEYCHAIN !== "1" && process.env.CI !== "1" && (0, import_node_child_process.spawnSync)("security", ["-h"], { timeout: 2e3 }).status === 0;
9429
9436
  }
9430
9437
  function encodeSecretPayload(payload) {
9431
9438
  return JSON.stringify(payload);
@@ -9444,16 +9451,25 @@ function saveSecret(payload) {
9444
9451
  ensureConfigDir();
9445
9452
  const secret = encodeSecretPayload(payload);
9446
9453
  if (canUseMacKeychain()) {
9447
- (0, import_node_child_process.spawnSync)("security", ["delete-generic-password", "-a", import_node_os2.default.userInfo().username, "-s", KEYCHAIN_SERVICE]);
9448
- (0, import_node_child_process.spawnSync)("security", ["add-generic-password", "-a", import_node_os2.default.userInfo().username, "-s", KEYCHAIN_SERVICE, "-w", secret]);
9449
- return;
9454
+ (0, import_node_child_process.spawnSync)("security", ["delete-generic-password", "-a", import_node_os2.default.userInfo().username, "-s", KEYCHAIN_SERVICE], {
9455
+ timeout: 2e3
9456
+ });
9457
+ const result = (0, import_node_child_process.spawnSync)(
9458
+ "security",
9459
+ ["add-generic-password", "-a", import_node_os2.default.userInfo().username, "-s", KEYCHAIN_SERVICE, "-w", secret],
9460
+ { timeout: 2e3 }
9461
+ );
9462
+ if (result.status === 0) {
9463
+ return;
9464
+ }
9450
9465
  }
9451
9466
  import_node_fs2.default.writeFileSync(FALLBACK_SECRET_PATH, encrypt(secret), { mode: 384 });
9452
9467
  }
9453
9468
  function readSecret() {
9454
9469
  if (canUseMacKeychain()) {
9455
9470
  const result = (0, import_node_child_process.spawnSync)("security", ["find-generic-password", "-a", import_node_os2.default.userInfo().username, "-s", KEYCHAIN_SERVICE, "-w"], {
9456
- encoding: "utf8"
9471
+ encoding: "utf8",
9472
+ timeout: 2e3
9457
9473
  });
9458
9474
  if (result.status === 0) {
9459
9475
  return decodeSecretPayload(result.stdout.trim());
@@ -9466,7 +9482,9 @@ function readSecret() {
9466
9482
  }
9467
9483
  function deleteSecret() {
9468
9484
  if (canUseMacKeychain()) {
9469
- (0, import_node_child_process.spawnSync)("security", ["delete-generic-password", "-a", import_node_os2.default.userInfo().username, "-s", KEYCHAIN_SERVICE]);
9485
+ (0, import_node_child_process.spawnSync)("security", ["delete-generic-password", "-a", import_node_os2.default.userInfo().username, "-s", KEYCHAIN_SERVICE], {
9486
+ timeout: 2e3
9487
+ });
9470
9488
  }
9471
9489
  if (import_node_fs2.default.existsSync(FALLBACK_SECRET_PATH)) {
9472
9490
  import_node_fs2.default.rmSync(FALLBACK_SECRET_PATH, { force: true });
@@ -9976,10 +9994,12 @@ program2.command("runtime:detect").option("--project <projectId>").option("--rep
9976
9994
  program2.command("runtime:build").option("--project <projectId>").requiredOption("--detection <detectionId>").description("Build or reuse a cached runtime image from a runtime detection").action(async (options) => {
9977
9995
  const config = loadConfig();
9978
9996
  printJson(
9979
- await createClient(config).runtime.build({
9980
- projectId: requireProjectId(options, config),
9981
- detectionId: normalizeId(options.detection, "detection", "Runtime detection ID")
9982
- })
9997
+ redactInlineSource(
9998
+ await createClient(config).runtime.build({
9999
+ projectId: requireProjectId(options, config),
10000
+ detectionId: normalizeId(options.detection, "detection", "Runtime detection ID")
10001
+ })
10002
+ )
9983
10003
  );
9984
10004
  });
9985
10005
  program2.command("runs:quote").option("--project <projectId>").requiredOption("--dataset <datasetId>").requiredOption("--model <baseModel>").option("--eval <evalDatasetId>").option("--gpus <gpuCount>", "gpu count", "1").option("--nodes <nodeCount>", "node count", "1").option("--accelerator <acceleratorClass>", "optional hard accelerator constraint (for example: a10g, a100, h100)").option("--min-memory <gigabytes>", "minimum GPU memory in GB").option("--precision <precision>", "fp16_bf16, fp8, or fp32").option("--interconnect <interconnect>", "pcie or nvlink").option("--mode <mode>", "efficient, balanced, or power").option("--repo <path>").option("--git <url>").option("--branch <branch>").option("--summary", "print a human-readable price summary instead of raw JSON").description("Preview Efficient, Balanced, and Power launch options").action(async (options) => {
@@ -9999,7 +10019,8 @@ program2.command("runs:list").option("--project <projectId>").description("List
9999
10019
  printJson(await createClient(loadConfig()).runs.list(normalizeOptionalId(options.project, "project", "Project ID")));
10000
10020
  });
10001
10021
  program2.command("runs:status").argument("<runId>").description("Fetch full run detail").action(async (runId) => {
10002
- printJson(await createClient(loadConfig()).runs.get(normalizeId(runId, "run", "Run ID")));
10022
+ const detail = await createClient(loadConfig()).runs.get(normalizeId(runId, "run", "Run ID"));
10023
+ printJson({ ...detail, ...detail.run });
10003
10024
  });
10004
10025
  program2.command("runs:logs").argument("<runId>").description("Fetch run logs").action(async (runId) => {
10005
10026
  printJson(await createClient(loadConfig()).runs.logs(normalizeId(runId, "run", "Run ID")));
@@ -10065,7 +10086,7 @@ program2.command("models:export").argument("<modelId>").description("Fetch the e
10065
10086
  program2.command("deployments:list").description("List deployments").action(async () => {
10066
10087
  printJson(await createClient(loadConfig()).deployments.list());
10067
10088
  });
10068
- program2.command("deployments:create").requiredOption("--model <modelId>").option("--project <projectId>", "accepted for consistency; deployment project is inferred from the model").description("Create a deployment for a model").action(async (options) => {
10089
+ program2.command("deployments:create").requiredOption("--model <modelId>").option("--project <projectId>", "accepted for consistency; deployment project is inferred from the model").description("Create a hosted deployment for a model. Requires TRAINING_DEPLOYMENT_BASE_URL to be configured on the backend.").action(async (options) => {
10069
10090
  const config = loadConfig();
10070
10091
  const client = createClient(config);
10071
10092
  const projectId = normalizeOptionalId(options.project, "project", "Project ID");
@@ -10092,12 +10113,10 @@ program2.command("billing:summary").description("Fetch billing summary").action(
10092
10113
  printJson(await createClient(loadConfig()).billing.getSummary());
10093
10114
  });
10094
10115
  program2.command("billing:usage").option("--unit <unit>", "normalized_tflop_seconds, reserved_gpu_seconds, or usd").option("--run <runId>", "filter usage records to one run").description("List billing usage records").action(async (options) => {
10095
- printJson(
10096
- await createClient(loadConfig()).billing.getUsage(
10097
- normalizeOptionalBillingUnit(options.unit),
10098
- normalizeOptionalId(options.run, "run", "Run ID")
10099
- )
10100
- );
10116
+ const runId = normalizeOptionalId(options.run, "run", "Run ID");
10117
+ const unit = normalizeOptionalBillingUnit(options.unit);
10118
+ const client = createClient(loadConfig());
10119
+ printJson(runId && !unit ? await client.billing.getRunUsage(runId) : await client.billing.getUsage(unit, runId));
10101
10120
  });
10102
10121
  program2.command("billing:invoices").description("List invoices").action(async () => {
10103
10122
  printJson(await createClient(loadConfig()).billing.listInvoices());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trainfabric",
3
- "version": "0.1.34",
3
+ "version": "0.1.36",
4
4
  "description": "Trainfabric CLI for launching GPU training jobs on the hosted Trainfabric backend.",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",