@learnrudi/cli 1.10.3 → 1.10.5

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.cjs CHANGED
@@ -662,7 +662,7 @@ async function downloadDirectoryFromGitHub(dirUrl, destDir, onProgress) {
662
662
  async function downloadRuntime(runtime, version, destPath, options = {}) {
663
663
  const { onProgress } = options;
664
664
  const platformArch = getPlatformArch2();
665
- const { execSync: execSync10 } = await import("child_process");
665
+ const { execSync: execSync11 } = await import("child_process");
666
666
  const runtimeManifest = await loadRuntimeManifest(runtime);
667
667
  const customDownload = runtimeManifest?.download?.[platformArch];
668
668
  const tempDir = import_path3.default.join(PATHS2.cache, "downloads");
@@ -688,7 +688,7 @@ async function downloadRuntime(runtime, version, destPath, options = {}) {
688
688
  const tempFile = import_path3.default.join(tempDir, `${runtime}-${version}-${platformArch}.download`);
689
689
  try {
690
690
  if (url.includes("github.com")) {
691
- execSync10(`curl -sL "${url}" -o "${tempFile}"`, { stdio: "pipe" });
691
+ execSync11(`curl -sL "${url}" -o "${tempFile}"`, { stdio: "pipe" });
692
692
  } else {
693
693
  const response = await fetch(url, {
694
694
  headers: {
@@ -709,13 +709,13 @@ async function downloadRuntime(runtime, version, destPath, options = {}) {
709
709
  import_fs2.default.renameSync(tempFile, binaryPath);
710
710
  import_fs2.default.chmodSync(binaryPath, 493);
711
711
  } else if (downloadType === "tar.gz" || downloadType === "tgz") {
712
- execSync10(`tar -xzf "${tempFile}" -C "${destPath}" --strip-components=1`, { stdio: "pipe" });
712
+ execSync11(`tar -xzf "${tempFile}" -C "${destPath}" --strip-components=1`, { stdio: "pipe" });
713
713
  import_fs2.default.unlinkSync(tempFile);
714
714
  } else if (downloadType === "tar.xz") {
715
- execSync10(`tar -xJf "${tempFile}" -C "${destPath}" --strip-components=1`, { stdio: "pipe" });
715
+ execSync11(`tar -xJf "${tempFile}" -C "${destPath}" --strip-components=1`, { stdio: "pipe" });
716
716
  import_fs2.default.unlinkSync(tempFile);
717
717
  } else if (downloadType === "zip") {
718
- execSync10(`unzip -o "${tempFile}" -d "${destPath}"`, { stdio: "pipe" });
718
+ execSync11(`unzip -o "${tempFile}" -d "${destPath}"`, { stdio: "pipe" });
719
719
  import_fs2.default.unlinkSync(tempFile);
720
720
  } else {
721
721
  throw new Error(`Unsupported download type: ${downloadType}`);
@@ -756,7 +756,7 @@ async function downloadTool(toolName, destPath, options = {}) {
756
756
  import_fs2.default.rmSync(destPath, { recursive: true });
757
757
  }
758
758
  import_fs2.default.mkdirSync(destPath, { recursive: true });
759
- const { execSync: execSync10 } = await import("child_process");
759
+ const { execSync: execSync11 } = await import("child_process");
760
760
  const downloads = toolManifest.downloads?.[platformArch];
761
761
  if (downloads && Array.isArray(downloads)) {
762
762
  const downloadedUrls = /* @__PURE__ */ new Set();
@@ -785,11 +785,11 @@ async function downloadTool(toolName, destPath, options = {}) {
785
785
  onProgress?.({ phase: "extracting", tool: toolName, binary: import_path3.default.basename(binary) });
786
786
  const archiveType = type || guessArchiveType(urlFilename);
787
787
  if (archiveType === "zip") {
788
- execSync10(`unzip -o "${tempFile}" -d "${destPath}"`, { stdio: "pipe" });
788
+ execSync11(`unzip -o "${tempFile}" -d "${destPath}"`, { stdio: "pipe" });
789
789
  } else if (archiveType === "tar.xz") {
790
- execSync10(`tar -xJf "${tempFile}" -C "${destPath}"`, { stdio: "pipe" });
790
+ execSync11(`tar -xJf "${tempFile}" -C "${destPath}"`, { stdio: "pipe" });
791
791
  } else if (archiveType === "tar.gz" || archiveType === "tgz") {
792
- execSync10(`tar -xzf "${tempFile}" -C "${destPath}"`, { stdio: "pipe" });
792
+ execSync11(`tar -xzf "${tempFile}" -C "${destPath}"`, { stdio: "pipe" });
793
793
  } else {
794
794
  throw new Error(`Unsupported archive type: ${archiveType}`);
795
795
  }
@@ -838,11 +838,11 @@ async function downloadTool(toolName, destPath, options = {}) {
838
838
  const stripComponents = extractConfig.strip || 0;
839
839
  const stripFlag = stripComponents > 0 ? ` --strip-components=${stripComponents}` : "";
840
840
  if (archiveType === "zip") {
841
- execSync10(`unzip -o "${tempFile}" -d "${destPath}"`, { stdio: "pipe" });
841
+ execSync11(`unzip -o "${tempFile}" -d "${destPath}"`, { stdio: "pipe" });
842
842
  } else if (archiveType === "tar.xz") {
843
- execSync10(`tar -xJf "${tempFile}" -C "${destPath}"${stripFlag}`, { stdio: "pipe" });
843
+ execSync11(`tar -xJf "${tempFile}" -C "${destPath}"${stripFlag}`, { stdio: "pipe" });
844
844
  } else if (archiveType === "tar.gz" || archiveType === "tgz") {
845
- execSync10(`tar -xzf "${tempFile}" -C "${destPath}"${stripFlag}`, { stdio: "pipe" });
845
+ execSync11(`tar -xzf "${tempFile}" -C "${destPath}"${stripFlag}`, { stdio: "pipe" });
846
846
  } else {
847
847
  throw new Error(`Unsupported archive type: ${archiveType}`);
848
848
  }
@@ -1296,17 +1296,17 @@ var require_visit = __commonJS({
1296
1296
  visit.BREAK = BREAK;
1297
1297
  visit.SKIP = SKIP;
1298
1298
  visit.REMOVE = REMOVE;
1299
- function visit_(key, node, visitor, path34) {
1300
- const ctrl = callVisitor(key, node, visitor, path34);
1299
+ function visit_(key, node, visitor, path35) {
1300
+ const ctrl = callVisitor(key, node, visitor, path35);
1301
1301
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
1302
- replaceNode(key, path34, ctrl);
1303
- return visit_(key, ctrl, visitor, path34);
1302
+ replaceNode(key, path35, ctrl);
1303
+ return visit_(key, ctrl, visitor, path35);
1304
1304
  }
1305
1305
  if (typeof ctrl !== "symbol") {
1306
1306
  if (identity.isCollection(node)) {
1307
- path34 = Object.freeze(path34.concat(node));
1307
+ path35 = Object.freeze(path35.concat(node));
1308
1308
  for (let i2 = 0; i2 < node.items.length; ++i2) {
1309
- const ci = visit_(i2, node.items[i2], visitor, path34);
1309
+ const ci = visit_(i2, node.items[i2], visitor, path35);
1310
1310
  if (typeof ci === "number")
1311
1311
  i2 = ci - 1;
1312
1312
  else if (ci === BREAK)
@@ -1317,13 +1317,13 @@ var require_visit = __commonJS({
1317
1317
  }
1318
1318
  }
1319
1319
  } else if (identity.isPair(node)) {
1320
- path34 = Object.freeze(path34.concat(node));
1321
- const ck = visit_("key", node.key, visitor, path34);
1320
+ path35 = Object.freeze(path35.concat(node));
1321
+ const ck = visit_("key", node.key, visitor, path35);
1322
1322
  if (ck === BREAK)
1323
1323
  return BREAK;
1324
1324
  else if (ck === REMOVE)
1325
1325
  node.key = null;
1326
- const cv = visit_("value", node.value, visitor, path34);
1326
+ const cv = visit_("value", node.value, visitor, path35);
1327
1327
  if (cv === BREAK)
1328
1328
  return BREAK;
1329
1329
  else if (cv === REMOVE)
@@ -1344,17 +1344,17 @@ var require_visit = __commonJS({
1344
1344
  visitAsync.BREAK = BREAK;
1345
1345
  visitAsync.SKIP = SKIP;
1346
1346
  visitAsync.REMOVE = REMOVE;
1347
- async function visitAsync_(key, node, visitor, path34) {
1348
- const ctrl = await callVisitor(key, node, visitor, path34);
1347
+ async function visitAsync_(key, node, visitor, path35) {
1348
+ const ctrl = await callVisitor(key, node, visitor, path35);
1349
1349
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
1350
- replaceNode(key, path34, ctrl);
1351
- return visitAsync_(key, ctrl, visitor, path34);
1350
+ replaceNode(key, path35, ctrl);
1351
+ return visitAsync_(key, ctrl, visitor, path35);
1352
1352
  }
1353
1353
  if (typeof ctrl !== "symbol") {
1354
1354
  if (identity.isCollection(node)) {
1355
- path34 = Object.freeze(path34.concat(node));
1355
+ path35 = Object.freeze(path35.concat(node));
1356
1356
  for (let i2 = 0; i2 < node.items.length; ++i2) {
1357
- const ci = await visitAsync_(i2, node.items[i2], visitor, path34);
1357
+ const ci = await visitAsync_(i2, node.items[i2], visitor, path35);
1358
1358
  if (typeof ci === "number")
1359
1359
  i2 = ci - 1;
1360
1360
  else if (ci === BREAK)
@@ -1365,13 +1365,13 @@ var require_visit = __commonJS({
1365
1365
  }
1366
1366
  }
1367
1367
  } else if (identity.isPair(node)) {
1368
- path34 = Object.freeze(path34.concat(node));
1369
- const ck = await visitAsync_("key", node.key, visitor, path34);
1368
+ path35 = Object.freeze(path35.concat(node));
1369
+ const ck = await visitAsync_("key", node.key, visitor, path35);
1370
1370
  if (ck === BREAK)
1371
1371
  return BREAK;
1372
1372
  else if (ck === REMOVE)
1373
1373
  node.key = null;
1374
- const cv = await visitAsync_("value", node.value, visitor, path34);
1374
+ const cv = await visitAsync_("value", node.value, visitor, path35);
1375
1375
  if (cv === BREAK)
1376
1376
  return BREAK;
1377
1377
  else if (cv === REMOVE)
@@ -1398,23 +1398,23 @@ var require_visit = __commonJS({
1398
1398
  }
1399
1399
  return visitor;
1400
1400
  }
1401
- function callVisitor(key, node, visitor, path34) {
1401
+ function callVisitor(key, node, visitor, path35) {
1402
1402
  if (typeof visitor === "function")
1403
- return visitor(key, node, path34);
1403
+ return visitor(key, node, path35);
1404
1404
  if (identity.isMap(node))
1405
- return visitor.Map?.(key, node, path34);
1405
+ return visitor.Map?.(key, node, path35);
1406
1406
  if (identity.isSeq(node))
1407
- return visitor.Seq?.(key, node, path34);
1407
+ return visitor.Seq?.(key, node, path35);
1408
1408
  if (identity.isPair(node))
1409
- return visitor.Pair?.(key, node, path34);
1409
+ return visitor.Pair?.(key, node, path35);
1410
1410
  if (identity.isScalar(node))
1411
- return visitor.Scalar?.(key, node, path34);
1411
+ return visitor.Scalar?.(key, node, path35);
1412
1412
  if (identity.isAlias(node))
1413
- return visitor.Alias?.(key, node, path34);
1413
+ return visitor.Alias?.(key, node, path35);
1414
1414
  return void 0;
1415
1415
  }
1416
- function replaceNode(key, path34, node) {
1417
- const parent = path34[path34.length - 1];
1416
+ function replaceNode(key, path35, node) {
1417
+ const parent = path35[path35.length - 1];
1418
1418
  if (identity.isCollection(parent)) {
1419
1419
  parent.items[key] = node;
1420
1420
  } else if (identity.isPair(parent)) {
@@ -2022,10 +2022,10 @@ var require_Collection = __commonJS({
2022
2022
  var createNode = require_createNode();
2023
2023
  var identity = require_identity();
2024
2024
  var Node = require_Node();
2025
- function collectionFromPath(schema, path34, value) {
2025
+ function collectionFromPath(schema, path35, value) {
2026
2026
  let v2 = value;
2027
- for (let i2 = path34.length - 1; i2 >= 0; --i2) {
2028
- const k2 = path34[i2];
2027
+ for (let i2 = path35.length - 1; i2 >= 0; --i2) {
2028
+ const k2 = path35[i2];
2029
2029
  if (typeof k2 === "number" && Number.isInteger(k2) && k2 >= 0) {
2030
2030
  const a2 = [];
2031
2031
  a2[k2] = v2;
@@ -2044,7 +2044,7 @@ var require_Collection = __commonJS({
2044
2044
  sourceObjects: /* @__PURE__ */ new Map()
2045
2045
  });
2046
2046
  }
2047
- var isEmptyPath = (path34) => path34 == null || typeof path34 === "object" && !!path34[Symbol.iterator]().next().done;
2047
+ var isEmptyPath = (path35) => path35 == null || typeof path35 === "object" && !!path35[Symbol.iterator]().next().done;
2048
2048
  var Collection = class extends Node.NodeBase {
2049
2049
  constructor(type, schema) {
2050
2050
  super(type);
@@ -2074,11 +2074,11 @@ var require_Collection = __commonJS({
2074
2074
  * be a Pair instance or a `{ key, value }` object, which may not have a key
2075
2075
  * that already exists in the map.
2076
2076
  */
2077
- addIn(path34, value) {
2078
- if (isEmptyPath(path34))
2077
+ addIn(path35, value) {
2078
+ if (isEmptyPath(path35))
2079
2079
  this.add(value);
2080
2080
  else {
2081
- const [key, ...rest] = path34;
2081
+ const [key, ...rest] = path35;
2082
2082
  const node = this.get(key, true);
2083
2083
  if (identity.isCollection(node))
2084
2084
  node.addIn(rest, value);
@@ -2092,8 +2092,8 @@ var require_Collection = __commonJS({
2092
2092
  * Removes a value from the collection.
2093
2093
  * @returns `true` if the item was found and removed.
2094
2094
  */
2095
- deleteIn(path34) {
2096
- const [key, ...rest] = path34;
2095
+ deleteIn(path35) {
2096
+ const [key, ...rest] = path35;
2097
2097
  if (rest.length === 0)
2098
2098
  return this.delete(key);
2099
2099
  const node = this.get(key, true);
@@ -2107,8 +2107,8 @@ var require_Collection = __commonJS({
2107
2107
  * scalar values from their surrounding node; to disable set `keepScalar` to
2108
2108
  * `true` (collections are always returned intact).
2109
2109
  */
2110
- getIn(path34, keepScalar) {
2111
- const [key, ...rest] = path34;
2110
+ getIn(path35, keepScalar) {
2111
+ const [key, ...rest] = path35;
2112
2112
  const node = this.get(key, true);
2113
2113
  if (rest.length === 0)
2114
2114
  return !keepScalar && identity.isScalar(node) ? node.value : node;
@@ -2126,8 +2126,8 @@ var require_Collection = __commonJS({
2126
2126
  /**
2127
2127
  * Checks if the collection includes a value with the key `key`.
2128
2128
  */
2129
- hasIn(path34) {
2130
- const [key, ...rest] = path34;
2129
+ hasIn(path35) {
2130
+ const [key, ...rest] = path35;
2131
2131
  if (rest.length === 0)
2132
2132
  return this.has(key);
2133
2133
  const node = this.get(key, true);
@@ -2137,8 +2137,8 @@ var require_Collection = __commonJS({
2137
2137
  * Sets a value in this collection. For `!!set`, `value` needs to be a
2138
2138
  * boolean to add/remove the item from the set.
2139
2139
  */
2140
- setIn(path34, value) {
2141
- const [key, ...rest] = path34;
2140
+ setIn(path35, value) {
2141
+ const [key, ...rest] = path35;
2142
2142
  if (rest.length === 0) {
2143
2143
  this.set(key, value);
2144
2144
  } else {
@@ -4642,9 +4642,9 @@ var require_Document = __commonJS({
4642
4642
  this.contents.add(value);
4643
4643
  }
4644
4644
  /** Adds a value to the document. */
4645
- addIn(path34, value) {
4645
+ addIn(path35, value) {
4646
4646
  if (assertCollection(this.contents))
4647
- this.contents.addIn(path34, value);
4647
+ this.contents.addIn(path35, value);
4648
4648
  }
4649
4649
  /**
4650
4650
  * Create a new `Alias` node, ensuring that the target `node` has the required anchor.
@@ -4719,14 +4719,14 @@ var require_Document = __commonJS({
4719
4719
  * Removes a value from the document.
4720
4720
  * @returns `true` if the item was found and removed.
4721
4721
  */
4722
- deleteIn(path34) {
4723
- if (Collection.isEmptyPath(path34)) {
4722
+ deleteIn(path35) {
4723
+ if (Collection.isEmptyPath(path35)) {
4724
4724
  if (this.contents == null)
4725
4725
  return false;
4726
4726
  this.contents = null;
4727
4727
  return true;
4728
4728
  }
4729
- return assertCollection(this.contents) ? this.contents.deleteIn(path34) : false;
4729
+ return assertCollection(this.contents) ? this.contents.deleteIn(path35) : false;
4730
4730
  }
4731
4731
  /**
4732
4732
  * Returns item at `key`, or `undefined` if not found. By default unwraps
@@ -4741,10 +4741,10 @@ var require_Document = __commonJS({
4741
4741
  * scalar values from their surrounding node; to disable set `keepScalar` to
4742
4742
  * `true` (collections are always returned intact).
4743
4743
  */
4744
- getIn(path34, keepScalar) {
4745
- if (Collection.isEmptyPath(path34))
4744
+ getIn(path35, keepScalar) {
4745
+ if (Collection.isEmptyPath(path35))
4746
4746
  return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
4747
- return identity.isCollection(this.contents) ? this.contents.getIn(path34, keepScalar) : void 0;
4747
+ return identity.isCollection(this.contents) ? this.contents.getIn(path35, keepScalar) : void 0;
4748
4748
  }
4749
4749
  /**
4750
4750
  * Checks if the document includes a value with the key `key`.
@@ -4755,10 +4755,10 @@ var require_Document = __commonJS({
4755
4755
  /**
4756
4756
  * Checks if the document includes a value at `path`.
4757
4757
  */
4758
- hasIn(path34) {
4759
- if (Collection.isEmptyPath(path34))
4758
+ hasIn(path35) {
4759
+ if (Collection.isEmptyPath(path35))
4760
4760
  return this.contents !== void 0;
4761
- return identity.isCollection(this.contents) ? this.contents.hasIn(path34) : false;
4761
+ return identity.isCollection(this.contents) ? this.contents.hasIn(path35) : false;
4762
4762
  }
4763
4763
  /**
4764
4764
  * Sets a value in this document. For `!!set`, `value` needs to be a
@@ -4775,13 +4775,13 @@ var require_Document = __commonJS({
4775
4775
  * Sets a value in this document. For `!!set`, `value` needs to be a
4776
4776
  * boolean to add/remove the item from the set.
4777
4777
  */
4778
- setIn(path34, value) {
4779
- if (Collection.isEmptyPath(path34)) {
4778
+ setIn(path35, value) {
4779
+ if (Collection.isEmptyPath(path35)) {
4780
4780
  this.contents = value;
4781
4781
  } else if (this.contents == null) {
4782
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path34), value);
4782
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path35), value);
4783
4783
  } else if (assertCollection(this.contents)) {
4784
- this.contents.setIn(path34, value);
4784
+ this.contents.setIn(path35, value);
4785
4785
  }
4786
4786
  }
4787
4787
  /**
@@ -6733,9 +6733,9 @@ var require_cst_visit = __commonJS({
6733
6733
  visit.BREAK = BREAK;
6734
6734
  visit.SKIP = SKIP;
6735
6735
  visit.REMOVE = REMOVE;
6736
- visit.itemAtPath = (cst, path34) => {
6736
+ visit.itemAtPath = (cst, path35) => {
6737
6737
  let item = cst;
6738
- for (const [field, index] of path34) {
6738
+ for (const [field, index] of path35) {
6739
6739
  const tok = item?.[field];
6740
6740
  if (tok && "items" in tok) {
6741
6741
  item = tok.items[index];
@@ -6744,23 +6744,23 @@ var require_cst_visit = __commonJS({
6744
6744
  }
6745
6745
  return item;
6746
6746
  };
6747
- visit.parentCollection = (cst, path34) => {
6748
- const parent = visit.itemAtPath(cst, path34.slice(0, -1));
6749
- const field = path34[path34.length - 1][0];
6747
+ visit.parentCollection = (cst, path35) => {
6748
+ const parent = visit.itemAtPath(cst, path35.slice(0, -1));
6749
+ const field = path35[path35.length - 1][0];
6750
6750
  const coll = parent?.[field];
6751
6751
  if (coll && "items" in coll)
6752
6752
  return coll;
6753
6753
  throw new Error("Parent collection not found");
6754
6754
  };
6755
- function _visit(path34, item, visitor) {
6756
- let ctrl = visitor(item, path34);
6755
+ function _visit(path35, item, visitor) {
6756
+ let ctrl = visitor(item, path35);
6757
6757
  if (typeof ctrl === "symbol")
6758
6758
  return ctrl;
6759
6759
  for (const field of ["key", "value"]) {
6760
6760
  const token = item[field];
6761
6761
  if (token && "items" in token) {
6762
6762
  for (let i2 = 0; i2 < token.items.length; ++i2) {
6763
- const ci = _visit(Object.freeze(path34.concat([[field, i2]])), token.items[i2], visitor);
6763
+ const ci = _visit(Object.freeze(path35.concat([[field, i2]])), token.items[i2], visitor);
6764
6764
  if (typeof ci === "number")
6765
6765
  i2 = ci - 1;
6766
6766
  else if (ci === BREAK)
@@ -6771,10 +6771,10 @@ var require_cst_visit = __commonJS({
6771
6771
  }
6772
6772
  }
6773
6773
  if (typeof ctrl === "function" && field === "key")
6774
- ctrl = ctrl(item, path34);
6774
+ ctrl = ctrl(item, path35);
6775
6775
  }
6776
6776
  }
6777
- return typeof ctrl === "function" ? ctrl(item, path34) : ctrl;
6777
+ return typeof ctrl === "function" ? ctrl(item, path35) : ctrl;
6778
6778
  }
6779
6779
  exports2.visit = visit;
6780
6780
  }
@@ -8059,14 +8059,14 @@ var require_parser = __commonJS({
8059
8059
  case "scalar":
8060
8060
  case "single-quoted-scalar":
8061
8061
  case "double-quoted-scalar": {
8062
- const fs34 = this.flowScalar(this.type);
8062
+ const fs35 = this.flowScalar(this.type);
8063
8063
  if (atNextItem || it2.value) {
8064
- map.items.push({ start, key: fs34, sep: [] });
8064
+ map.items.push({ start, key: fs35, sep: [] });
8065
8065
  this.onKeyLine = true;
8066
8066
  } else if (it2.sep) {
8067
- this.stack.push(fs34);
8067
+ this.stack.push(fs35);
8068
8068
  } else {
8069
- Object.assign(it2, { key: fs34, sep: [] });
8069
+ Object.assign(it2, { key: fs35, sep: [] });
8070
8070
  this.onKeyLine = true;
8071
8071
  }
8072
8072
  return;
@@ -8194,13 +8194,13 @@ var require_parser = __commonJS({
8194
8194
  case "scalar":
8195
8195
  case "single-quoted-scalar":
8196
8196
  case "double-quoted-scalar": {
8197
- const fs34 = this.flowScalar(this.type);
8197
+ const fs35 = this.flowScalar(this.type);
8198
8198
  if (!it2 || it2.value)
8199
- fc.items.push({ start: [], key: fs34, sep: [] });
8199
+ fc.items.push({ start: [], key: fs35, sep: [] });
8200
8200
  else if (it2.sep)
8201
- this.stack.push(fs34);
8201
+ this.stack.push(fs35);
8202
8202
  else
8203
- Object.assign(it2, { key: fs34, sep: [] });
8203
+ Object.assign(it2, { key: fs35, sep: [] });
8204
8204
  return;
8205
8205
  }
8206
8206
  case "flow-map-end":
@@ -8918,7 +8918,7 @@ async function installSinglePackage(pkg, options = {}) {
8918
8918
  onProgress?.({ phase: "downloading", package: pkg.id });
8919
8919
  if (pkg.npmPackage) {
8920
8920
  try {
8921
- const { execSync: execSync10 } = await import("child_process");
8921
+ const { execSync: execSync11 } = await import("child_process");
8922
8922
  if (!import_fs5.default.existsSync(installPath)) {
8923
8923
  import_fs5.default.mkdirSync(installPath, { recursive: true });
8924
8924
  }
@@ -8926,11 +8926,11 @@ async function installSinglePackage(pkg, options = {}) {
8926
8926
  const resourcesPath = process.env.RESOURCES_PATH;
8927
8927
  const npmCmd = resourcesPath ? import_path6.default.join(resourcesPath, "bundled-runtimes", "node", "bin", "npm") : "npm";
8928
8928
  if (!import_fs5.default.existsSync(import_path6.default.join(installPath, "package.json"))) {
8929
- execSync10(`"${npmCmd}" init -y`, { cwd: installPath, stdio: "pipe" });
8929
+ execSync11(`"${npmCmd}" init -y`, { cwd: installPath, stdio: "pipe" });
8930
8930
  }
8931
8931
  const shouldIgnoreScripts = pkg.source?.type === "npm" && !allowScripts;
8932
8932
  const installFlags = shouldIgnoreScripts ? "--ignore-scripts --no-audit --no-fund" : "--no-audit --no-fund";
8933
- execSync10(`"${npmCmd}" install ${pkg.npmPackage} ${installFlags}`, { cwd: installPath, stdio: "pipe" });
8933
+ execSync11(`"${npmCmd}" install ${pkg.npmPackage} ${installFlags}`, { cwd: installPath, stdio: "pipe" });
8934
8934
  let bins = pkg.bins;
8935
8935
  if (!bins || bins.length === 0) {
8936
8936
  bins = discoverNpmBins(installPath, pkg.npmPackage);
@@ -8951,7 +8951,7 @@ async function installSinglePackage(pkg, options = {}) {
8951
8951
  /^npx\s+(\S+)/,
8952
8952
  `"${import_path6.default.join(installPath, "node_modules", ".bin", "$1")}"`
8953
8953
  );
8954
- execSync10(postInstallCmd, { cwd: installPath, stdio: "pipe" });
8954
+ execSync11(postInstallCmd, { cwd: installPath, stdio: "pipe" });
8955
8955
  }
8956
8956
  const scriptsDetected = hasInstallScripts(installPath, pkg.npmPackage);
8957
8957
  const scriptsPolicy = installFlags.includes("--ignore-scripts") ? "ignore" : "allow";
@@ -9320,7 +9320,7 @@ async function updateAll(options = {}) {
9320
9320
  return results;
9321
9321
  }
9322
9322
  async function installStackDependencies(stackPath, onProgress) {
9323
- const { execSync: execSync10 } = await import("child_process");
9323
+ const { execSync: execSync11 } = await import("child_process");
9324
9324
  const nodePath = import_path6.default.join(stackPath, "node");
9325
9325
  if (import_fs5.default.existsSync(nodePath)) {
9326
9326
  const packageJsonPath = import_path6.default.join(nodePath, "package.json");
@@ -9328,7 +9328,7 @@ async function installStackDependencies(stackPath, onProgress) {
9328
9328
  onProgress?.({ phase: "installing-deps", message: "Installing Node.js dependencies..." });
9329
9329
  try {
9330
9330
  const npmCmd = await findNpmExecutable();
9331
- execSync10(`"${npmCmd}" install`, { cwd: nodePath, stdio: "pipe" });
9331
+ execSync11(`"${npmCmd}" install`, { cwd: nodePath, stdio: "pipe" });
9332
9332
  } catch (error) {
9333
9333
  console.warn(`Warning: Failed to install Node.js dependencies: ${error.message}`);
9334
9334
  }
@@ -9386,8 +9386,8 @@ function findUvExecutable() {
9386
9386
  return uvPath;
9387
9387
  }
9388
9388
  try {
9389
- const { execSync: execSync10 } = require("child_process");
9390
- execSync10("uv --version", { stdio: "pipe" });
9389
+ const { execSync: execSync11 } = require("child_process");
9390
+ execSync11("uv --version", { stdio: "pipe" });
9391
9391
  return "uv";
9392
9392
  } catch {
9393
9393
  return null;
@@ -9411,37 +9411,37 @@ async function ensureUv(onProgress) {
9411
9411
  return null;
9412
9412
  }
9413
9413
  async function installPythonPackage(installPath, pipPackage, onProgress) {
9414
- const { execSync: execSync10 } = await import("child_process");
9414
+ const { execSync: execSync11 } = await import("child_process");
9415
9415
  const uvCmd = findUvExecutable();
9416
9416
  if (uvCmd) {
9417
9417
  onProgress?.({ phase: "installing", message: `uv pip install ${pipPackage}` });
9418
- execSync10(`"${uvCmd}" venv "${installPath}/venv"`, { stdio: "pipe" });
9419
- execSync10(`"${uvCmd}" pip install --python "${installPath}/venv/bin/python" ${pipPackage}`, { stdio: "pipe" });
9418
+ execSync11(`"${uvCmd}" venv "${installPath}/venv"`, { stdio: "pipe" });
9419
+ execSync11(`"${uvCmd}" pip install --python "${installPath}/venv/bin/python" ${pipPackage}`, { stdio: "pipe" });
9420
9420
  return { usedUv: true };
9421
9421
  } else {
9422
9422
  onProgress?.({ phase: "installing", message: `pip install ${pipPackage}` });
9423
9423
  const pythonCmd = await findPythonExecutable();
9424
- execSync10(`"${pythonCmd}" -m venv "${installPath}/venv"`, { stdio: "pipe" });
9425
- execSync10(`"${installPath}/venv/bin/pip" install ${pipPackage}`, { stdio: "pipe" });
9424
+ execSync11(`"${pythonCmd}" -m venv "${installPath}/venv"`, { stdio: "pipe" });
9425
+ execSync11(`"${installPath}/venv/bin/pip" install ${pipPackage}`, { stdio: "pipe" });
9426
9426
  return { usedUv: false };
9427
9427
  }
9428
9428
  }
9429
9429
  async function installPythonRequirements(pythonPath, onProgress) {
9430
- const { execSync: execSync10 } = await import("child_process");
9430
+ const { execSync: execSync11 } = await import("child_process");
9431
9431
  const uvCmd = findUvExecutable();
9432
9432
  const isWindows = process.platform === "win32";
9433
9433
  const venvPython = isWindows ? import_path6.default.join(pythonPath, "venv", "Scripts", "python.exe") : import_path6.default.join(pythonPath, "venv", "bin", "python");
9434
9434
  if (uvCmd) {
9435
9435
  onProgress?.({ phase: "installing-deps", message: "Installing Python dependencies with uv..." });
9436
- execSync10(`"${uvCmd}" venv "${pythonPath}/venv"`, { cwd: pythonPath, stdio: "pipe" });
9437
- execSync10(`"${uvCmd}" pip install --python "${venvPython}" -r requirements.txt`, { cwd: pythonPath, stdio: "pipe" });
9436
+ execSync11(`"${uvCmd}" venv "${pythonPath}/venv"`, { cwd: pythonPath, stdio: "pipe" });
9437
+ execSync11(`"${uvCmd}" pip install --python "${venvPython}" -r requirements.txt`, { cwd: pythonPath, stdio: "pipe" });
9438
9438
  return { usedUv: true };
9439
9439
  } else {
9440
9440
  onProgress?.({ phase: "installing-deps", message: "Installing Python dependencies..." });
9441
9441
  const pythonCmd = await findPythonExecutable();
9442
- execSync10(`"${pythonCmd}" -m venv venv`, { cwd: pythonPath, stdio: "pipe" });
9442
+ execSync11(`"${pythonCmd}" -m venv venv`, { cwd: pythonPath, stdio: "pipe" });
9443
9443
  const pipCmd = isWindows ? ".\\venv\\Scripts\\pip" : "./venv/bin/pip";
9444
- execSync10(`${pipCmd} install -r requirements.txt`, { cwd: pythonPath, stdio: "pipe" });
9444
+ execSync11(`${pipCmd} install -r requirements.txt`, { cwd: pythonPath, stdio: "pipe" });
9445
9445
  return { usedUv: false };
9446
9446
  }
9447
9447
  }
@@ -13605,8 +13605,8 @@ var require_utils = __commonJS({
13605
13605
  }
13606
13606
  return ind;
13607
13607
  }
13608
- function removeDotSegments(path34) {
13609
- let input = path34;
13608
+ function removeDotSegments(path35) {
13609
+ let input = path35;
13610
13610
  const output = [];
13611
13611
  let nextSlash = -1;
13612
13612
  let len = 0;
@@ -13805,8 +13805,8 @@ var require_schemes = __commonJS({
13805
13805
  wsComponent.secure = void 0;
13806
13806
  }
13807
13807
  if (wsComponent.resourceName) {
13808
- const [path34, query] = wsComponent.resourceName.split("?");
13809
- wsComponent.path = path34 && path34 !== "/" ? path34 : void 0;
13808
+ const [path35, query] = wsComponent.resourceName.split("?");
13809
+ wsComponent.path = path35 && path35 !== "/" ? path35 : void 0;
13810
13810
  wsComponent.query = query;
13811
13811
  wsComponent.resourceName = void 0;
13812
13812
  }
@@ -17159,12 +17159,12 @@ var require_dist2 = __commonJS({
17159
17159
  throw new Error(`Unknown format "${name}"`);
17160
17160
  return f2;
17161
17161
  };
17162
- function addFormats2(ajv2, list, fs34, exportName) {
17162
+ function addFormats2(ajv2, list, fs35, exportName) {
17163
17163
  var _a2;
17164
17164
  var _b;
17165
17165
  (_a2 = (_b = ajv2.opts.code).formats) !== null && _a2 !== void 0 ? _a2 : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
17166
17166
  for (const f2 of list)
17167
- ajv2.addFormat(f2, fs34[f2]);
17167
+ ajv2.addFormat(f2, fs35[f2]);
17168
17168
  }
17169
17169
  module2.exports = exports2 = formatsPlugin;
17170
17170
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -18864,14 +18864,14 @@ var require_url_state_machine = __commonJS({
18864
18864
  return url.replace(/\u0009|\u000A|\u000D/g, "");
18865
18865
  }
18866
18866
  function shortenPath(url) {
18867
- const path34 = url.path;
18868
- if (path34.length === 0) {
18867
+ const path35 = url.path;
18868
+ if (path35.length === 0) {
18869
18869
  return;
18870
18870
  }
18871
- if (url.scheme === "file" && path34.length === 1 && isNormalizedWindowsDriveLetter(path34[0])) {
18871
+ if (url.scheme === "file" && path35.length === 1 && isNormalizedWindowsDriveLetter(path35[0])) {
18872
18872
  return;
18873
18873
  }
18874
- path34.pop();
18874
+ path35.pop();
18875
18875
  }
18876
18876
  function includesCredentials(url) {
18877
18877
  return url.username !== "" || url.password !== "";
@@ -24855,14 +24855,14 @@ __export(fileFromPath_exports, {
24855
24855
  fileFromPathSync: () => fileFromPathSync,
24856
24856
  isFile: () => isFile
24857
24857
  });
24858
- function createFileFromPath(path34, { mtimeMs, size }, filenameOrOptions, options = {}) {
24858
+ function createFileFromPath(path35, { mtimeMs, size }, filenameOrOptions, options = {}) {
24859
24859
  let filename;
24860
24860
  if (isPlainObject_default2(filenameOrOptions)) {
24861
24861
  [options, filename] = [filenameOrOptions, void 0];
24862
24862
  } else {
24863
24863
  filename = filenameOrOptions;
24864
24864
  }
24865
- const file = new FileFromPath({ path: path34, size, lastModified: mtimeMs });
24865
+ const file = new FileFromPath({ path: path35, size, lastModified: mtimeMs });
24866
24866
  if (!filename) {
24867
24867
  filename = file.name;
24868
24868
  }
@@ -24871,13 +24871,13 @@ function createFileFromPath(path34, { mtimeMs, size }, filenameOrOptions, option
24871
24871
  lastModified: file.lastModified
24872
24872
  });
24873
24873
  }
24874
- function fileFromPathSync(path34, filenameOrOptions, options = {}) {
24875
- const stats = (0, import_fs16.statSync)(path34);
24876
- return createFileFromPath(path34, stats, filenameOrOptions, options);
24874
+ function fileFromPathSync(path35, filenameOrOptions, options = {}) {
24875
+ const stats = (0, import_fs16.statSync)(path35);
24876
+ return createFileFromPath(path35, stats, filenameOrOptions, options);
24877
24877
  }
24878
- async function fileFromPath2(path34, filenameOrOptions, options) {
24879
- const stats = await import_fs16.promises.stat(path34);
24880
- return createFileFromPath(path34, stats, filenameOrOptions, options);
24878
+ async function fileFromPath2(path35, filenameOrOptions, options) {
24879
+ const stats = await import_fs16.promises.stat(path35);
24880
+ return createFileFromPath(path35, stats, filenameOrOptions, options);
24881
24881
  }
24882
24882
  var import_fs16, import_path17, import_node_domexception, __classPrivateFieldSet4, __classPrivateFieldGet5, _FileFromPath_path, _FileFromPath_start, MESSAGE, FileFromPath;
24883
24883
  var init_fileFromPath = __esm({
@@ -24938,13 +24938,13 @@ var init_fileFromPath = __esm({
24938
24938
  });
24939
24939
 
24940
24940
  // node_modules/.pnpm/openai@4.104.0/node_modules/openai/_shims/node-runtime.mjs
24941
- async function fileFromPath3(path34, ...args) {
24941
+ async function fileFromPath3(path35, ...args) {
24942
24942
  const { fileFromPath: _fileFromPath } = await Promise.resolve().then(() => (init_fileFromPath(), fileFromPath_exports));
24943
24943
  if (!fileFromPathWarned) {
24944
- console.warn(`fileFromPath is deprecated; use fs.createReadStream(${JSON.stringify(path34)}) instead`);
24944
+ console.warn(`fileFromPath is deprecated; use fs.createReadStream(${JSON.stringify(path35)}) instead`);
24945
24945
  fileFromPathWarned = true;
24946
24946
  }
24947
- return await _fileFromPath(path34, ...args);
24947
+ return await _fileFromPath(path35, ...args);
24948
24948
  }
24949
24949
  async function getMultipartRequestOptions2(form, opts) {
24950
24950
  const encoder = new FormDataEncoder(form);
@@ -25877,29 +25877,29 @@ var init_core = __esm({
25877
25877
  defaultIdempotencyKey() {
25878
25878
  return `stainless-node-retry-${uuid4()}`;
25879
25879
  }
25880
- get(path34, opts) {
25881
- return this.methodRequest("get", path34, opts);
25880
+ get(path35, opts) {
25881
+ return this.methodRequest("get", path35, opts);
25882
25882
  }
25883
- post(path34, opts) {
25884
- return this.methodRequest("post", path34, opts);
25883
+ post(path35, opts) {
25884
+ return this.methodRequest("post", path35, opts);
25885
25885
  }
25886
- patch(path34, opts) {
25887
- return this.methodRequest("patch", path34, opts);
25886
+ patch(path35, opts) {
25887
+ return this.methodRequest("patch", path35, opts);
25888
25888
  }
25889
- put(path34, opts) {
25890
- return this.methodRequest("put", path34, opts);
25889
+ put(path35, opts) {
25890
+ return this.methodRequest("put", path35, opts);
25891
25891
  }
25892
- delete(path34, opts) {
25893
- return this.methodRequest("delete", path34, opts);
25892
+ delete(path35, opts) {
25893
+ return this.methodRequest("delete", path35, opts);
25894
25894
  }
25895
- methodRequest(method, path34, opts) {
25895
+ methodRequest(method, path35, opts) {
25896
25896
  return this.request(Promise.resolve(opts).then(async (opts2) => {
25897
25897
  const body = opts2 && isBlobLike(opts2?.body) ? new DataView(await opts2.body.arrayBuffer()) : opts2?.body instanceof DataView ? opts2.body : opts2?.body instanceof ArrayBuffer ? new DataView(opts2.body) : opts2 && ArrayBuffer.isView(opts2?.body) ? new DataView(opts2.body.buffer) : opts2?.body;
25898
- return { method, path: path34, ...opts2, body };
25898
+ return { method, path: path35, ...opts2, body };
25899
25899
  }));
25900
25900
  }
25901
- getAPIList(path34, Page2, opts) {
25902
- return this.requestAPIList(Page2, { method: "get", path: path34, ...opts });
25901
+ getAPIList(path35, Page2, opts) {
25902
+ return this.requestAPIList(Page2, { method: "get", path: path35, ...opts });
25903
25903
  }
25904
25904
  calculateContentLength(body) {
25905
25905
  if (typeof body === "string") {
@@ -25918,10 +25918,10 @@ var init_core = __esm({
25918
25918
  }
25919
25919
  buildRequest(inputOptions, { retryCount = 0 } = {}) {
25920
25920
  const options = { ...inputOptions };
25921
- const { method, path: path34, query, headers = {} } = options;
25921
+ const { method, path: path35, query, headers = {} } = options;
25922
25922
  const body = ArrayBuffer.isView(options.body) || options.__binaryRequest && typeof options.body === "string" ? options.body : isMultipartBody(options.body) ? options.body.body : options.body ? JSON.stringify(options.body, null, 2) : null;
25923
25923
  const contentLength = this.calculateContentLength(body);
25924
- const url = this.buildURL(path34, query);
25924
+ const url = this.buildURL(path35, query);
25925
25925
  if ("timeout" in options)
25926
25926
  validatePositiveInteger("timeout", options.timeout);
25927
25927
  options.timeout = options.timeout ?? this.timeout;
@@ -26037,8 +26037,8 @@ var init_core = __esm({
26037
26037
  const request = this.makeRequest(options, null);
26038
26038
  return new PagePromise(this, request, Page2);
26039
26039
  }
26040
- buildURL(path34, query) {
26041
- const url = isAbsoluteURL(path34) ? new URL(path34) : new URL(this.baseURL + (this.baseURL.endsWith("/") && path34.startsWith("/") ? path34.slice(1) : path34));
26040
+ buildURL(path35, query) {
26041
+ const url = isAbsoluteURL(path35) ? new URL(path35) : new URL(this.baseURL + (this.baseURL.endsWith("/") && path35.startsWith("/") ? path35.slice(1) : path35));
26042
26042
  const defaultQuery = this.defaultQuery();
26043
26043
  if (!isEmptyObj(defaultQuery)) {
26044
26044
  query = { ...defaultQuery, ...query };
@@ -31643,9 +31643,9 @@ async function checkProviderStatus() {
31643
31643
  }
31644
31644
  };
31645
31645
  try {
31646
- const { execSync: execSync10 } = await import("child_process");
31646
+ const { execSync: execSync11 } = await import("child_process");
31647
31647
  try {
31648
- execSync10("which ollama", { stdio: "pipe" });
31648
+ execSync11("which ollama", { stdio: "pipe" });
31649
31649
  status.ollama.installed = true;
31650
31650
  } catch {
31651
31651
  }
@@ -31721,9 +31721,9 @@ async function autoSetupOllama() {
31721
31721
  };
31722
31722
  }
31723
31723
  try {
31724
- const { execSync: execSync10 } = await import("child_process");
31724
+ const { execSync: execSync11 } = await import("child_process");
31725
31725
  console.log("Pulling nomic-embed-text model...");
31726
- execSync10("ollama pull nomic-embed-text", { stdio: "inherit" });
31726
+ execSync11("ollama pull nomic-embed-text", { stdio: "inherit" });
31727
31727
  return { success: true, message: "Ollama configured with nomic-embed-text" };
31728
31728
  } catch (err) {
31729
31729
  return { success: false, message: `Failed to pull model: ${err.message}` };
@@ -33271,11 +33271,11 @@ async function runStack(id, options = {}) {
33271
33271
  const startTime = Date.now();
33272
33272
  const packagePath = getPackagePath2(id);
33273
33273
  const manifestPath = import_path11.default.join(packagePath, "manifest.json");
33274
- const { default: fs34 } = await import("fs");
33275
- if (!fs34.existsSync(manifestPath)) {
33274
+ const { default: fs35 } = await import("fs");
33275
+ if (!fs35.existsSync(manifestPath)) {
33276
33276
  throw new Error(`Stack manifest not found: ${id}`);
33277
33277
  }
33278
- const manifest = JSON.parse(fs34.readFileSync(manifestPath, "utf-8"));
33278
+ const manifest = JSON.parse(fs35.readFileSync(manifestPath, "utf-8"));
33279
33279
  const { command, args } = resolveCommandFromManifest(manifest, packagePath);
33280
33280
  const secrets = await getSecrets(manifest.requires?.secrets || []);
33281
33281
  const runEnv = {
@@ -36333,8 +36333,8 @@ async function ensureEmbeddingProvider(preferredProvider = "auto", options = {})
36333
36333
  });
36334
36334
  console.log("\r \u2713 Ollama installed ");
36335
36335
  console.log(" Starting ollama serve...");
36336
- const { spawn: spawn4 } = await import("child_process");
36337
- const server = spawn4("ollama", ["serve"], {
36336
+ const { spawn: spawn5 } = await import("child_process");
36337
+ const server = spawn5("ollama", ["serve"], {
36338
36338
  detached: true,
36339
36339
  stdio: "ignore",
36340
36340
  env: { ...process.env, HOME: process.env.HOME }
@@ -36342,8 +36342,8 @@ async function ensureEmbeddingProvider(preferredProvider = "auto", options = {})
36342
36342
  server.unref();
36343
36343
  await new Promise((r2) => setTimeout(r2, 2e3));
36344
36344
  console.log(" Pulling nomic-embed-text model (274MB)...");
36345
- const { execSync: execSync10 } = await import("child_process");
36346
- execSync10("ollama pull nomic-embed-text", { stdio: "inherit" });
36345
+ const { execSync: execSync11 } = await import("child_process");
36346
+ execSync11("ollama pull nomic-embed-text", { stdio: "inherit" });
36347
36347
  console.log(" \u2713 Model ready\n");
36348
36348
  return await getProvider2("ollama");
36349
36349
  } catch (err) {
@@ -36690,9 +36690,9 @@ async function sessionExport(args, flags) {
36690
36690
  };
36691
36691
  const json = JSON.stringify(exportData, null, 2);
36692
36692
  if (flags.output || flags.o) {
36693
- const fs34 = await import("fs");
36693
+ const fs35 = await import("fs");
36694
36694
  const outputFile = flags.output || flags.o;
36695
- fs34.writeFileSync(outputFile, json);
36695
+ fs35.writeFileSync(outputFile, json);
36696
36696
  console.log(`\u2713 Exported session to: ${outputFile}`);
36697
36697
  } else {
36698
36698
  console.log(json);
@@ -40435,6 +40435,240 @@ Project deleted: ${project.name}`);
40435
40435
  }
40436
40436
  }
40437
40437
 
40438
+ // src/commands/studio.js
40439
+ var import_fs29 = __toESM(require("fs"), 1);
40440
+ var import_path27 = __toESM(require("path"), 1);
40441
+ var import_os10 = __toESM(require("os"), 1);
40442
+ var import_child_process13 = require("child_process");
40443
+ var STUDIO_WEBSITE = "https://learnrudi.com";
40444
+ var STUDIO_PATHS = {
40445
+ darwin: [
40446
+ "/Applications/RUDI Studio.app",
40447
+ import_path27.default.join(import_os10.default.homedir(), "Applications/RUDI Studio.app")
40448
+ ],
40449
+ win32: [
40450
+ import_path27.default.join(import_os10.default.homedir(), "AppData/Local/Programs/RUDI Studio"),
40451
+ "C:/Program Files/RUDI Studio"
40452
+ ],
40453
+ linux: [
40454
+ "/opt/RUDI Studio",
40455
+ import_path27.default.join(import_os10.default.homedir(), ".local/share/applications/rudi-studio")
40456
+ ]
40457
+ };
40458
+ var APP_DATA_PATHS = {
40459
+ darwin: [
40460
+ import_path27.default.join(import_os10.default.homedir(), "Library/Application Support/RUDI Studio"),
40461
+ import_path27.default.join(import_os10.default.homedir(), "Library/Application Support/rudi-studio"),
40462
+ import_path27.default.join(import_os10.default.homedir(), "Library/Caches/RUDI Studio"),
40463
+ import_path27.default.join(import_os10.default.homedir(), "Library/Caches/rudi-studio"),
40464
+ import_path27.default.join(import_os10.default.homedir(), "Library/Preferences/com.rudi.studio.plist"),
40465
+ import_path27.default.join(import_os10.default.homedir(), "Library/Saved Application State/com.rudi.studio.savedState")
40466
+ ],
40467
+ win32: [
40468
+ import_path27.default.join(import_os10.default.homedir(), "AppData/Roaming/RUDI Studio"),
40469
+ import_path27.default.join(import_os10.default.homedir(), "AppData/Local/RUDI Studio")
40470
+ ],
40471
+ linux: [
40472
+ import_path27.default.join(import_os10.default.homedir(), ".config/RUDI Studio"),
40473
+ import_path27.default.join(import_os10.default.homedir(), ".config/rudi-studio")
40474
+ ]
40475
+ };
40476
+ function findStudioPath() {
40477
+ const platform = process.platform;
40478
+ const paths = STUDIO_PATHS[platform] || [];
40479
+ for (const p2 of paths) {
40480
+ if (import_fs29.default.existsSync(p2)) {
40481
+ return p2;
40482
+ }
40483
+ }
40484
+ if (platform === "darwin") {
40485
+ try {
40486
+ const result = (0, import_child_process13.execSync)(`mdfind "kMDItemCFBundleIdentifier == 'com.rudi.studio'" 2>/dev/null`, {
40487
+ encoding: "utf-8",
40488
+ timeout: 5e3
40489
+ }).trim();
40490
+ if (result) {
40491
+ const foundPath = result.split("\n")[0];
40492
+ if (import_fs29.default.existsSync(foundPath)) {
40493
+ return foundPath;
40494
+ }
40495
+ }
40496
+ const nameResult = (0, import_child_process13.execSync)(`mdfind "kMDItemDisplayName == 'RUDI Studio' && kMDItemContentType == 'com.apple.application-bundle'" 2>/dev/null`, {
40497
+ encoding: "utf-8",
40498
+ timeout: 5e3
40499
+ }).trim();
40500
+ if (nameResult) {
40501
+ const foundPath = nameResult.split("\n")[0];
40502
+ if (import_fs29.default.existsSync(foundPath)) {
40503
+ return foundPath;
40504
+ }
40505
+ }
40506
+ } catch {
40507
+ }
40508
+ }
40509
+ return null;
40510
+ }
40511
+ function getStudioVersion(studioPath) {
40512
+ if (process.platform === "darwin") {
40513
+ const plistPath = import_path27.default.join(studioPath, "Contents/Info.plist");
40514
+ if (import_fs29.default.existsSync(plistPath)) {
40515
+ const content = import_fs29.default.readFileSync(plistPath, "utf-8");
40516
+ const match = content.match(/<key>CFBundleShortVersionString<\/key>\s*<string>([^<]+)<\/string>/);
40517
+ if (match) {
40518
+ return match[1];
40519
+ }
40520
+ }
40521
+ } else {
40522
+ const pkgPath = import_path27.default.join(studioPath, "resources/app/package.json");
40523
+ if (import_fs29.default.existsSync(pkgPath)) {
40524
+ try {
40525
+ const pkg = JSON.parse(import_fs29.default.readFileSync(pkgPath, "utf-8"));
40526
+ return pkg.version;
40527
+ } catch {
40528
+ }
40529
+ }
40530
+ }
40531
+ return null;
40532
+ }
40533
+ function openUrl(url) {
40534
+ const platform = process.platform;
40535
+ let cmd, args;
40536
+ if (platform === "darwin") {
40537
+ cmd = "open";
40538
+ args = [url];
40539
+ } else if (platform === "win32") {
40540
+ cmd = "cmd";
40541
+ args = ["/c", "start", "", url];
40542
+ } else {
40543
+ cmd = "xdg-open";
40544
+ args = [url];
40545
+ }
40546
+ (0, import_child_process13.spawn)(cmd, args, { detached: true, stdio: "ignore" }).unref();
40547
+ }
40548
+ async function studioOpen() {
40549
+ console.log(`Opening ${STUDIO_WEBSITE}...`);
40550
+ openUrl(STUDIO_WEBSITE);
40551
+ }
40552
+ async function studioVersion(flags) {
40553
+ const studioPath = findStudioPath();
40554
+ if (!studioPath) {
40555
+ console.log("RUDI Studio is not installed");
40556
+ console.log(`
40557
+ Get it at: ${STUDIO_WEBSITE}`);
40558
+ process.exit(1);
40559
+ }
40560
+ const version = getStudioVersion(studioPath);
40561
+ if (version) {
40562
+ console.log(`RUDI Studio v${version}`);
40563
+ } else {
40564
+ console.log("RUDI Studio installed");
40565
+ console.log(` Location: ${studioPath}`);
40566
+ console.log(" Version: unknown");
40567
+ }
40568
+ if (flags.verbose) {
40569
+ console.log(`
40570
+ Path: ${studioPath}`);
40571
+ }
40572
+ }
40573
+ async function studioUninstall(flags) {
40574
+ const studioPath = findStudioPath();
40575
+ const platform = process.platform;
40576
+ const dataPaths = APP_DATA_PATHS[platform] || [];
40577
+ const existingDataPaths = dataPaths.filter((p2) => import_fs29.default.existsSync(p2));
40578
+ if (!studioPath && existingDataPaths.length === 0) {
40579
+ console.log("RUDI Studio is not installed");
40580
+ process.exit(0);
40581
+ }
40582
+ console.log("The following will be removed:");
40583
+ if (studioPath) {
40584
+ console.log(` App: ${studioPath}`);
40585
+ }
40586
+ for (const p2 of existingDataPaths) {
40587
+ console.log(` Data: ${p2}`);
40588
+ }
40589
+ console.log("");
40590
+ console.log("Note: ~/.rudi/ will NOT be removed (managed by RUDI CLI)");
40591
+ console.log("");
40592
+ if (!flags.force && !flags.y) {
40593
+ console.log("Run with --force or -y to confirm uninstall");
40594
+ process.exit(0);
40595
+ }
40596
+ let errors = [];
40597
+ if (studioPath) {
40598
+ try {
40599
+ import_fs29.default.rmSync(studioPath, { recursive: true, force: true });
40600
+ console.log(`Removed: ${studioPath}`);
40601
+ } catch (err) {
40602
+ errors.push(`Failed to remove ${studioPath}: ${err.message}`);
40603
+ }
40604
+ }
40605
+ for (const p2 of existingDataPaths) {
40606
+ try {
40607
+ import_fs29.default.rmSync(p2, { recursive: true, force: true });
40608
+ console.log(`Removed: ${p2}`);
40609
+ } catch (err) {
40610
+ errors.push(`Failed to remove ${p2}: ${err.message}`);
40611
+ }
40612
+ }
40613
+ if (errors.length > 0) {
40614
+ console.log("");
40615
+ console.log("Some items could not be removed:");
40616
+ for (const err of errors) {
40617
+ console.log(` ${err}`);
40618
+ }
40619
+ console.log("");
40620
+ console.log("You may need to remove them manually or use sudo.");
40621
+ process.exit(1);
40622
+ }
40623
+ console.log("");
40624
+ console.log("RUDI Studio uninstalled successfully");
40625
+ }
40626
+ function showHelp() {
40627
+ console.log(`rudi studio - Manage RUDI Studio
40628
+
40629
+ Usage:
40630
+ rudi studio Open RUDI website
40631
+ rudi studio version Show installed Studio version
40632
+ rudi studio uninstall Uninstall RUDI Studio
40633
+
40634
+ Options:
40635
+ --force, -y Skip confirmation for uninstall
40636
+ --verbose Show additional details
40637
+
40638
+ Examples:
40639
+ rudi studio # Open learnrudi.com in browser
40640
+ rudi studio version # Check installed version
40641
+ rudi studio uninstall -y # Remove Studio and app data
40642
+ `);
40643
+ }
40644
+ async function cmdStudio(args, flags) {
40645
+ const subcommand = args[0];
40646
+ switch (subcommand) {
40647
+ case "version":
40648
+ case "v":
40649
+ await studioVersion(flags);
40650
+ break;
40651
+ case "uninstall":
40652
+ case "remove":
40653
+ case "rm":
40654
+ await studioUninstall(flags);
40655
+ break;
40656
+ case "help":
40657
+ case "-h":
40658
+ case "--help":
40659
+ showHelp();
40660
+ break;
40661
+ case "open":
40662
+ case void 0:
40663
+ await studioOpen();
40664
+ break;
40665
+ default:
40666
+ console.error(`Unknown subcommand: ${subcommand}`);
40667
+ console.error(`Run 'rudi studio help' for usage`);
40668
+ process.exit(1);
40669
+ }
40670
+ }
40671
+
40438
40672
  // src/index.js
40439
40673
  var VERSION2 = "2.0.0";
40440
40674
  async function main() {
@@ -40542,6 +40776,9 @@ async function main() {
40542
40776
  case "package":
40543
40777
  await cmdInfo(args, flags);
40544
40778
  break;
40779
+ case "studio":
40780
+ await cmdStudio(args, flags);
40781
+ break;
40545
40782
  // Shortcuts for listing specific package types
40546
40783
  case "stacks":
40547
40784
  await cmdList(["stacks"], flags);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": "1.0.0",
3
- "generated": "2026-01-10T21:04:03.316Z",
3
+ "generated": "2026-01-10T22:47:26.415Z",
4
4
  "packages": {
5
5
  "runtimes": [
6
6
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@learnrudi/cli",
3
- "version": "1.10.3",
3
+ "version": "1.10.5",
4
4
  "description": "RUDI CLI - Install and manage MCP stacks, runtimes, and AI agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -15,15 +15,15 @@
15
15
  "dependencies": {
16
16
  "better-sqlite3": "^12.5.0",
17
17
  "@learnrudi/core": "1.0.5",
18
- "@learnrudi/db": "1.0.2",
19
18
  "@learnrudi/embeddings": "0.1.0",
19
+ "@learnrudi/db": "1.0.2",
20
20
  "@learnrudi/env": "1.0.1",
21
21
  "@learnrudi/manifest": "1.0.0",
22
22
  "@learnrudi/mcp": "1.0.0",
23
23
  "@learnrudi/registry-client": "1.0.5",
24
- "@learnrudi/runner": "1.0.1",
25
24
  "@learnrudi/secrets": "1.0.1",
26
- "@learnrudi/utils": "1.0.0"
25
+ "@learnrudi/utils": "1.0.0",
26
+ "@learnrudi/runner": "1.0.1"
27
27
  },
28
28
  "devDependencies": {
29
29
  "esbuild": "^0.27.2"