@hathbanger/jr-studio 0.0.4 → 0.0.6

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.js +491 -208
  2. package/package.json +14 -11
package/dist/index.js CHANGED
@@ -967,8 +967,8 @@ var require_command = __commonJS({
967
967
  "../../node_modules/.pnpm/commander@12.1.0/node_modules/commander/lib/command.js"(exports2) {
968
968
  var EventEmitter = require("node:events").EventEmitter;
969
969
  var childProcess = require("node:child_process");
970
- var path5 = require("node:path");
971
- var fs5 = require("node:fs");
970
+ var path6 = require("node:path");
971
+ var fs6 = require("node:fs");
972
972
  var process2 = require("node:process");
973
973
  var { Argument: Argument2, humanReadableArgName } = require_argument();
974
974
  var { CommanderError: CommanderError2 } = require_error();
@@ -1900,11 +1900,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
1900
1900
  let launchWithNode = false;
1901
1901
  const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
1902
1902
  function findFile(baseDir, baseName) {
1903
- const localBin = path5.resolve(baseDir, baseName);
1904
- if (fs5.existsSync(localBin)) return localBin;
1905
- if (sourceExt.includes(path5.extname(baseName))) return void 0;
1903
+ const localBin = path6.resolve(baseDir, baseName);
1904
+ if (fs6.existsSync(localBin)) return localBin;
1905
+ if (sourceExt.includes(path6.extname(baseName))) return void 0;
1906
1906
  const foundExt = sourceExt.find(
1907
- (ext) => fs5.existsSync(`${localBin}${ext}`)
1907
+ (ext) => fs6.existsSync(`${localBin}${ext}`)
1908
1908
  );
1909
1909
  if (foundExt) return `${localBin}${foundExt}`;
1910
1910
  return void 0;
@@ -1916,21 +1916,21 @@ Expecting one of '${allowedValues.join("', '")}'`);
1916
1916
  if (this._scriptPath) {
1917
1917
  let resolvedScriptPath;
1918
1918
  try {
1919
- resolvedScriptPath = fs5.realpathSync(this._scriptPath);
1919
+ resolvedScriptPath = fs6.realpathSync(this._scriptPath);
1920
1920
  } catch (err) {
1921
1921
  resolvedScriptPath = this._scriptPath;
1922
1922
  }
1923
- executableDir = path5.resolve(
1924
- path5.dirname(resolvedScriptPath),
1923
+ executableDir = path6.resolve(
1924
+ path6.dirname(resolvedScriptPath),
1925
1925
  executableDir
1926
1926
  );
1927
1927
  }
1928
1928
  if (executableDir) {
1929
1929
  let localFile = findFile(executableDir, executableFile);
1930
1930
  if (!localFile && !subcommand._executableFile && this._scriptPath) {
1931
- const legacyName = path5.basename(
1931
+ const legacyName = path6.basename(
1932
1932
  this._scriptPath,
1933
- path5.extname(this._scriptPath)
1933
+ path6.extname(this._scriptPath)
1934
1934
  );
1935
1935
  if (legacyName !== this._name) {
1936
1936
  localFile = findFile(
@@ -1941,7 +1941,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1941
1941
  }
1942
1942
  executableFile = localFile || executableFile;
1943
1943
  }
1944
- launchWithNode = sourceExt.includes(path5.extname(executableFile));
1944
+ launchWithNode = sourceExt.includes(path6.extname(executableFile));
1945
1945
  let proc;
1946
1946
  if (process2.platform !== "win32") {
1947
1947
  if (launchWithNode) {
@@ -2781,7 +2781,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2781
2781
  * @return {Command}
2782
2782
  */
2783
2783
  nameFromFilename(filename) {
2784
- this._name = path5.basename(filename, path5.extname(filename));
2784
+ this._name = path6.basename(filename, path6.extname(filename));
2785
2785
  return this;
2786
2786
  }
2787
2787
  /**
@@ -2795,9 +2795,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
2795
2795
  * @param {string} [path]
2796
2796
  * @return {(string|null|Command)}
2797
2797
  */
2798
- executableDir(path6) {
2799
- if (path6 === void 0) return this._executableDir;
2800
- this._executableDir = path6;
2798
+ executableDir(path7) {
2799
+ if (path7 === void 0) return this._executableDir;
2800
+ this._executableDir = path7;
2801
2801
  return this;
2802
2802
  }
2803
2803
  /**
@@ -3897,15 +3897,15 @@ var require_route = __commonJS({
3897
3897
  };
3898
3898
  }
3899
3899
  function wrapConversion(toModel, graph) {
3900
- const path5 = [graph[toModel].parent, toModel];
3900
+ const path6 = [graph[toModel].parent, toModel];
3901
3901
  let fn = conversions[graph[toModel].parent][toModel];
3902
3902
  let cur = graph[toModel].parent;
3903
3903
  while (graph[cur].parent) {
3904
- path5.unshift(graph[cur].parent);
3904
+ path6.unshift(graph[cur].parent);
3905
3905
  fn = link(conversions[graph[cur].parent][cur], fn);
3906
3906
  cur = graph[cur].parent;
3907
3907
  }
3908
- fn.conversion = path5;
3908
+ fn.conversion = path6;
3909
3909
  return fn;
3910
3910
  }
3911
3911
  module2.exports = function(fromModel) {
@@ -7063,7 +7063,7 @@ var require_buffer_list = __commonJS({
7063
7063
  }
7064
7064
  }, {
7065
7065
  key: "join",
7066
- value: function join6(s) {
7066
+ value: function join7(s) {
7067
7067
  if (this.length === 0) return "";
7068
7068
  var p = this.head;
7069
7069
  var ret = "" + p.data;
@@ -10036,7 +10036,7 @@ var require_bl = __commonJS({
10036
10036
  var require_ora = __commonJS({
10037
10037
  "../../node_modules/.pnpm/ora@5.4.1/node_modules/ora/index.js"(exports2, module2) {
10038
10038
  "use strict";
10039
- var readline4 = require("readline");
10039
+ var readline5 = require("readline");
10040
10040
  var chalk = require_source();
10041
10041
  var cliCursor = require_cli_cursor();
10042
10042
  var cliSpinners = require_cli_spinners();
@@ -10089,7 +10089,7 @@ var require_ora = __commonJS({
10089
10089
  if (process.platform === "win32") {
10090
10090
  return;
10091
10091
  }
10092
- this.rl = readline4.createInterface({
10092
+ this.rl = readline5.createInterface({
10093
10093
  input: process.stdin,
10094
10094
  output: this.mutedStream
10095
10095
  });
@@ -19598,22 +19598,22 @@ var require_nacl_fast = __commonJS({
19598
19598
  randombytes = fn;
19599
19599
  };
19600
19600
  (function() {
19601
- var crypto4 = typeof self !== "undefined" ? self.crypto || self.msCrypto : null;
19602
- if (crypto4 && crypto4.getRandomValues) {
19601
+ var crypto3 = typeof self !== "undefined" ? self.crypto || self.msCrypto : null;
19602
+ if (crypto3 && crypto3.getRandomValues) {
19603
19603
  var QUOTA = 65536;
19604
19604
  nacl2.setPRNG(function(x, n) {
19605
19605
  var i, v = new Uint8Array(n);
19606
19606
  for (i = 0; i < n; i += QUOTA) {
19607
- crypto4.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA)));
19607
+ crypto3.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA)));
19608
19608
  }
19609
19609
  for (i = 0; i < n; i++) x[i] = v[i];
19610
19610
  cleanup(v);
19611
19611
  });
19612
19612
  } else if (typeof require !== "undefined") {
19613
- crypto4 = require("crypto");
19614
- if (crypto4 && crypto4.randomBytes) {
19613
+ crypto3 = require("crypto");
19614
+ if (crypto3 && crypto3.randomBytes) {
19615
19615
  nacl2.setPRNG(function(x, n) {
19616
- var i, v = crypto4.randomBytes(n);
19616
+ var i, v = crypto3.randomBytes(n);
19617
19617
  for (i = 0; i < n; i++) x[i] = v[i];
19618
19618
  cleanup(v);
19619
19619
  });
@@ -29750,28 +29750,28 @@ var require_valid_url = __commonJS({
29750
29750
  var splitted = [];
29751
29751
  var scheme = "";
29752
29752
  var authority = "";
29753
- var path5 = "";
29753
+ var path6 = "";
29754
29754
  var query = "";
29755
29755
  var fragment = "";
29756
29756
  var out = "";
29757
29757
  splitted = splitUri(value);
29758
29758
  scheme = splitted[1];
29759
29759
  authority = splitted[2];
29760
- path5 = splitted[3];
29760
+ path6 = splitted[3];
29761
29761
  query = splitted[4];
29762
29762
  fragment = splitted[5];
29763
- if (!(scheme && scheme.length && path5.length >= 0)) return;
29763
+ if (!(scheme && scheme.length && path6.length >= 0)) return;
29764
29764
  if (authority && authority.length) {
29765
- if (!(path5.length === 0 || /^\//.test(path5))) return;
29765
+ if (!(path6.length === 0 || /^\//.test(path6))) return;
29766
29766
  } else {
29767
- if (/^\/\//.test(path5)) return;
29767
+ if (/^\/\//.test(path6)) return;
29768
29768
  }
29769
29769
  if (!/^[a-z][a-z0-9\+\-\.]*$/.test(scheme.toLowerCase())) return;
29770
29770
  out += scheme + ":";
29771
29771
  if (authority && authority.length) {
29772
29772
  out += "//" + authority;
29773
29773
  }
29774
- out += path5;
29774
+ out += path6;
29775
29775
  if (query && query.length) {
29776
29776
  out += "?" + query;
29777
29777
  }
@@ -29787,7 +29787,7 @@ var require_valid_url = __commonJS({
29787
29787
  var splitted = [];
29788
29788
  var scheme = "";
29789
29789
  var authority = "";
29790
- var path5 = "";
29790
+ var path6 = "";
29791
29791
  var port = "";
29792
29792
  var query = "";
29793
29793
  var fragment = "";
@@ -29795,7 +29795,7 @@ var require_valid_url = __commonJS({
29795
29795
  splitted = splitUri(value);
29796
29796
  scheme = splitted[1];
29797
29797
  authority = splitted[2];
29798
- path5 = splitted[3];
29798
+ path6 = splitted[3];
29799
29799
  query = splitted[4];
29800
29800
  fragment = splitted[5];
29801
29801
  if (!scheme) return;
@@ -29816,7 +29816,7 @@ var require_valid_url = __commonJS({
29816
29816
  if (port) {
29817
29817
  out += port;
29818
29818
  }
29819
- out += path5;
29819
+ out += path6;
29820
29820
  if (query && query.length) {
29821
29821
  out += "?" + query;
29822
29822
  }
@@ -33229,12 +33229,12 @@ var require_abstract_coder = __commonJS({
33229
33229
  exports2.Result = Result;
33230
33230
  function checkResultErrors(result) {
33231
33231
  const errors = [];
33232
- const checkErrors = function(path5, object) {
33232
+ const checkErrors = function(path6, object) {
33233
33233
  if (!Array.isArray(object)) {
33234
33234
  return;
33235
33235
  }
33236
33236
  for (let key in object) {
33237
- const childPath = path5.slice();
33237
+ const childPath = path6.slice();
33238
33238
  childPath.push(key);
33239
33239
  try {
33240
33240
  checkErrors(childPath, object[key]);
@@ -52270,8 +52270,8 @@ var require_constants2 = __commonJS({
52270
52270
  // ../../node_modules/.pnpm/node-gyp-build@4.8.4/node_modules/node-gyp-build/node-gyp-build.js
52271
52271
  var require_node_gyp_build = __commonJS({
52272
52272
  "../../node_modules/.pnpm/node-gyp-build@4.8.4/node_modules/node-gyp-build/node-gyp-build.js"(exports2, module2) {
52273
- var fs5 = require("fs");
52274
- var path5 = require("path");
52273
+ var fs6 = require("fs");
52274
+ var path6 = require("path");
52275
52275
  var os4 = require("os");
52276
52276
  var runtimeRequire = typeof __webpack_require__ === "function" ? __non_webpack_require__ : require;
52277
52277
  var vars = process.config && process.config.variables || {};
@@ -52288,21 +52288,21 @@ var require_node_gyp_build = __commonJS({
52288
52288
  return runtimeRequire(load.resolve(dir));
52289
52289
  }
52290
52290
  load.resolve = load.path = function(dir) {
52291
- dir = path5.resolve(dir || ".");
52291
+ dir = path6.resolve(dir || ".");
52292
52292
  try {
52293
- var name = runtimeRequire(path5.join(dir, "package.json")).name.toUpperCase().replace(/-/g, "_");
52293
+ var name = runtimeRequire(path6.join(dir, "package.json")).name.toUpperCase().replace(/-/g, "_");
52294
52294
  if (process.env[name + "_PREBUILD"]) dir = process.env[name + "_PREBUILD"];
52295
52295
  } catch (err) {
52296
52296
  }
52297
52297
  if (!prebuildsOnly) {
52298
- var release = getFirst(path5.join(dir, "build/Release"), matchBuild);
52298
+ var release = getFirst(path6.join(dir, "build/Release"), matchBuild);
52299
52299
  if (release) return release;
52300
- var debug = getFirst(path5.join(dir, "build/Debug"), matchBuild);
52300
+ var debug = getFirst(path6.join(dir, "build/Debug"), matchBuild);
52301
52301
  if (debug) return debug;
52302
52302
  }
52303
52303
  var prebuild = resolve(dir);
52304
52304
  if (prebuild) return prebuild;
52305
- var nearby = resolve(path5.dirname(process.execPath));
52305
+ var nearby = resolve(path6.dirname(process.execPath));
52306
52306
  if (nearby) return nearby;
52307
52307
  var target = [
52308
52308
  "platform=" + platform,
@@ -52319,26 +52319,26 @@ var require_node_gyp_build = __commonJS({
52319
52319
  ].filter(Boolean).join(" ");
52320
52320
  throw new Error("No native build was found for " + target + "\n loaded from: " + dir + "\n");
52321
52321
  function resolve(dir2) {
52322
- var tuples = readdirSync(path5.join(dir2, "prebuilds")).map(parseTuple);
52322
+ var tuples = readdirSync(path6.join(dir2, "prebuilds")).map(parseTuple);
52323
52323
  var tuple = tuples.filter(matchTuple(platform, arch)).sort(compareTuples)[0];
52324
52324
  if (!tuple) return;
52325
- var prebuilds = path5.join(dir2, "prebuilds", tuple.name);
52325
+ var prebuilds = path6.join(dir2, "prebuilds", tuple.name);
52326
52326
  var parsed = readdirSync(prebuilds).map(parseTags);
52327
52327
  var candidates = parsed.filter(matchTags(runtime, abi2));
52328
52328
  var winner = candidates.sort(compareTags(runtime))[0];
52329
- if (winner) return path5.join(prebuilds, winner.file);
52329
+ if (winner) return path6.join(prebuilds, winner.file);
52330
52330
  }
52331
52331
  };
52332
52332
  function readdirSync(dir) {
52333
52333
  try {
52334
- return fs5.readdirSync(dir);
52334
+ return fs6.readdirSync(dir);
52335
52335
  } catch (err) {
52336
52336
  return [];
52337
52337
  }
52338
52338
  }
52339
52339
  function getFirst(dir, filter) {
52340
52340
  var files = readdirSync(dir).filter(filter);
52341
- return files[0] && path5.join(dir, files[0]);
52341
+ return files[0] && path6.join(dir, files[0]);
52342
52342
  }
52343
52343
  function matchBuild(name) {
52344
52344
  return /\.node$/.test(name);
@@ -52425,7 +52425,7 @@ var require_node_gyp_build = __commonJS({
52425
52425
  return typeof window !== "undefined" && window.process && window.process.type === "renderer";
52426
52426
  }
52427
52427
  function isAlpine(platform2) {
52428
- return platform2 === "linux" && fs5.existsSync("/etc/alpine-release");
52428
+ return platform2 === "linux" && fs6.existsSync("/etc/alpine-release");
52429
52429
  }
52430
52430
  load.parseTags = parseTags;
52431
52431
  load.matchTags = matchTags;
@@ -57817,9 +57817,9 @@ var require_provider_ipcsocket = __commonJS({
57817
57817
  get socket() {
57818
57818
  return this.#socket;
57819
57819
  }
57820
- constructor(path5, network, options) {
57820
+ constructor(path6, network, options) {
57821
57821
  super(network, options);
57822
- this.#socket = (0, net_1.connect)(path5);
57822
+ this.#socket = (0, net_1.connect)(path6);
57823
57823
  this.socket.on("ready", async () => {
57824
57824
  try {
57825
57825
  await this._start();
@@ -59159,11 +59159,11 @@ var require_utils6 = __commonJS({
59159
59159
  function spelunk(object, _path) {
59160
59160
  const match = _path.match(/^([a-z0-9$_.-]*)(:([a-z]+))?(!)?$/i);
59161
59161
  (0, index_js_1.assertArgument)(match != null, "invalid path", "path", _path);
59162
- const path5 = match[1];
59162
+ const path6 = match[1];
59163
59163
  const type = match[3];
59164
59164
  const reqd = match[4] === "!";
59165
59165
  let cur = object;
59166
- for (const comp of path5.toLowerCase().split(".")) {
59166
+ for (const comp of path6.toLowerCase().split(".")) {
59167
59167
  if (Array.isArray(cur)) {
59168
59168
  if (!comp.match(/^[0-9]+$/)) {
59169
59169
  break;
@@ -59185,7 +59185,7 @@ var require_utils6 = __commonJS({
59185
59185
  break;
59186
59186
  }
59187
59187
  }
59188
- (0, index_js_1.assertArgument)(!reqd || cur != null, "missing required value", "path", path5);
59188
+ (0, index_js_1.assertArgument)(!reqd || cur != null, "missing required value", "path", path6);
59189
59189
  if (type && cur != null) {
59190
59190
  if (type === "int") {
59191
59191
  if (typeof cur === "string" && cur.match(/^-?[0-9]+$/)) {
@@ -59210,7 +59210,7 @@ var require_utils6 = __commonJS({
59210
59210
  if (type === typeof cur) {
59211
59211
  return cur;
59212
59212
  }
59213
- (0, index_js_1.assertArgument)(false, `wrong type found for ${type} `, "path", path5);
59213
+ (0, index_js_1.assertArgument)(false, `wrong type found for ${type} `, "path", path6);
59214
59214
  }
59215
59215
  return cur;
59216
59216
  }
@@ -59408,7 +59408,7 @@ var require_json_keystore = __commonJS({
59408
59408
  };
59409
59409
  if (account.mnemonic) {
59410
59410
  const client = options.client != null ? options.client : `ethers/${_version_js_1.version}`;
59411
- const path5 = account.mnemonic.path || defaultPath;
59411
+ const path6 = account.mnemonic.path || defaultPath;
59412
59412
  const locale = account.mnemonic.locale || "en";
59413
59413
  const mnemonicKey = key.slice(32, 64);
59414
59414
  const entropy = (0, index_js_4.getBytes)(account.mnemonic.entropy, "account.mnemonic.entropy");
@@ -59421,7 +59421,7 @@ var require_json_keystore = __commonJS({
59421
59421
  data["x-ethers"] = {
59422
59422
  client,
59423
59423
  gethFilename,
59424
- path: path5,
59424
+ path: path6,
59425
59425
  locale,
59426
59426
  mnemonicCounter: (0, index_js_4.hexlify)(mnemonicIv).substring(2),
59427
59427
  mnemonicCiphertext: (0, index_js_4.hexlify)(mnemonicCiphertext).substring(2),
@@ -59506,11 +59506,11 @@ var require_hdwallet = __commonJS({
59506
59506
  const I = (0, index_js_4.getBytes)((0, index_js_1.computeHmac)("sha512", chainCode, data));
59507
59507
  return { IL: I.slice(0, 32), IR: I.slice(32) };
59508
59508
  }
59509
- function derivePath(node, path5) {
59510
- const components = path5.split("/");
59511
- (0, index_js_4.assertArgument)(components.length > 0, "invalid path", "path", path5);
59509
+ function derivePath(node, path6) {
59510
+ const components = path6.split("/");
59511
+ (0, index_js_4.assertArgument)(components.length > 0, "invalid path", "path", path6);
59512
59512
  if (components[0] === "m") {
59513
- (0, index_js_4.assertArgument)(node.depth === 0, `cannot derive root path (i.e. path starting with "m/") for a node at non-zero depth ${node.depth}`, "path", path5);
59513
+ (0, index_js_4.assertArgument)(node.depth === 0, `cannot derive root path (i.e. path starting with "m/") for a node at non-zero depth ${node.depth}`, "path", path6);
59514
59514
  components.shift();
59515
59515
  }
59516
59516
  let result = node;
@@ -59580,7 +59580,7 @@ var require_hdwallet = __commonJS({
59580
59580
  /**
59581
59581
  * @private
59582
59582
  */
59583
- constructor(guard, signingKey, parentFingerprint, chainCode, path5, index2, depth, mnemonic, provider) {
59583
+ constructor(guard, signingKey, parentFingerprint, chainCode, path6, index2, depth, mnemonic, provider) {
59584
59584
  super(signingKey, provider);
59585
59585
  (0, index_js_4.assertPrivate)(guard, _guard, "HDNodeWallet");
59586
59586
  (0, index_js_4.defineProperties)(this, { publicKey: signingKey.compressedPublicKey });
@@ -59589,7 +59589,7 @@ var require_hdwallet = __commonJS({
59589
59589
  parentFingerprint,
59590
59590
  fingerprint,
59591
59591
  chainCode,
59592
- path: path5,
59592
+ path: path6,
59593
59593
  index: index2,
59594
59594
  depth
59595
59595
  });
@@ -59673,22 +59673,22 @@ var require_hdwallet = __commonJS({
59673
59673
  deriveChild(_index) {
59674
59674
  const index2 = (0, index_js_4.getNumber)(_index, "index");
59675
59675
  (0, index_js_4.assertArgument)(index2 <= 4294967295, "invalid index", "index", index2);
59676
- let path5 = this.path;
59677
- if (path5) {
59678
- path5 += "/" + (index2 & ~HardenedBit);
59676
+ let path6 = this.path;
59677
+ if (path6) {
59678
+ path6 += "/" + (index2 & ~HardenedBit);
59679
59679
  if (index2 & HardenedBit) {
59680
- path5 += "'";
59680
+ path6 += "'";
59681
59681
  }
59682
59682
  }
59683
59683
  const { IR, IL } = ser_I(index2, this.chainCode, this.publicKey, this.privateKey);
59684
59684
  const ki = new index_js_1.SigningKey((0, index_js_4.toBeHex)(((0, index_js_4.toBigInt)(IL) + BigInt(this.privateKey)) % N, 32));
59685
- return new _HDNodeWallet(_guard, ki, this.fingerprint, (0, index_js_4.hexlify)(IR), path5, index2, this.depth + 1, this.mnemonic, this.provider);
59685
+ return new _HDNodeWallet(_guard, ki, this.fingerprint, (0, index_js_4.hexlify)(IR), path6, index2, this.depth + 1, this.mnemonic, this.provider);
59686
59686
  }
59687
59687
  /**
59688
59688
  * Return the HDNode for %%path%% from this node.
59689
59689
  */
59690
- derivePath(path5) {
59691
- return derivePath(this, path5);
59690
+ derivePath(path6) {
59691
+ return derivePath(this, path6);
59692
59692
  }
59693
59693
  static #fromSeed(_seed, mnemonic) {
59694
59694
  (0, index_js_4.assertArgument)((0, index_js_4.isBytesLike)(_seed), "invalid seed", "seed", "[REDACTED]");
@@ -59733,43 +59733,43 @@ var require_hdwallet = __commonJS({
59733
59733
  /**
59734
59734
  * Creates a new random HDNode.
59735
59735
  */
59736
- static createRandom(password, path5, wordlist2) {
59736
+ static createRandom(password, path6, wordlist2) {
59737
59737
  if (password == null) {
59738
59738
  password = "";
59739
59739
  }
59740
- if (path5 == null) {
59741
- path5 = exports2.defaultPath;
59740
+ if (path6 == null) {
59741
+ path6 = exports2.defaultPath;
59742
59742
  }
59743
59743
  if (wordlist2 == null) {
59744
59744
  wordlist2 = lang_en_js_1.LangEn.wordlist();
59745
59745
  }
59746
59746
  const mnemonic = mnemonic_js_1.Mnemonic.fromEntropy((0, index_js_1.randomBytes)(16), password, wordlist2);
59747
- return _HDNodeWallet.#fromSeed(mnemonic.computeSeed(), mnemonic).derivePath(path5);
59747
+ return _HDNodeWallet.#fromSeed(mnemonic.computeSeed(), mnemonic).derivePath(path6);
59748
59748
  }
59749
59749
  /**
59750
59750
  * Create an HD Node from %%mnemonic%%.
59751
59751
  */
59752
- static fromMnemonic(mnemonic, path5) {
59753
- if (!path5) {
59754
- path5 = exports2.defaultPath;
59752
+ static fromMnemonic(mnemonic, path6) {
59753
+ if (!path6) {
59754
+ path6 = exports2.defaultPath;
59755
59755
  }
59756
- return _HDNodeWallet.#fromSeed(mnemonic.computeSeed(), mnemonic).derivePath(path5);
59756
+ return _HDNodeWallet.#fromSeed(mnemonic.computeSeed(), mnemonic).derivePath(path6);
59757
59757
  }
59758
59758
  /**
59759
59759
  * Creates an HD Node from a mnemonic %%phrase%%.
59760
59760
  */
59761
- static fromPhrase(phrase, password, path5, wordlist2) {
59761
+ static fromPhrase(phrase, password, path6, wordlist2) {
59762
59762
  if (password == null) {
59763
59763
  password = "";
59764
59764
  }
59765
- if (path5 == null) {
59766
- path5 = exports2.defaultPath;
59765
+ if (path6 == null) {
59766
+ path6 = exports2.defaultPath;
59767
59767
  }
59768
59768
  if (wordlist2 == null) {
59769
59769
  wordlist2 = lang_en_js_1.LangEn.wordlist();
59770
59770
  }
59771
59771
  const mnemonic = mnemonic_js_1.Mnemonic.fromPhrase(phrase, password, wordlist2);
59772
- return _HDNodeWallet.#fromSeed(mnemonic.computeSeed(), mnemonic).derivePath(path5);
59772
+ return _HDNodeWallet.#fromSeed(mnemonic.computeSeed(), mnemonic).derivePath(path6);
59773
59773
  }
59774
59774
  /**
59775
59775
  * Creates an HD Node from a %%seed%%.
@@ -59822,7 +59822,7 @@ var require_hdwallet = __commonJS({
59822
59822
  /**
59823
59823
  * @private
59824
59824
  */
59825
- constructor(guard, address, publicKey, parentFingerprint, chainCode, path5, index2, depth, provider) {
59825
+ constructor(guard, address, publicKey, parentFingerprint, chainCode, path6, index2, depth, provider) {
59826
59826
  super(address, provider);
59827
59827
  (0, index_js_4.assertPrivate)(guard, _guard, "HDNodeVoidWallet");
59828
59828
  (0, index_js_4.defineProperties)(this, { publicKey });
@@ -59832,7 +59832,7 @@ var require_hdwallet = __commonJS({
59832
59832
  fingerprint,
59833
59833
  parentFingerprint,
59834
59834
  chainCode,
59835
- path: path5,
59835
+ path: path6,
59836
59836
  index: index2,
59837
59837
  depth
59838
59838
  });
@@ -59870,23 +59870,23 @@ var require_hdwallet = __commonJS({
59870
59870
  deriveChild(_index) {
59871
59871
  const index2 = (0, index_js_4.getNumber)(_index, "index");
59872
59872
  (0, index_js_4.assertArgument)(index2 <= 4294967295, "invalid index", "index", index2);
59873
- let path5 = this.path;
59874
- if (path5) {
59875
- path5 += "/" + (index2 & ~HardenedBit);
59873
+ let path6 = this.path;
59874
+ if (path6) {
59875
+ path6 += "/" + (index2 & ~HardenedBit);
59876
59876
  if (index2 & HardenedBit) {
59877
- path5 += "'";
59877
+ path6 += "'";
59878
59878
  }
59879
59879
  }
59880
59880
  const { IR, IL } = ser_I(index2, this.chainCode, this.publicKey, null);
59881
59881
  const Ki = index_js_1.SigningKey.addPoints(IL, this.publicKey, true);
59882
59882
  const address = (0, index_js_3.computeAddress)(Ki);
59883
- return new _HDNodeVoidWallet(_guard, address, Ki, this.fingerprint, (0, index_js_4.hexlify)(IR), path5, index2, this.depth + 1, this.provider);
59883
+ return new _HDNodeVoidWallet(_guard, address, Ki, this.fingerprint, (0, index_js_4.hexlify)(IR), path6, index2, this.depth + 1, this.provider);
59884
59884
  }
59885
59885
  /**
59886
59886
  * Return the signer for %%path%% from this node.
59887
59887
  */
59888
- derivePath(path5) {
59889
- return derivePath(this, path5);
59888
+ derivePath(path6) {
59889
+ return derivePath(this, path6);
59890
59890
  }
59891
59891
  };
59892
59892
  exports2.HDNodeVoidWallet = HDNodeVoidWallet;
@@ -62118,14 +62118,14 @@ var require_utils7 = __commonJS({
62118
62118
  return res === EIP1271_MAGICVALUE;
62119
62119
  });
62120
62120
  exports2.checkContractWalletSignature = checkContractWalletSignature;
62121
- var generateNonce = () => {
62121
+ var generateNonce2 = () => {
62122
62122
  const nonce = (0, random_1.randomStringForEntropy)(96);
62123
62123
  if (!nonce || nonce.length < 8) {
62124
62124
  throw new Error("Error during nonce creation.");
62125
62125
  }
62126
62126
  return nonce;
62127
62127
  };
62128
- exports2.generateNonce = generateNonce;
62128
+ exports2.generateNonce = generateNonce2;
62129
62129
  var isValidISO8601Date = (inputDate) => {
62130
62130
  const inputMatch = ISO8601.exec(inputDate);
62131
62131
  if (!inputDate) {
@@ -72594,14 +72594,14 @@ var HDKey = class _HDKey {
72594
72594
  }
72595
72595
  this.pubHash = hash160(this._publicKey);
72596
72596
  }
72597
- derive(path5) {
72598
- if (!/^[mM]'?/.test(path5)) {
72597
+ derive(path6) {
72598
+ if (!/^[mM]'?/.test(path6)) {
72599
72599
  throw new Error('Path must start with "m" or "M"');
72600
72600
  }
72601
- if (/^[mM]'?$/.test(path5)) {
72601
+ if (/^[mM]'?$/.test(path6)) {
72602
72602
  return this;
72603
72603
  }
72604
- const parts = path5.replace(/^[mM]'?\//, "").split("/");
72604
+ const parts = path6.replace(/^[mM]'?\//, "").split("/");
72605
72605
  let child = this;
72606
72606
  for (const c of parts) {
72607
72607
  const m = /^(\d+)('?)$/.exec(c);
@@ -73898,59 +73898,156 @@ function getPrivateKey(password = "") {
73898
73898
  // src/lib/api-fetch.ts
73899
73899
  var readline2 = __toESM(require("readline"));
73900
73900
 
73901
- // src/lib/http-sig.ts
73902
- async function generateSigningKeyPair() {
73903
- const keyPair = await crypto.subtle.generateKey("Ed25519", true, ["sign", "verify"]);
73904
- const publicKeyRaw = await crypto.subtle.exportKey("raw", keyPair.publicKey);
73905
- const privateKeyPkcs8 = await crypto.subtle.exportKey("pkcs8", keyPair.privateKey);
73901
+ // ../../node_modules/.pnpm/@hathbanger+tap-core@1.0.0/node_modules/@hathbanger/tap-core/dist/keys.js
73902
+ var import_node_crypto2 = require("node:crypto");
73903
+ var subtle = import_node_crypto2.webcrypto.subtle;
73904
+ async function generateKeyPair() {
73905
+ const result = await subtle.generateKey({ name: "Ed25519" }, true, ["sign", "verify"]);
73906
+ const { privateKey, publicKey } = result;
73907
+ const publicJwk = await subtle.exportKey("jwk", publicKey);
73908
+ const keyId = await deriveKeyId(publicJwk);
73906
73909
  return {
73907
- publicKey: Buffer.from(publicKeyRaw).toString("base64"),
73908
- privateKey: Buffer.from(privateKeyPkcs8).toString("base64")
73910
+ keyId,
73911
+ privateKey,
73912
+ publicKey,
73913
+ jwk: { ...publicJwk, kid: keyId, use: "sig", alg: "EdDSA" }
73909
73914
  };
73910
73915
  }
73911
- async function signRequest(opts) {
73912
- const { method, url, headers, keyId, privateKeyBase64 } = opts;
73913
- const parsedUrl = new URL(url);
73914
- const created = Math.floor(Date.now() / 1e3);
73915
- const components = ["@method", "@path", "@authority"];
73916
- if (headers["content-type"]) components.push("content-type");
73917
- const paramStr = `(${components.map((c) => `"${c}"`).join(" ")});keyid="${keyId}";alg="ed25519";created=${created}`;
73918
- const lines = [];
73919
- for (const component of components) {
73920
- switch (component) {
73921
- case "@method":
73922
- lines.push(`"@method": ${method.toUpperCase()}`);
73923
- break;
73924
- case "@path":
73925
- lines.push(`"@path": ${parsedUrl.pathname}`);
73926
- break;
73927
- case "@authority":
73928
- lines.push(`"@authority": ${parsedUrl.host}`);
73929
- break;
73930
- default:
73931
- lines.push(`"${component}": ${headers[component]}`);
73932
- }
73933
- }
73934
- lines.push(`"@signature-params": ${paramStr}`);
73935
- const sigBase = lines.join("\n");
73936
- const privKeyDer = Buffer.from(privateKeyBase64, "base64");
73937
- const privateKey = await crypto.subtle.importKey(
73938
- "pkcs8",
73939
- privKeyDer,
73940
- { name: "Ed25519" },
73941
- false,
73942
- ["sign"]
73943
- );
73944
- const sigBytes = await crypto.subtle.sign(
73945
- { name: "Ed25519" },
73946
- privateKey,
73947
- new TextEncoder().encode(sigBase)
73948
- );
73916
+ async function importPrivateKey(jwk) {
73917
+ return subtle.importKey("jwk", jwk, { name: "Ed25519" }, false, ["sign"]);
73918
+ }
73919
+ async function importPublicKey(jwk) {
73920
+ return subtle.importKey("jwk", jwk, { name: "Ed25519" }, false, ["verify"]);
73921
+ }
73922
+ async function exportKeyPairToJwk(pair) {
73923
+ const privateJwk = await subtle.exportKey("jwk", pair.privateKey);
73924
+ const publicJwk = await subtle.exportKey("jwk", pair.publicKey);
73925
+ return {
73926
+ privateJwk: { ...privateJwk, kid: pair.keyId },
73927
+ publicJwk: { ...publicJwk, kid: pair.keyId, use: "sig" }
73928
+ };
73929
+ }
73930
+ async function loadKeyPairFromJwk(privateJwk) {
73931
+ const privateKey = await importPrivateKey(privateJwk);
73932
+ const publicJwk = {
73933
+ kty: privateJwk.kty,
73934
+ crv: privateJwk.crv,
73935
+ x: privateJwk.x,
73936
+ kid: privateJwk.kid,
73937
+ use: "sig"
73938
+ };
73939
+ const publicKey = await importPublicKey(publicJwk);
73940
+ const keyId = privateJwk.kid ?? await deriveKeyId(publicJwk);
73941
+ return { keyId, privateKey, publicKey, jwk: { ...publicJwk, kid: keyId } };
73942
+ }
73943
+ async function deriveKeyId(publicJwk) {
73944
+ const thumbprintInput = JSON.stringify({
73945
+ crv: publicJwk.crv,
73946
+ kty: publicJwk.kty,
73947
+ x: publicJwk.x
73948
+ });
73949
+ const encoded = new TextEncoder().encode(thumbprintInput);
73950
+ const hash4 = await subtle.digest("SHA-256", encoded);
73951
+ return base64url(hash4);
73952
+ }
73953
+ function base64url(buffer2) {
73954
+ const bytes = buffer2 instanceof ArrayBuffer ? new Uint8Array(buffer2) : buffer2;
73955
+ return Buffer.from(bytes).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
73956
+ }
73957
+ function base64urlDecode(str) {
73958
+ const padded = str.replace(/-/g, "+").replace(/_/g, "/");
73959
+ const pad5 = padded.length % 4;
73960
+ return Buffer.from(pad5 ? padded + "=".repeat(4 - pad5) : padded, "base64");
73961
+ }
73962
+
73963
+ // ../../node_modules/.pnpm/@hathbanger+tap-core@1.0.0/node_modules/@hathbanger/tap-core/dist/nonce.js
73964
+ var import_node_crypto3 = require("node:crypto");
73965
+ var SIGNATURE_WINDOW_SECONDS = 480;
73966
+ function generateNonce() {
73967
+ const bytes = import_node_crypto3.webcrypto.getRandomValues(new Uint8Array(24));
73968
+ return base64url(bytes.buffer);
73969
+ }
73970
+ function nowSeconds() {
73971
+ return Math.floor(Date.now() / 1e3);
73972
+ }
73973
+ function makeTimestamps() {
73974
+ const created = nowSeconds();
73975
+ return { created, expires: created + SIGNATURE_WINDOW_SECONDS };
73976
+ }
73977
+
73978
+ // ../../node_modules/.pnpm/@hathbanger+tap-core@1.0.0/node_modules/@hathbanger/tap-core/dist/sign.js
73979
+ var import_node_crypto4 = require("node:crypto");
73980
+ var subtle2 = import_node_crypto4.webcrypto.subtle;
73981
+ function buildSignatureBase(components, params) {
73982
+ const componentNames = components.map(([name]) => name);
73983
+ const paramsString = buildSignatureInputParams(componentNames, params);
73984
+ const lines = [
73985
+ ...components.map(([name, value]) => `"${name}": ${value}`),
73986
+ `"@signature-params": ${paramsString}`
73987
+ ];
73988
+ return lines.join("\n");
73989
+ }
73990
+ function buildSignatureInputParams(componentNames, params) {
73991
+ const components = `(${componentNames.map((n) => `"${n}"`).join(" ")})`;
73992
+ const attrs = [
73993
+ `created=${params.created}`,
73994
+ `expires=${params.expires}`,
73995
+ `nonce="${params.nonce}"`,
73996
+ `keyid="${params.keyId}"`,
73997
+ `alg="${params.alg}"`,
73998
+ `tag="${params.tag}"`
73999
+ ].join(";");
74000
+ return `${components};${attrs}`;
74001
+ }
74002
+ async function signRequest(keyPair, components, tag) {
74003
+ const { created, expires } = makeTimestamps();
74004
+ const nonce = generateNonce();
74005
+ const params = {
74006
+ tag,
74007
+ keyId: keyPair.keyId,
74008
+ alg: "ed25519",
74009
+ created,
74010
+ expires,
74011
+ nonce
74012
+ };
74013
+ const componentNames = components.map(([name]) => name);
74014
+ const paramsString = buildSignatureInputParams(componentNames, params);
74015
+ const signatureBase = buildSignatureBase(components, params);
74016
+ const encoded = new TextEncoder().encode(signatureBase);
74017
+ const signatureBuffer = await subtle2.sign("Ed25519", keyPair.privateKey, encoded);
74018
+ const signatureB64 = base64url(signatureBuffer);
74019
+ return {
74020
+ "signature-input": `sig1=${paramsString}`,
74021
+ signature: `sig1=:${signatureB64}:`
74022
+ };
74023
+ }
74024
+
74025
+ // ../../node_modules/.pnpm/@hathbanger+tap-core@1.0.0/node_modules/@hathbanger/tap-core/dist/verify.js
74026
+ var import_node_crypto5 = require("node:crypto");
74027
+ var subtle3 = import_node_crypto5.webcrypto.subtle;
74028
+
74029
+ // src/lib/http-sig.ts
74030
+ async function generateSigningKeyPair(walletAddress) {
74031
+ const pair = await generateKeyPair();
74032
+ const { privateJwk, publicJwk } = await exportKeyPairToJwk(pair);
74033
+ const kid = walletAddress.toLowerCase();
74034
+ const rawPubBytes = base64urlDecode(publicJwk.x);
73949
74035
  return {
73950
- "Signature-Input": `sig1=${paramStr}`,
73951
- Signature: `sig1=:${Buffer.from(sigBytes).toString("base64")}:`
74036
+ publicKeyBase64: Buffer.from(rawPubBytes).toString("base64"),
74037
+ privateJwk: { ...privateJwk, kid }
73952
74038
  };
73953
74039
  }
74040
+ async function signHttpRequest(opts) {
74041
+ const { method, url, privateJwk } = opts;
74042
+ const parsed = new URL(url);
74043
+ const pair = await loadKeyPairFromJwk(privateJwk);
74044
+ const components = [
74045
+ ["@method", method.toUpperCase()],
74046
+ ["@authority", parsed.host],
74047
+ ["@path", parsed.pathname]
74048
+ ];
74049
+ return signRequest(pair, components, "agent-browser-auth");
74050
+ }
73954
74051
 
73955
74052
  // src/lib/api-fetch.ts
73956
74053
  async function promptForUrl(reason) {
@@ -73966,32 +74063,21 @@ async function promptForUrl(reason) {
73966
74063
  });
73967
74064
  });
73968
74065
  }
73969
- async function buildSignedHeaders(method, url, options) {
74066
+ async function buildSignedHeaders(method, url) {
73970
74067
  const cfg = readJrConfig();
73971
- if (!cfg.signingKeyPrivate || !cfg.walletAddress) return {};
73972
- const existingHeaders = {};
73973
- if (options?.headers && typeof options.headers === "object" && !Array.isArray(options.headers)) {
73974
- for (const [k, v] of Object.entries(options.headers)) {
73975
- existingHeaders[k.toLowerCase()] = v;
73976
- }
73977
- }
74068
+ if (!cfg.signingKeyPrivateJwk) return {};
73978
74069
  try {
73979
- return await signRequest({
73980
- method,
73981
- url,
73982
- headers: existingHeaders,
73983
- keyId: cfg.walletAddress,
73984
- privateKeyBase64: cfg.signingKeyPrivate
73985
- });
74070
+ const privateJwk = JSON.parse(cfg.signingKeyPrivateJwk);
74071
+ return await signHttpRequest({ method, url, privateJwk });
73986
74072
  } catch {
73987
74073
  return {};
73988
74074
  }
73989
74075
  }
73990
- async function apiFetch(path5, options, _baseUrl) {
74076
+ async function apiFetch(path6, options, _baseUrl) {
73991
74077
  const base2 = _baseUrl ?? getApiUrl();
73992
- const url = `${base2}${path5}`;
74078
+ const url = `${base2}${path6}`;
73993
74079
  const method = options?.method ?? "GET";
73994
- const sigHeaders = await buildSignedHeaders(method, url, options);
74080
+ const sigHeaders = await buildSignedHeaders(method, url);
73995
74081
  const mergedOptions = {
73996
74082
  ...options,
73997
74083
  headers: {
@@ -74005,12 +74091,12 @@ async function apiFetch(path5, options, _baseUrl) {
74005
74091
  } catch (err) {
74006
74092
  const reason = `No response from ${url} \u2014 ${err.message}`;
74007
74093
  const newBase = await promptForUrl(reason);
74008
- return apiFetch(path5, options, newBase);
74094
+ return apiFetch(path6, options, newBase);
74009
74095
  }
74010
74096
  if (res.status === 404) {
74011
74097
  const reason = `404 Not Found at ${url}`;
74012
74098
  const newBase = await promptForUrl(reason);
74013
- return apiFetch(path5, options, newBase);
74099
+ return apiFetch(path6, options, newBase);
74014
74100
  }
74015
74101
  return res;
74016
74102
  }
@@ -74115,6 +74201,105 @@ async function downloadAction(generationId, options) {
74115
74201
  display.printTracks(trackDisplays);
74116
74202
  }
74117
74203
 
74204
+ // src/commands/export.ts
74205
+ var fs4 = __toESM(require("fs"));
74206
+ var path4 = __toESM(require("path"));
74207
+ async function exportAction(generationId, options) {
74208
+ const token = requireToken();
74209
+ const baseUrl = getApiUrl();
74210
+ const display = makeDisplay({});
74211
+ let durationSeconds;
74212
+ if (options.hours != null && options.hours !== "") {
74213
+ const hours = parseFloat(options.hours);
74214
+ if (!Number.isFinite(hours) || hours <= 0) {
74215
+ process.stderr.write("--hours must be a positive number.\n");
74216
+ process.exit(1);
74217
+ }
74218
+ durationSeconds = Math.round(hours * 3600);
74219
+ } else if (options.duration != null && options.duration !== "") {
74220
+ const n = parseInt(options.duration, 10);
74221
+ if (!Number.isInteger(n) || n < 1 || n > 14400) {
74222
+ process.stderr.write("--duration must be an integer between 1 and 14400 (seconds).\n");
74223
+ process.exit(1);
74224
+ }
74225
+ durationSeconds = n;
74226
+ } else {
74227
+ process.stderr.write("Provide --duration <seconds> or --hours <n> (e.g. --hours 1 for 1 hour).\n");
74228
+ process.exit(1);
74229
+ }
74230
+ const trackIndex = options.trackIndex != null ? parseInt(options.trackIndex, 10) : 0;
74231
+ if (!Number.isInteger(trackIndex) || trackIndex < 0) {
74232
+ process.stderr.write("--track-index must be a non-negative integer.\n");
74233
+ process.exit(1);
74234
+ }
74235
+ const spinner = display.startSpinner("Creating looped export...");
74236
+ let res;
74237
+ try {
74238
+ res = await apiFetch(`/api/generations/${generationId}/export`, {
74239
+ method: "POST",
74240
+ headers: {
74241
+ "Content-Type": "application/json",
74242
+ Authorization: `Bearer ${token}`,
74243
+ Cookie: `jr-auth=${token}`
74244
+ },
74245
+ body: JSON.stringify({
74246
+ duration_seconds: durationSeconds,
74247
+ track_index: trackIndex
74248
+ })
74249
+ });
74250
+ } catch (err) {
74251
+ display.stopSpinner(spinner, void 0, "Export request failed");
74252
+ process.stderr.write(`${err.message}
74253
+ `);
74254
+ process.exit(1);
74255
+ }
74256
+ display.stopSpinner(spinner);
74257
+ if (!res.ok) {
74258
+ const text = await res.text();
74259
+ process.stderr.write(`Error (${res.status}): ${text}
74260
+ `);
74261
+ process.exit(1);
74262
+ }
74263
+ const data = await res.json();
74264
+ if (options.json) {
74265
+ process.stdout.write(JSON.stringify(data, null, 2) + "\n");
74266
+ return;
74267
+ }
74268
+ process.stdout.write(`Export URL (${durationSeconds}s): ${data.export_url}
74269
+ `);
74270
+ process.stdout.write(`Duration: ${data.duration_seconds} seconds
74271
+ `);
74272
+ if (options.output) {
74273
+ const outSpinner = display.startSpinner("Downloading export...");
74274
+ try {
74275
+ const getRes = await fetch(data.export_url);
74276
+ if (!getRes.ok) {
74277
+ throw new Error(`Download failed: ${getRes.status}`);
74278
+ }
74279
+ const buffer2 = Buffer.from(await getRes.arrayBuffer());
74280
+ let outPath = options.output;
74281
+ try {
74282
+ const stat = fs4.statSync(outPath);
74283
+ if (stat.isDirectory()) {
74284
+ outPath = path4.join(outPath, `looped-${durationSeconds}s.mp3`);
74285
+ }
74286
+ } catch {
74287
+ if (!path4.extname(outPath)) {
74288
+ outPath = path4.join(outPath, `looped-${durationSeconds}s.mp3`);
74289
+ }
74290
+ }
74291
+ fs4.mkdirSync(path4.dirname(outPath), { recursive: true });
74292
+ fs4.writeFileSync(outPath, buffer2);
74293
+ display.stopSpinner(outSpinner, `Saved to ${outPath}`);
74294
+ } catch (err) {
74295
+ display.stopSpinner(outSpinner, void 0, "Download failed");
74296
+ process.stderr.write(`${err.message}
74297
+ `);
74298
+ process.exit(1);
74299
+ }
74300
+ }
74301
+ }
74302
+
74118
74303
  // src/commands/models.ts
74119
74304
  var MODELS = [
74120
74305
  { id: "suno-v4", maxDuration: "4 min", promptLimit: 3e3, styleLimit: 200, notes: "Improved vocal quality" },
@@ -74139,23 +74324,23 @@ function modelsAction() {
74139
74324
  }
74140
74325
 
74141
74326
  // src/lib/history.ts
74142
- var fs4 = __toESM(require("fs"));
74143
- var path4 = __toESM(require("path"));
74327
+ var fs5 = __toESM(require("fs"));
74328
+ var path5 = __toESM(require("path"));
74144
74329
  var os3 = __toESM(require("os"));
74145
- var HISTORY_DIR = path4.join(os3.homedir(), ".tunes");
74146
- var HISTORY_FILE = path4.join(HISTORY_DIR, "history.json");
74330
+ var HISTORY_DIR = path5.join(os3.homedir(), ".tunes");
74331
+ var HISTORY_FILE = path5.join(HISTORY_DIR, "history.json");
74147
74332
  function ensureHistoryDir() {
74148
- if (!fs4.existsSync(HISTORY_DIR)) {
74149
- fs4.mkdirSync(HISTORY_DIR, { recursive: true });
74333
+ if (!fs5.existsSync(HISTORY_DIR)) {
74334
+ fs5.mkdirSync(HISTORY_DIR, { recursive: true });
74150
74335
  }
74151
74336
  }
74152
74337
  function readHistory() {
74153
74338
  ensureHistoryDir();
74154
- if (!fs4.existsSync(HISTORY_FILE)) {
74339
+ if (!fs5.existsSync(HISTORY_FILE)) {
74155
74340
  return [];
74156
74341
  }
74157
74342
  try {
74158
- const raw = fs4.readFileSync(HISTORY_FILE, "utf8");
74343
+ const raw = fs5.readFileSync(HISTORY_FILE, "utf8");
74159
74344
  return JSON.parse(raw);
74160
74345
  } catch {
74161
74346
  return [];
@@ -74306,12 +74491,13 @@ async function loginAction() {
74306
74491
  console.log("\nSigning auth message...");
74307
74492
  const signature = await signAuthMessage(privateKey, message);
74308
74493
  const apiUrl = getApiUrl();
74309
- let { signingKeyPublic, signingKeyPrivate } = cfg;
74310
- if (!signingKeyPublic || !signingKeyPrivate) {
74311
- const kp = await generateSigningKeyPair();
74312
- signingKeyPublic = kp.publicKey;
74313
- signingKeyPrivate = kp.privateKey;
74314
- writeJrConfig({ signingKeyPublic, signingKeyPrivate });
74494
+ let signingKeyPublic = cfg.signingKeyPublic;
74495
+ let signingKeyPrivateJwk = cfg.signingKeyPrivateJwk;
74496
+ if (!signingKeyPublic || !signingKeyPrivateJwk) {
74497
+ const kp = await generateSigningKeyPair(walletAddress);
74498
+ signingKeyPublic = kp.publicKeyBase64;
74499
+ signingKeyPrivateJwk = JSON.stringify(kp.privateJwk);
74500
+ writeJrConfig({ signingKeyPublic, signingKeyPrivateJwk });
74315
74501
  }
74316
74502
  const res = await apiFetch("/api/auth", {
74317
74503
  method: "POST",
@@ -75648,8 +75834,8 @@ function getErrorMap() {
75648
75834
 
75649
75835
  // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js
75650
75836
  var makeIssue = (params) => {
75651
- const { data, path: path5, errorMaps, issueData } = params;
75652
- const fullPath = [...path5, ...issueData.path || []];
75837
+ const { data, path: path6, errorMaps, issueData } = params;
75838
+ const fullPath = [...path6, ...issueData.path || []];
75653
75839
  const fullIssue = {
75654
75840
  ...issueData,
75655
75841
  path: fullPath
@@ -75765,11 +75951,11 @@ var errorUtil;
75765
75951
 
75766
75952
  // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js
75767
75953
  var ParseInputLazyPath = class {
75768
- constructor(parent, value, path5, key) {
75954
+ constructor(parent, value, path6, key) {
75769
75955
  this._cachedPath = [];
75770
75956
  this.parent = parent;
75771
75957
  this.data = value;
75772
- this._path = path5;
75958
+ this._path = path6;
75773
75959
  this._key = key;
75774
75960
  }
75775
75961
  get path() {
@@ -79628,8 +79814,8 @@ async function jrGenerateAction(prompt2, options) {
79628
79814
  const reason = `No response from ${apiUrl}/api/generate \u2014 ${err.message}`;
79629
79815
  process.stdout.write(`\x1B[33m${reason}\x1B[0m
79630
79816
  `);
79631
- const { default: readline4 } = await import("readline");
79632
- const rl = readline4.createInterface({ input: process.stdin, output: process.stdout });
79817
+ const { default: readline5 } = await import("readline");
79818
+ const rl = readline5.createInterface({ input: process.stdin, output: process.stdout });
79633
79819
  const newBase = await new Promise(
79634
79820
  (resolve) => rl.question("Base URL [https://jr-studio-web.fly.dev]: ", (a) => {
79635
79821
  rl.close();
@@ -79719,21 +79905,6 @@ async function promptPassword3() {
79719
79905
  }
79720
79906
 
79721
79907
  // src/commands/jr-tasks.ts
79722
- var crypto3 = __toESM(require("crypto"));
79723
- function buildRFC9421Headers(path5, token) {
79724
- const created = Math.floor(Date.now() / 1e3);
79725
- const apiUrl = getApiUrl();
79726
- const { host } = new URL(apiUrl);
79727
- const sigBase = `"@method": GET
79728
- "@path": ${path5}
79729
- "@authority": ${host}
79730
- "@signature-params": ("@method" "@path" "@authority");created=${created}`;
79731
- const sig = crypto3.createHmac("sha256", token).update(sigBase).digest("base64");
79732
- return {
79733
- "Signature-Input": `sig1=("@method" "@path" "@authority");created=${created}`,
79734
- Signature: `sig1=:${sig}:`
79735
- };
79736
- }
79737
79908
  function statusColor(status) {
79738
79909
  const codes = {
79739
79910
  pending: "\x1B[33m",
@@ -79755,13 +79926,11 @@ async function jrTasksAction(options) {
79755
79926
  sort: options.sort,
79756
79927
  ...options.status ? { status: options.status } : {}
79757
79928
  });
79758
- const path5 = `/api/tasks?${params.toString()}`;
79759
- const rfc9421 = buildRFC9421Headers(path5, token);
79760
- const res = await apiFetch(path5, {
79929
+ const path6 = `/api/tasks?${params.toString()}`;
79930
+ const res = await apiFetch(path6, {
79761
79931
  headers: {
79762
79932
  Authorization: `Bearer ${token}`,
79763
- Cookie: `jr-auth=${token}`,
79764
- ...rfc9421
79933
+ Cookie: `jr-auth=${token}`
79765
79934
  }
79766
79935
  });
79767
79936
  if (!res.ok) {
@@ -79794,6 +79963,100 @@ ${col("ID", 36)} ${col("PROMPT", 42)} ${col("MODEL", 12)} ${col("STATUS", 12)
79794
79963
  Page ${page} \xB7 ${rows.length} of ${total} total`);
79795
79964
  }
79796
79965
 
79966
+ // src/commands/track.ts
79967
+ var readline4 = __toESM(require("readline"));
79968
+ async function trackListAction(options) {
79969
+ await jrTasksAction({
79970
+ page: options.page ?? "1",
79971
+ limit: options.limit ?? "20",
79972
+ sort: options.sort ?? "created_at",
79973
+ status: options.status,
79974
+ json: options.json
79975
+ });
79976
+ }
79977
+ async function trackShowAction(generationId, options) {
79978
+ const token = requireToken();
79979
+ const res = await apiFetch(`/api/generations/${generationId}`, {
79980
+ method: "GET",
79981
+ headers: {
79982
+ Authorization: `Bearer ${token}`,
79983
+ Cookie: `jr-auth=${token}`
79984
+ }
79985
+ });
79986
+ if (!res.ok) {
79987
+ const text = await res.text();
79988
+ process.stderr.write(`Error (${res.status}): ${text}
79989
+ `);
79990
+ process.exit(1);
79991
+ }
79992
+ const g = await res.json();
79993
+ if (options.json) {
79994
+ process.stdout.write(JSON.stringify(g, null, 2) + "\n");
79995
+ return;
79996
+ }
79997
+ process.stdout.write(`ID ${g.id}
79998
+ `);
79999
+ process.stdout.write(`Status ${g.status}
80000
+ `);
80001
+ process.stdout.write(`Prompt ${g.prompt}
80002
+ `);
80003
+ process.stdout.write(`Model ${g.model}
80004
+ `);
80005
+ process.stdout.write(`Title ${g.title ?? g.prompt}
80006
+ `);
80007
+ process.stdout.write(`Created ${new Date(g.created_at).toLocaleString()}
80008
+ `);
80009
+ if (g.audio_url) {
80010
+ process.stdout.write(`Audio ${g.audio_url}
80011
+ `);
80012
+ }
80013
+ process.stdout.write(`Track ${g.track_url}
80014
+ `);
80015
+ }
80016
+ async function trackCreateAction(prompt2, options) {
80017
+ await jrGenerateAction(prompt2, {
80018
+ model: options.model ?? "suno-v4.5",
80019
+ instrumental: options.instrumental ?? false,
80020
+ customMode: options.customMode ?? false,
80021
+ title: options.title,
80022
+ style: options.style,
80023
+ negativeTags: options.negativeTags,
80024
+ wait: options.wait ?? false,
80025
+ pollInterval: options.pollInterval ?? "5"
80026
+ });
80027
+ }
80028
+ async function trackDeleteAction(generationId, options) {
80029
+ if (!options.force) {
80030
+ const rl = readline4.createInterface({ input: process.stdin, output: process.stdout });
80031
+ const answer = await new Promise((resolve) => {
80032
+ rl.question(`Delete track ${generationId}? [y/N] `, (a) => {
80033
+ rl.close();
80034
+ resolve(a.trim().toLowerCase());
80035
+ });
80036
+ });
80037
+ if (answer !== "y" && answer !== "yes") {
80038
+ process.stdout.write("Aborted.\n");
80039
+ return;
80040
+ }
80041
+ }
80042
+ const token = requireToken();
80043
+ const res = await apiFetch(`/api/generations/${generationId}`, {
80044
+ method: "DELETE",
80045
+ headers: {
80046
+ Authorization: `Bearer ${token}`,
80047
+ Cookie: `jr-auth=${token}`
80048
+ }
80049
+ });
80050
+ if (!res.ok) {
80051
+ const text = await res.text();
80052
+ process.stderr.write(`Error (${res.status}): ${text}
80053
+ `);
80054
+ process.exit(1);
80055
+ }
80056
+ process.stdout.write(`Deleted ${generationId}
80057
+ `);
80058
+ }
80059
+
79797
80060
  // src/commands/wallet.ts
79798
80061
  async function promptPassword4() {
79799
80062
  return new Promise((resolve) => {
@@ -86906,7 +87169,7 @@ async function networkSetAction(network) {
86906
87169
 
86907
87170
  // src/index.ts
86908
87171
  var program2 = new Command();
86909
- program2.name("jr-studio").description("AI music generation CLI powered by EvoLink (Suno models)").version("0.0.4").option("--url <url>", "JR Studio base URL \u2014 saved to ~/.jr-studio/config.json for future calls");
87172
+ program2.name("jr-studio").description("AI music generation CLI powered by EvoLink (Suno models)").version("0.0.5").option("--url <url>", "JR Studio base URL \u2014 saved to ~/.jr-studio/config.json for future calls");
86910
87173
  program2.hook("preAction", () => {
86911
87174
  const { url } = program2.opts();
86912
87175
  if (url) writeJrConfig({ api_url: url.replace(/\/$/, "") });
@@ -86917,6 +87180,9 @@ program2.command("status <task-id>").description("Check the status of a previous
86917
87180
  program2.command("download <generation-id>").description("Download audio for a completed generation (use the generation_id from `generate`)").option("-o, --output <dir>", "Download directory", "./").option("--format <format>", "Preferred format", "mp3").action(async (generationId, options) => {
86918
87181
  await downloadAction(generationId, options);
86919
87182
  });
87183
+ program2.command("export <generation-id>").description("Create a looped export of a track for a given duration (e.g. 1 hour)").option("-d, --duration <seconds>", "Duration in seconds (1\u201314400)").option("--hours <n>", "Duration in hours (e.g. 1 for 1 hour)").option("--track-index <n>", "Clip index for multi-clip generations", "0").option("-o, --output <path>", "Download the export to this file or directory").option("--json", "Raw JSON output").action(async (generationId, options) => {
87184
+ await exportAction(generationId, options);
87185
+ });
86920
87186
  program2.command("models").description("List available models with their capabilities").action(() => {
86921
87187
  modelsAction();
86922
87188
  });
@@ -86988,6 +87254,23 @@ networkCmd.argument("[network]", "base | base-sepolia (omit to show current)").a
86988
87254
  program2.command("tasks").description("List your JR Studio generation tasks").option("--page <n>", "Page number", "1").option("--limit <n>", "Results per page", "20").option("--sort <field>", "Sort field", "created_at").option("--status <status>", "Filter by status (pending, processing, completed, failed)").option("--json", "Raw JSON output").action(async (options) => {
86989
87255
  await jrTasksAction(options);
86990
87256
  });
87257
+ var trackCmd = program2.command("track").description("CRUD operations on tracks (generations)");
87258
+ trackCmd.command("list").description("List your tracks (same as tasks)").option("--page <n>", "Page number", "1").option("--limit <n>", "Results per page", "20").option("--sort <field>", "Sort field", "created_at").option("--status <status>", "Filter by status (pending, processing, completed, failed)").option("--json", "Raw JSON output").action(async (options) => {
87259
+ await trackListAction(options);
87260
+ });
87261
+ trackCmd.command("show <generation-id>").description("Show details for a track").option("--json", "Raw JSON output").action(async (generationId, options) => {
87262
+ await trackShowAction(generationId, options);
87263
+ });
87264
+ trackCmd.command("create <prompt>").description("Create a new track (same as generate)").option(
87265
+ "-m, --model <model>",
87266
+ "Model: suno-v4 | suno-v4.5 | suno-v4.5plus | suno-v4.5all | suno-v5",
87267
+ "suno-v4.5"
87268
+ ).option("-i, --instrumental", "Instrumental only", false).option("-c, --custom-mode", "Custom mode \u2014 prompt is lyrics", false).option("-t, --title <title>", "Track title (custom mode)").option("-s, --style <style>", "Genre/mood (required in custom mode)").option("-n, --negative-tags <tags>", "Styles to exclude").option("--wait", "Poll until complete", false).option("--poll-interval <seconds>", "Seconds between polls", "5").action(async (prompt2, options) => {
87269
+ await trackCreateAction(prompt2, options);
87270
+ });
87271
+ trackCmd.command("delete <generation-id>").description("Delete a track and its exports").option("-f, --force", "Skip confirmation").action(async (generationId, options) => {
87272
+ await trackDeleteAction(generationId, options);
87273
+ });
86991
87274
  program2.parse(process.argv);
86992
87275
  /*! Bundled license information:
86993
87276
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hathbanger/jr-studio",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "description": "AI music generation CLI powered by EvoLink (Suno models)",
5
5
  "license": "ISC",
6
6
  "type": "commonjs",
@@ -11,15 +11,24 @@
11
11
  "bin": {
12
12
  "jr-studio": "./dist/index.js"
13
13
  },
14
+ "scripts": {
15
+ "build": "esbuild src/index.ts --bundle --platform=node --target=node20 --outfile=dist/index.js --external:fsevents",
16
+ "dev": "tsx src/index.ts",
17
+ "lint": "eslint src/**/*.ts",
18
+ "start": "node dist/index.js",
19
+ "prepublishOnly": "node scripts/prepublish.js",
20
+ "postpublish": "PREPUBLISH_RESTORE=1 node scripts/prepublish.js"
21
+ },
14
22
  "dependencies": {
15
- "commander": "^12.1.0",
16
- "ora": "^5.4.1",
17
- "cli-progress": "^3.12.0",
23
+ "@hathbanger/tap-core": "^1.0.0",
18
24
  "@scure/bip32": "^2.0.1",
19
25
  "@scure/bip39": "^2.0.1",
20
26
  "@x402/core": "^2.0.0",
21
27
  "@x402/evm": "^2.0.0",
22
28
  "@x402/fetch": "^2.0.0",
29
+ "cli-progress": "^3.12.0",
30
+ "commander": "^12.1.0",
31
+ "ora": "^5.4.1",
23
32
  "viem": "^2.43.5"
24
33
  },
25
34
  "devDependencies": {
@@ -31,11 +40,5 @@
31
40
  "eslint": "^8.57.0",
32
41
  "tsx": "^4.19.2",
33
42
  "typescript": "^5.5.0"
34
- },
35
- "scripts": {
36
- "build": "esbuild src/index.ts --bundle --platform=node --target=node20 --outfile=dist/index.js --external:fsevents",
37
- "dev": "tsx src/index.ts",
38
- "lint": "eslint src/**/*.ts",
39
- "start": "node dist/index.js"
40
43
  }
41
- }
44
+ }