trainfabric 0.1.35 → 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 +30 -14
  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.35";
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 });
@@ -10068,7 +10086,7 @@ program2.command("models:export").argument("<modelId>").description("Fetch the e
10068
10086
  program2.command("deployments:list").description("List deployments").action(async () => {
10069
10087
  printJson(await createClient(loadConfig()).deployments.list());
10070
10088
  });
10071
- 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) => {
10072
10090
  const config = loadConfig();
10073
10091
  const client = createClient(config);
10074
10092
  const projectId = normalizeOptionalId(options.project, "project", "Project ID");
@@ -10095,12 +10113,10 @@ program2.command("billing:summary").description("Fetch billing summary").action(
10095
10113
  printJson(await createClient(loadConfig()).billing.getSummary());
10096
10114
  });
10097
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) => {
10098
- printJson(
10099
- await createClient(loadConfig()).billing.getUsage(
10100
- normalizeOptionalBillingUnit(options.unit),
10101
- normalizeOptionalId(options.run, "run", "Run ID")
10102
- )
10103
- );
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));
10104
10120
  });
10105
10121
  program2.command("billing:invoices").description("List invoices").action(async () => {
10106
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.35",
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",