@learnrudi/cli 1.4.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.cjs +374 -181
  2. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -781,17 +781,17 @@ var require_visit = __commonJS({
781
781
  visit.BREAK = BREAK;
782
782
  visit.SKIP = SKIP;
783
783
  visit.REMOVE = REMOVE;
784
- function visit_(key, node, visitor, path17) {
785
- const ctrl = callVisitor(key, node, visitor, path17);
784
+ function visit_(key, node, visitor, path18) {
785
+ const ctrl = callVisitor(key, node, visitor, path18);
786
786
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
787
- replaceNode(key, path17, ctrl);
788
- return visit_(key, ctrl, visitor, path17);
787
+ replaceNode(key, path18, ctrl);
788
+ return visit_(key, ctrl, visitor, path18);
789
789
  }
790
790
  if (typeof ctrl !== "symbol") {
791
791
  if (identity.isCollection(node)) {
792
- path17 = Object.freeze(path17.concat(node));
792
+ path18 = Object.freeze(path18.concat(node));
793
793
  for (let i = 0; i < node.items.length; ++i) {
794
- const ci = visit_(i, node.items[i], visitor, path17);
794
+ const ci = visit_(i, node.items[i], visitor, path18);
795
795
  if (typeof ci === "number")
796
796
  i = ci - 1;
797
797
  else if (ci === BREAK)
@@ -802,13 +802,13 @@ var require_visit = __commonJS({
802
802
  }
803
803
  }
804
804
  } else if (identity.isPair(node)) {
805
- path17 = Object.freeze(path17.concat(node));
806
- const ck = visit_("key", node.key, visitor, path17);
805
+ path18 = Object.freeze(path18.concat(node));
806
+ const ck = visit_("key", node.key, visitor, path18);
807
807
  if (ck === BREAK)
808
808
  return BREAK;
809
809
  else if (ck === REMOVE)
810
810
  node.key = null;
811
- const cv = visit_("value", node.value, visitor, path17);
811
+ const cv = visit_("value", node.value, visitor, path18);
812
812
  if (cv === BREAK)
813
813
  return BREAK;
814
814
  else if (cv === REMOVE)
@@ -829,17 +829,17 @@ var require_visit = __commonJS({
829
829
  visitAsync.BREAK = BREAK;
830
830
  visitAsync.SKIP = SKIP;
831
831
  visitAsync.REMOVE = REMOVE;
832
- async function visitAsync_(key, node, visitor, path17) {
833
- const ctrl = await callVisitor(key, node, visitor, path17);
832
+ async function visitAsync_(key, node, visitor, path18) {
833
+ const ctrl = await callVisitor(key, node, visitor, path18);
834
834
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
835
- replaceNode(key, path17, ctrl);
836
- return visitAsync_(key, ctrl, visitor, path17);
835
+ replaceNode(key, path18, ctrl);
836
+ return visitAsync_(key, ctrl, visitor, path18);
837
837
  }
838
838
  if (typeof ctrl !== "symbol") {
839
839
  if (identity.isCollection(node)) {
840
- path17 = Object.freeze(path17.concat(node));
840
+ path18 = Object.freeze(path18.concat(node));
841
841
  for (let i = 0; i < node.items.length; ++i) {
842
- const ci = await visitAsync_(i, node.items[i], visitor, path17);
842
+ const ci = await visitAsync_(i, node.items[i], visitor, path18);
843
843
  if (typeof ci === "number")
844
844
  i = ci - 1;
845
845
  else if (ci === BREAK)
@@ -850,13 +850,13 @@ var require_visit = __commonJS({
850
850
  }
851
851
  }
852
852
  } else if (identity.isPair(node)) {
853
- path17 = Object.freeze(path17.concat(node));
854
- const ck = await visitAsync_("key", node.key, visitor, path17);
853
+ path18 = Object.freeze(path18.concat(node));
854
+ const ck = await visitAsync_("key", node.key, visitor, path18);
855
855
  if (ck === BREAK)
856
856
  return BREAK;
857
857
  else if (ck === REMOVE)
858
858
  node.key = null;
859
- const cv = await visitAsync_("value", node.value, visitor, path17);
859
+ const cv = await visitAsync_("value", node.value, visitor, path18);
860
860
  if (cv === BREAK)
861
861
  return BREAK;
862
862
  else if (cv === REMOVE)
@@ -883,23 +883,23 @@ var require_visit = __commonJS({
883
883
  }
884
884
  return visitor;
885
885
  }
886
- function callVisitor(key, node, visitor, path17) {
886
+ function callVisitor(key, node, visitor, path18) {
887
887
  if (typeof visitor === "function")
888
- return visitor(key, node, path17);
888
+ return visitor(key, node, path18);
889
889
  if (identity.isMap(node))
890
- return visitor.Map?.(key, node, path17);
890
+ return visitor.Map?.(key, node, path18);
891
891
  if (identity.isSeq(node))
892
- return visitor.Seq?.(key, node, path17);
892
+ return visitor.Seq?.(key, node, path18);
893
893
  if (identity.isPair(node))
894
- return visitor.Pair?.(key, node, path17);
894
+ return visitor.Pair?.(key, node, path18);
895
895
  if (identity.isScalar(node))
896
- return visitor.Scalar?.(key, node, path17);
896
+ return visitor.Scalar?.(key, node, path18);
897
897
  if (identity.isAlias(node))
898
- return visitor.Alias?.(key, node, path17);
898
+ return visitor.Alias?.(key, node, path18);
899
899
  return void 0;
900
900
  }
901
- function replaceNode(key, path17, node) {
902
- const parent = path17[path17.length - 1];
901
+ function replaceNode(key, path18, node) {
902
+ const parent = path18[path18.length - 1];
903
903
  if (identity.isCollection(parent)) {
904
904
  parent.items[key] = node;
905
905
  } else if (identity.isPair(parent)) {
@@ -1507,10 +1507,10 @@ var require_Collection = __commonJS({
1507
1507
  var createNode = require_createNode();
1508
1508
  var identity = require_identity();
1509
1509
  var Node = require_Node();
1510
- function collectionFromPath(schema, path17, value) {
1510
+ function collectionFromPath(schema, path18, value) {
1511
1511
  let v = value;
1512
- for (let i = path17.length - 1; i >= 0; --i) {
1513
- const k = path17[i];
1512
+ for (let i = path18.length - 1; i >= 0; --i) {
1513
+ const k = path18[i];
1514
1514
  if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
1515
1515
  const a = [];
1516
1516
  a[k] = v;
@@ -1529,7 +1529,7 @@ var require_Collection = __commonJS({
1529
1529
  sourceObjects: /* @__PURE__ */ new Map()
1530
1530
  });
1531
1531
  }
1532
- var isEmptyPath = (path17) => path17 == null || typeof path17 === "object" && !!path17[Symbol.iterator]().next().done;
1532
+ var isEmptyPath = (path18) => path18 == null || typeof path18 === "object" && !!path18[Symbol.iterator]().next().done;
1533
1533
  var Collection = class extends Node.NodeBase {
1534
1534
  constructor(type, schema) {
1535
1535
  super(type);
@@ -1559,11 +1559,11 @@ var require_Collection = __commonJS({
1559
1559
  * be a Pair instance or a `{ key, value }` object, which may not have a key
1560
1560
  * that already exists in the map.
1561
1561
  */
1562
- addIn(path17, value) {
1563
- if (isEmptyPath(path17))
1562
+ addIn(path18, value) {
1563
+ if (isEmptyPath(path18))
1564
1564
  this.add(value);
1565
1565
  else {
1566
- const [key, ...rest] = path17;
1566
+ const [key, ...rest] = path18;
1567
1567
  const node = this.get(key, true);
1568
1568
  if (identity.isCollection(node))
1569
1569
  node.addIn(rest, value);
@@ -1577,8 +1577,8 @@ var require_Collection = __commonJS({
1577
1577
  * Removes a value from the collection.
1578
1578
  * @returns `true` if the item was found and removed.
1579
1579
  */
1580
- deleteIn(path17) {
1581
- const [key, ...rest] = path17;
1580
+ deleteIn(path18) {
1581
+ const [key, ...rest] = path18;
1582
1582
  if (rest.length === 0)
1583
1583
  return this.delete(key);
1584
1584
  const node = this.get(key, true);
@@ -1592,8 +1592,8 @@ var require_Collection = __commonJS({
1592
1592
  * scalar values from their surrounding node; to disable set `keepScalar` to
1593
1593
  * `true` (collections are always returned intact).
1594
1594
  */
1595
- getIn(path17, keepScalar) {
1596
- const [key, ...rest] = path17;
1595
+ getIn(path18, keepScalar) {
1596
+ const [key, ...rest] = path18;
1597
1597
  const node = this.get(key, true);
1598
1598
  if (rest.length === 0)
1599
1599
  return !keepScalar && identity.isScalar(node) ? node.value : node;
@@ -1611,8 +1611,8 @@ var require_Collection = __commonJS({
1611
1611
  /**
1612
1612
  * Checks if the collection includes a value with the key `key`.
1613
1613
  */
1614
- hasIn(path17) {
1615
- const [key, ...rest] = path17;
1614
+ hasIn(path18) {
1615
+ const [key, ...rest] = path18;
1616
1616
  if (rest.length === 0)
1617
1617
  return this.has(key);
1618
1618
  const node = this.get(key, true);
@@ -1622,8 +1622,8 @@ var require_Collection = __commonJS({
1622
1622
  * Sets a value in this collection. For `!!set`, `value` needs to be a
1623
1623
  * boolean to add/remove the item from the set.
1624
1624
  */
1625
- setIn(path17, value) {
1626
- const [key, ...rest] = path17;
1625
+ setIn(path18, value) {
1626
+ const [key, ...rest] = path18;
1627
1627
  if (rest.length === 0) {
1628
1628
  this.set(key, value);
1629
1629
  } else {
@@ -4127,9 +4127,9 @@ var require_Document = __commonJS({
4127
4127
  this.contents.add(value);
4128
4128
  }
4129
4129
  /** Adds a value to the document. */
4130
- addIn(path17, value) {
4130
+ addIn(path18, value) {
4131
4131
  if (assertCollection(this.contents))
4132
- this.contents.addIn(path17, value);
4132
+ this.contents.addIn(path18, value);
4133
4133
  }
4134
4134
  /**
4135
4135
  * Create a new `Alias` node, ensuring that the target `node` has the required anchor.
@@ -4204,14 +4204,14 @@ var require_Document = __commonJS({
4204
4204
  * Removes a value from the document.
4205
4205
  * @returns `true` if the item was found and removed.
4206
4206
  */
4207
- deleteIn(path17) {
4208
- if (Collection.isEmptyPath(path17)) {
4207
+ deleteIn(path18) {
4208
+ if (Collection.isEmptyPath(path18)) {
4209
4209
  if (this.contents == null)
4210
4210
  return false;
4211
4211
  this.contents = null;
4212
4212
  return true;
4213
4213
  }
4214
- return assertCollection(this.contents) ? this.contents.deleteIn(path17) : false;
4214
+ return assertCollection(this.contents) ? this.contents.deleteIn(path18) : false;
4215
4215
  }
4216
4216
  /**
4217
4217
  * Returns item at `key`, or `undefined` if not found. By default unwraps
@@ -4226,10 +4226,10 @@ var require_Document = __commonJS({
4226
4226
  * scalar values from their surrounding node; to disable set `keepScalar` to
4227
4227
  * `true` (collections are always returned intact).
4228
4228
  */
4229
- getIn(path17, keepScalar) {
4230
- if (Collection.isEmptyPath(path17))
4229
+ getIn(path18, keepScalar) {
4230
+ if (Collection.isEmptyPath(path18))
4231
4231
  return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
4232
- return identity.isCollection(this.contents) ? this.contents.getIn(path17, keepScalar) : void 0;
4232
+ return identity.isCollection(this.contents) ? this.contents.getIn(path18, keepScalar) : void 0;
4233
4233
  }
4234
4234
  /**
4235
4235
  * Checks if the document includes a value with the key `key`.
@@ -4240,10 +4240,10 @@ var require_Document = __commonJS({
4240
4240
  /**
4241
4241
  * Checks if the document includes a value at `path`.
4242
4242
  */
4243
- hasIn(path17) {
4244
- if (Collection.isEmptyPath(path17))
4243
+ hasIn(path18) {
4244
+ if (Collection.isEmptyPath(path18))
4245
4245
  return this.contents !== void 0;
4246
- return identity.isCollection(this.contents) ? this.contents.hasIn(path17) : false;
4246
+ return identity.isCollection(this.contents) ? this.contents.hasIn(path18) : false;
4247
4247
  }
4248
4248
  /**
4249
4249
  * Sets a value in this document. For `!!set`, `value` needs to be a
@@ -4260,13 +4260,13 @@ var require_Document = __commonJS({
4260
4260
  * Sets a value in this document. For `!!set`, `value` needs to be a
4261
4261
  * boolean to add/remove the item from the set.
4262
4262
  */
4263
- setIn(path17, value) {
4264
- if (Collection.isEmptyPath(path17)) {
4263
+ setIn(path18, value) {
4264
+ if (Collection.isEmptyPath(path18)) {
4265
4265
  this.contents = value;
4266
4266
  } else if (this.contents == null) {
4267
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path17), value);
4267
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path18), value);
4268
4268
  } else if (assertCollection(this.contents)) {
4269
- this.contents.setIn(path17, value);
4269
+ this.contents.setIn(path18, value);
4270
4270
  }
4271
4271
  }
4272
4272
  /**
@@ -6218,9 +6218,9 @@ var require_cst_visit = __commonJS({
6218
6218
  visit.BREAK = BREAK;
6219
6219
  visit.SKIP = SKIP;
6220
6220
  visit.REMOVE = REMOVE;
6221
- visit.itemAtPath = (cst, path17) => {
6221
+ visit.itemAtPath = (cst, path18) => {
6222
6222
  let item = cst;
6223
- for (const [field, index] of path17) {
6223
+ for (const [field, index] of path18) {
6224
6224
  const tok = item?.[field];
6225
6225
  if (tok && "items" in tok) {
6226
6226
  item = tok.items[index];
@@ -6229,23 +6229,23 @@ var require_cst_visit = __commonJS({
6229
6229
  }
6230
6230
  return item;
6231
6231
  };
6232
- visit.parentCollection = (cst, path17) => {
6233
- const parent = visit.itemAtPath(cst, path17.slice(0, -1));
6234
- const field = path17[path17.length - 1][0];
6232
+ visit.parentCollection = (cst, path18) => {
6233
+ const parent = visit.itemAtPath(cst, path18.slice(0, -1));
6234
+ const field = path18[path18.length - 1][0];
6235
6235
  const coll = parent?.[field];
6236
6236
  if (coll && "items" in coll)
6237
6237
  return coll;
6238
6238
  throw new Error("Parent collection not found");
6239
6239
  };
6240
- function _visit(path17, item, visitor) {
6241
- let ctrl = visitor(item, path17);
6240
+ function _visit(path18, item, visitor) {
6241
+ let ctrl = visitor(item, path18);
6242
6242
  if (typeof ctrl === "symbol")
6243
6243
  return ctrl;
6244
6244
  for (const field of ["key", "value"]) {
6245
6245
  const token = item[field];
6246
6246
  if (token && "items" in token) {
6247
6247
  for (let i = 0; i < token.items.length; ++i) {
6248
- const ci = _visit(Object.freeze(path17.concat([[field, i]])), token.items[i], visitor);
6248
+ const ci = _visit(Object.freeze(path18.concat([[field, i]])), token.items[i], visitor);
6249
6249
  if (typeof ci === "number")
6250
6250
  i = ci - 1;
6251
6251
  else if (ci === BREAK)
@@ -6256,10 +6256,10 @@ var require_cst_visit = __commonJS({
6256
6256
  }
6257
6257
  }
6258
6258
  if (typeof ctrl === "function" && field === "key")
6259
- ctrl = ctrl(item, path17);
6259
+ ctrl = ctrl(item, path18);
6260
6260
  }
6261
6261
  }
6262
- return typeof ctrl === "function" ? ctrl(item, path17) : ctrl;
6262
+ return typeof ctrl === "function" ? ctrl(item, path18) : ctrl;
6263
6263
  }
6264
6264
  exports2.visit = visit;
6265
6265
  }
@@ -7544,14 +7544,14 @@ var require_parser = __commonJS({
7544
7544
  case "scalar":
7545
7545
  case "single-quoted-scalar":
7546
7546
  case "double-quoted-scalar": {
7547
- const fs19 = this.flowScalar(this.type);
7547
+ const fs20 = this.flowScalar(this.type);
7548
7548
  if (atNextItem || it.value) {
7549
- map.items.push({ start, key: fs19, sep: [] });
7549
+ map.items.push({ start, key: fs20, sep: [] });
7550
7550
  this.onKeyLine = true;
7551
7551
  } else if (it.sep) {
7552
- this.stack.push(fs19);
7552
+ this.stack.push(fs20);
7553
7553
  } else {
7554
- Object.assign(it, { key: fs19, sep: [] });
7554
+ Object.assign(it, { key: fs20, sep: [] });
7555
7555
  this.onKeyLine = true;
7556
7556
  }
7557
7557
  return;
@@ -7679,13 +7679,13 @@ var require_parser = __commonJS({
7679
7679
  case "scalar":
7680
7680
  case "single-quoted-scalar":
7681
7681
  case "double-quoted-scalar": {
7682
- const fs19 = this.flowScalar(this.type);
7682
+ const fs20 = this.flowScalar(this.type);
7683
7683
  if (!it || it.value)
7684
- fc.items.push({ start: [], key: fs19, sep: [] });
7684
+ fc.items.push({ start: [], key: fs20, sep: [] });
7685
7685
  else if (it.sep)
7686
- this.stack.push(fs19);
7686
+ this.stack.push(fs20);
7687
7687
  else
7688
- Object.assign(it, { key: fs19, sep: [] });
7688
+ Object.assign(it, { key: fs20, sep: [] });
7689
7689
  return;
7690
7690
  }
7691
7691
  case "flow-map-end":
@@ -11186,8 +11186,8 @@ var require_utils = __commonJS({
11186
11186
  }
11187
11187
  return ind;
11188
11188
  }
11189
- function removeDotSegments(path17) {
11190
- let input = path17;
11189
+ function removeDotSegments(path18) {
11190
+ let input = path18;
11191
11191
  const output = [];
11192
11192
  let nextSlash = -1;
11193
11193
  let len = 0;
@@ -11386,8 +11386,8 @@ var require_schemes = __commonJS({
11386
11386
  wsComponent.secure = void 0;
11387
11387
  }
11388
11388
  if (wsComponent.resourceName) {
11389
- const [path17, query] = wsComponent.resourceName.split("?");
11390
- wsComponent.path = path17 && path17 !== "/" ? path17 : void 0;
11389
+ const [path18, query] = wsComponent.resourceName.split("?");
11390
+ wsComponent.path = path18 && path18 !== "/" ? path18 : void 0;
11391
11391
  wsComponent.query = query;
11392
11392
  wsComponent.resourceName = void 0;
11393
11393
  }
@@ -14740,12 +14740,12 @@ var require_dist2 = __commonJS({
14740
14740
  throw new Error(`Unknown format "${name}"`);
14741
14741
  return f;
14742
14742
  };
14743
- function addFormats2(ajv2, list, fs19, exportName) {
14743
+ function addFormats2(ajv2, list, fs20, exportName) {
14744
14744
  var _a;
14745
14745
  var _b;
14746
14746
  (_a = (_b = ajv2.opts.code).formats) !== null && _a !== void 0 ? _a : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
14747
14747
  for (const f of list)
14748
- ajv2.addFormat(f, fs19[f]);
14748
+ ajv2.addFormat(f, fs20[f]);
14749
14749
  }
14750
14750
  module2.exports = exports2 = formatsPlugin;
14751
14751
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -14819,51 +14819,60 @@ rudi - RUDI CLI
14819
14819
  USAGE
14820
14820
  rudi <command> [options]
14821
14821
 
14822
- COMMANDS
14823
- search <query> Search for stacks, prompts, runtimes, binaries, agents
14824
- search --all List all available packages in registry
14825
- install <pkg> Install a package (stack, prompt, runtime, binary, agent)
14826
- remove <pkg> Remove an installed package
14827
- update [pkg] Update packages (or all if no pkg specified)
14828
- run <stack> [args] Run a stack with optional arguments
14829
- list [kind] List installed packages (stacks, prompts, runtimes, binaries, agents)
14830
-
14831
- secrets set <name> Set a secret
14832
- secrets list List configured secrets (masked)
14833
- secrets remove <name> Remove a secret
14834
-
14822
+ INTROSPECTION
14823
+ home Show ~/.rudi structure and installed packages
14824
+ stacks List installed stacks
14825
+ runtimes List installed runtimes
14826
+ binaries List installed binaries
14827
+ agents List installed agents
14828
+ prompts List installed prompts
14829
+ doctor Check system health and dependencies
14830
+ doctor --all Show all available runtimes/binaries from registry
14831
+
14832
+ PACKAGE MANAGEMENT
14833
+ search <query> Search registry for packages
14834
+ search --all List all available packages
14835
+ install <pkg> Install a package
14836
+ remove <pkg> Remove a package
14837
+ update [pkg] Update packages
14838
+ run <stack> Run a stack
14839
+
14840
+ DATABASE
14835
14841
  db stats Show database statistics
14836
14842
  db search <query> Search conversation history
14843
+ db reset --force Delete all data
14844
+ db vacuum Compact and reclaim space
14845
+ db tables Show table row counts
14837
14846
 
14838
- import sessions Import sessions from AI providers (claude, codex, gemini)
14839
- import status Show import status for all providers
14840
-
14841
- logs [options] Query agent visibility logs
14847
+ SESSION IMPORT
14848
+ import sessions Import from AI providers (claude, codex, gemini)
14849
+ import status Show import status
14842
14850
 
14843
- doctor Check system health and configuration
14851
+ SECRETS
14852
+ secrets set <name> Set a secret
14853
+ secrets list List configured secrets
14854
+ secrets remove <name> Remove a secret
14844
14855
 
14845
14856
  OPTIONS
14846
14857
  -h, --help Show help
14847
14858
  -v, --version Show version
14848
14859
  --verbose Verbose output
14849
14860
  --json Output as JSON
14850
- --force Force operation (skip confirmations)
14861
+ --force Force operation
14851
14862
 
14852
14863
  EXAMPLES
14853
- rudi search pdf Search for PDF-related stacks
14854
- rudi install pdf-creator Install the pdf-creator stack
14855
- rudi run pdf-creator Run the pdf-creator stack
14856
- rudi list stacks List installed stacks
14857
- rudi secrets set VERCEL_KEY Set a secret
14858
-
14859
- PACKAGE NAMESPACES
14860
- stack:name A stack (executable workflow)
14861
- prompt:name A prompt template
14862
- runtime:name A runtime interpreter (node, python, deno, bun)
14863
- binary:name A utility binary (ffmpeg, imagemagick, ripgrep)
14864
- agent:name An AI CLI tool (claude, codex, gemini, copilot)
14865
-
14866
- If no namespace is given, 'stack:' is assumed.
14864
+ rudi home Show ~/.rudi structure
14865
+ rudi runtimes List installed runtimes
14866
+ rudi install runtime:python Install Python in ~/.rudi
14867
+ rudi install binary:ffmpeg Install ffmpeg
14868
+ rudi doctor --all Show all available deps
14869
+
14870
+ PACKAGE TYPES
14871
+ stack:name MCP server stack
14872
+ runtime:name Node, Python, Deno, Bun
14873
+ binary:name ffmpeg, ripgrep, etc.
14874
+ agent:name Claude, Codex, Gemini CLIs
14875
+ prompt:name Prompt template
14867
14876
  `);
14868
14877
  }
14869
14878
  function printCommandHelp(command) {
@@ -15007,6 +15016,27 @@ EXAMPLES
15007
15016
  rudi import sessions claude Import only Claude sessions
15008
15017
  rudi import sessions --dry-run Preview without importing
15009
15018
  rudi import status Check what's available to import
15019
+ `,
15020
+ home: `
15021
+ rudi home - Show ~/.rudi structure and status
15022
+
15023
+ USAGE
15024
+ rudi home [options]
15025
+
15026
+ OPTIONS
15027
+ --verbose Show package details
15028
+ --json Output as JSON
15029
+
15030
+ SHOWS
15031
+ - Directory structure with sizes
15032
+ - Installed package counts
15033
+ - Database status
15034
+ - Quick commands reference
15035
+
15036
+ EXAMPLES
15037
+ rudi home
15038
+ rudi home --verbose
15039
+ rudi home --json
15010
15040
  `,
15011
15041
  doctor: `
15012
15042
  rudi doctor - System health check
@@ -15016,13 +15046,20 @@ USAGE
15016
15046
 
15017
15047
  OPTIONS
15018
15048
  --fix Attempt to fix issues
15049
+ --all Show all available runtimes/binaries from registry
15019
15050
 
15020
15051
  CHECKS
15021
15052
  - Directory structure
15022
15053
  - Database integrity
15023
15054
  - Installed packages
15024
- - Required runtimes
15055
+ - Available runtimes (node, python, deno, bun)
15056
+ - Available binaries (ffmpeg, ripgrep, etc.)
15025
15057
  - Secrets configuration
15058
+
15059
+ EXAMPLES
15060
+ rudi doctor
15061
+ rudi doctor --fix
15062
+ rudi doctor --all
15026
15063
  `,
15027
15064
  logs: `
15028
15065
  rudi logs - Query agent visibility logs
@@ -16611,11 +16648,11 @@ async function runStack(id, options = {}) {
16611
16648
  const startTime = Date.now();
16612
16649
  const packagePath = getPackagePath(id);
16613
16650
  const manifestPath = import_path7.default.join(packagePath, "manifest.json");
16614
- const { default: fs19 } = await import("fs");
16615
- if (!fs19.existsSync(manifestPath)) {
16651
+ const { default: fs20 } = await import("fs");
16652
+ if (!fs20.existsSync(manifestPath)) {
16616
16653
  throw new Error(`Stack manifest not found: ${id}`);
16617
16654
  }
16618
- const manifest = JSON.parse(fs19.readFileSync(manifestPath, "utf-8"));
16655
+ const manifest = JSON.parse(fs20.readFileSync(manifestPath, "utf-8"));
16619
16656
  const { command, args } = resolveCommandFromManifest(manifest, packagePath);
16620
16657
  const secrets = await getSecrets(manifest.requires?.secrets || []);
16621
16658
  const runEnv = {
@@ -19085,9 +19122,143 @@ async function cmdDoctor(args, flags) {
19085
19122
  }
19086
19123
  }
19087
19124
 
19088
- // src/commands/update.js
19125
+ // src/commands/home.js
19089
19126
  var import_fs14 = __toESM(require("fs"), 1);
19090
19127
  var import_path13 = __toESM(require("path"), 1);
19128
+ function formatBytes2(bytes) {
19129
+ if (bytes === 0) return "0 B";
19130
+ const k = 1024;
19131
+ const sizes = ["B", "KB", "MB", "GB"];
19132
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
19133
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + " " + sizes[i];
19134
+ }
19135
+ function getDirSize(dir) {
19136
+ if (!import_fs14.default.existsSync(dir)) return 0;
19137
+ let size = 0;
19138
+ try {
19139
+ const entries = import_fs14.default.readdirSync(dir, { withFileTypes: true });
19140
+ for (const entry of entries) {
19141
+ const fullPath = import_path13.default.join(dir, entry.name);
19142
+ if (entry.isDirectory()) {
19143
+ size += getDirSize(fullPath);
19144
+ } else {
19145
+ size += import_fs14.default.statSync(fullPath).size;
19146
+ }
19147
+ }
19148
+ } catch {
19149
+ }
19150
+ return size;
19151
+ }
19152
+ function countItems(dir) {
19153
+ if (!import_fs14.default.existsSync(dir)) return 0;
19154
+ try {
19155
+ return import_fs14.default.readdirSync(dir).filter((f) => !f.startsWith(".")).length;
19156
+ } catch {
19157
+ return 0;
19158
+ }
19159
+ }
19160
+ async function cmdHome(args, flags) {
19161
+ console.log("\u2550".repeat(60));
19162
+ console.log("RUDI Home: " + PATHS.home);
19163
+ console.log("\u2550".repeat(60));
19164
+ if (flags.json) {
19165
+ const data = {
19166
+ home: PATHS.home,
19167
+ directories: {},
19168
+ packages: {},
19169
+ database: {}
19170
+ };
19171
+ const dirs2 = [
19172
+ { key: "stacks", path: PATHS.stacks },
19173
+ { key: "prompts", path: PATHS.prompts },
19174
+ { key: "runtimes", path: PATHS.runtimes },
19175
+ { key: "binaries", path: PATHS.binaries },
19176
+ { key: "agents", path: PATHS.agents },
19177
+ { key: "cache", path: PATHS.cache }
19178
+ ];
19179
+ for (const dir of dirs2) {
19180
+ data.directories[dir.key] = {
19181
+ path: dir.path,
19182
+ exists: import_fs14.default.existsSync(dir.path),
19183
+ items: countItems(dir.path),
19184
+ size: getDirSize(dir.path)
19185
+ };
19186
+ }
19187
+ for (const kind of ["stack", "prompt", "runtime", "binary", "agent"]) {
19188
+ data.packages[kind] = getInstalledPackages(kind).length;
19189
+ }
19190
+ data.database = {
19191
+ initialized: isDatabaseInitialized(),
19192
+ size: getDbSize() || 0
19193
+ };
19194
+ console.log(JSON.stringify(data, null, 2));
19195
+ return;
19196
+ }
19197
+ console.log("\n\u{1F4C1} Directory Structure\n");
19198
+ const dirs = [
19199
+ { name: "stacks", path: PATHS.stacks, icon: "\u{1F4E6}", desc: "MCP server stacks" },
19200
+ { name: "prompts", path: PATHS.prompts, icon: "\u{1F4DD}", desc: "Prompt templates" },
19201
+ { name: "runtimes", path: PATHS.runtimes, icon: "\u2699\uFE0F", desc: "Node, Python, Deno, Bun" },
19202
+ { name: "binaries", path: PATHS.binaries, icon: "\u{1F527}", desc: "ffmpeg, ripgrep, etc." },
19203
+ { name: "agents", path: PATHS.agents, icon: "\u{1F916}", desc: "Claude, Codex, Gemini CLIs" },
19204
+ { name: "cache", path: PATHS.cache, icon: "\u{1F4BE}", desc: "Registry cache" }
19205
+ ];
19206
+ for (const dir of dirs) {
19207
+ const exists = import_fs14.default.existsSync(dir.path);
19208
+ const count = countItems(dir.path);
19209
+ const size = getDirSize(dir.path);
19210
+ console.log(`${dir.icon} ${dir.name}/`);
19211
+ console.log(` ${dir.desc}`);
19212
+ if (exists) {
19213
+ console.log(` ${count} items, ${formatBytes2(size)}`);
19214
+ } else {
19215
+ console.log(` (not created)`);
19216
+ }
19217
+ console.log();
19218
+ }
19219
+ console.log("\u{1F4BE} Database");
19220
+ const dbPath = import_path13.default.join(PATHS.home, "rudi.db");
19221
+ if (import_fs14.default.existsSync(dbPath)) {
19222
+ const dbSize = getDbSize() || import_fs14.default.statSync(dbPath).size;
19223
+ console.log(` ${formatBytes2(dbSize)}`);
19224
+ console.log(` ${dbPath}`);
19225
+ } else {
19226
+ console.log(` Not initialized`);
19227
+ }
19228
+ console.log();
19229
+ console.log("\u2550".repeat(60));
19230
+ console.log("Installed Packages");
19231
+ console.log("\u2550".repeat(60));
19232
+ const kinds = ["stack", "prompt", "runtime", "binary", "agent"];
19233
+ let total = 0;
19234
+ for (const kind of kinds) {
19235
+ const packages = getInstalledPackages(kind);
19236
+ const label = kind === "binary" ? "Binaries" : `${kind.charAt(0).toUpperCase() + kind.slice(1)}s`;
19237
+ console.log(` ${label.padEnd(12)} ${packages.length}`);
19238
+ if (packages.length > 0 && flags.verbose) {
19239
+ for (const pkg of packages.slice(0, 3)) {
19240
+ console.log(` - ${pkg.name || pkg.id}`);
19241
+ }
19242
+ if (packages.length > 3) {
19243
+ console.log(` ... and ${packages.length - 3} more`);
19244
+ }
19245
+ }
19246
+ total += packages.length;
19247
+ }
19248
+ console.log("\u2500".repeat(30));
19249
+ console.log(` ${"Total".padEnd(12)} ${total}`);
19250
+ console.log("\n\u{1F4CB} Quick Commands");
19251
+ console.log("\u2500".repeat(30));
19252
+ console.log(" rudi list stacks Show installed stacks");
19253
+ console.log(" rudi list runtimes Show installed runtimes");
19254
+ console.log(" rudi list binaries Show installed binaries");
19255
+ console.log(" rudi doctor --all Check system dependencies");
19256
+ console.log(" rudi db stats Database statistics");
19257
+ }
19258
+
19259
+ // src/commands/update.js
19260
+ var import_fs15 = __toESM(require("fs"), 1);
19261
+ var import_path14 = __toESM(require("path"), 1);
19091
19262
  var import_child_process3 = require("child_process");
19092
19263
  init_src();
19093
19264
  init_src2();
@@ -19113,7 +19284,7 @@ async function cmdUpdate(args, flags) {
19113
19284
  async function updatePackage(pkgId, flags) {
19114
19285
  const [kind, name] = parsePackageId(pkgId);
19115
19286
  const installPath = getPackagePath(pkgId);
19116
- if (!import_fs14.default.existsSync(installPath)) {
19287
+ if (!import_fs15.default.existsSync(installPath)) {
19117
19288
  return { success: false, error: "Package not installed" };
19118
19289
  }
19119
19290
  const pkg = await getPackage(pkgId);
@@ -19136,7 +19307,7 @@ async function updatePackage(pkgId, flags) {
19136
19307
  }
19137
19308
  if (pkg.pipPackage) {
19138
19309
  try {
19139
- const venvPip = import_path13.default.join(installPath, "venv", "bin", "pip");
19310
+ const venvPip = import_path14.default.join(installPath, "venv", "bin", "pip");
19140
19311
  (0, import_child_process3.execSync)(`"${venvPip}" install --upgrade ${pkg.pipPackage}`, {
19141
19312
  stdio: flags.verbose ? "inherit" : "pipe"
19142
19313
  });
@@ -19153,7 +19324,7 @@ async function updatePackage(pkgId, flags) {
19153
19324
  if (kind === "runtime" && !pkg.npmPackage && !pkg.pipPackage) {
19154
19325
  try {
19155
19326
  const { downloadRuntime: downloadRuntime2 } = await Promise.resolve().then(() => (init_src2(), src_exports));
19156
- import_fs14.default.rmSync(installPath, { recursive: true, force: true });
19327
+ import_fs15.default.rmSync(installPath, { recursive: true, force: true });
19157
19328
  await downloadRuntime2(name, pkg.version || "latest", installPath, {
19158
19329
  onProgress: (p) => {
19159
19330
  if (flags.verbose) console.log(` ${p.phase}...`);
@@ -19173,8 +19344,8 @@ async function updateAll(flags) {
19173
19344
  let failed = 0;
19174
19345
  for (const kind of kinds) {
19175
19346
  const dir = kind === "runtime" ? PATHS.runtimes : kind === "stack" ? PATHS.stacks : PATHS.prompts;
19176
- if (!import_fs14.default.existsSync(dir)) continue;
19177
- const entries = import_fs14.default.readdirSync(dir, { withFileTypes: true });
19347
+ if (!import_fs15.default.existsSync(dir)) continue;
19348
+ const entries = import_fs15.default.readdirSync(dir, { withFileTypes: true });
19178
19349
  for (const entry of entries) {
19179
19350
  if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
19180
19351
  const pkgId = `${kind}:${entry.name}`;
@@ -19193,14 +19364,14 @@ Updated ${updated} package(s)${failed > 0 ? `, ${failed} failed` : ""}`);
19193
19364
  }
19194
19365
  function getInstalledVersion(installPath, npmPackage) {
19195
19366
  try {
19196
- const pkgJsonPath = import_path13.default.join(installPath, "node_modules", npmPackage.replace("@", "").split("/")[0], "package.json");
19197
- if (import_fs14.default.existsSync(pkgJsonPath)) {
19198
- const pkgJson = JSON.parse(import_fs14.default.readFileSync(pkgJsonPath, "utf-8"));
19367
+ const pkgJsonPath = import_path14.default.join(installPath, "node_modules", npmPackage.replace("@", "").split("/")[0], "package.json");
19368
+ if (import_fs15.default.existsSync(pkgJsonPath)) {
19369
+ const pkgJson = JSON.parse(import_fs15.default.readFileSync(pkgJsonPath, "utf-8"));
19199
19370
  return pkgJson.version;
19200
19371
  }
19201
- const rootPkgPath = import_path13.default.join(installPath, "package.json");
19202
- if (import_fs14.default.existsSync(rootPkgPath)) {
19203
- const rootPkg = JSON.parse(import_fs14.default.readFileSync(rootPkgPath, "utf-8"));
19372
+ const rootPkgPath = import_path14.default.join(installPath, "package.json");
19373
+ if (import_fs15.default.existsSync(rootPkgPath)) {
19374
+ const rootPkg = JSON.parse(import_fs15.default.readFileSync(rootPkgPath, "utf-8"));
19204
19375
  const dep = rootPkg.dependencies?.[npmPackage];
19205
19376
  if (dep) return dep.replace(/[\^~]/, "");
19206
19377
  }
@@ -19209,30 +19380,30 @@ function getInstalledVersion(installPath, npmPackage) {
19209
19380
  return null;
19210
19381
  }
19211
19382
  function updateRuntimeMetadata(installPath, updates) {
19212
- const metaPath = import_path13.default.join(installPath, "runtime.json");
19383
+ const metaPath = import_path14.default.join(installPath, "runtime.json");
19213
19384
  try {
19214
19385
  let meta = {};
19215
- if (import_fs14.default.existsSync(metaPath)) {
19216
- meta = JSON.parse(import_fs14.default.readFileSync(metaPath, "utf-8"));
19386
+ if (import_fs15.default.existsSync(metaPath)) {
19387
+ meta = JSON.parse(import_fs15.default.readFileSync(metaPath, "utf-8"));
19217
19388
  }
19218
19389
  meta = { ...meta, ...updates };
19219
- import_fs14.default.writeFileSync(metaPath, JSON.stringify(meta, null, 2));
19390
+ import_fs15.default.writeFileSync(metaPath, JSON.stringify(meta, null, 2));
19220
19391
  } catch {
19221
19392
  }
19222
19393
  }
19223
19394
 
19224
19395
  // db/index.js
19225
19396
  var import_better_sqlite32 = __toESM(require("better-sqlite3"), 1);
19226
- var import_path14 = __toESM(require("path"), 1);
19397
+ var import_path15 = __toESM(require("path"), 1);
19227
19398
  var import_os4 = __toESM(require("os"), 1);
19228
- var import_fs15 = __toESM(require("fs"), 1);
19229
- var RUDI_HOME2 = import_path14.default.join(import_os4.default.homedir(), ".rudi");
19230
- var DB_PATH2 = import_path14.default.join(RUDI_HOME2, "rudi.db");
19399
+ var import_fs16 = __toESM(require("fs"), 1);
19400
+ var RUDI_HOME2 = import_path15.default.join(import_os4.default.homedir(), ".rudi");
19401
+ var DB_PATH2 = import_path15.default.join(RUDI_HOME2, "rudi.db");
19231
19402
  var db2 = null;
19232
19403
  function getDb2(options = {}) {
19233
19404
  if (!db2) {
19234
- if (!import_fs15.default.existsSync(RUDI_HOME2)) {
19235
- import_fs15.default.mkdirSync(RUDI_HOME2, { recursive: true });
19405
+ if (!import_fs16.default.existsSync(RUDI_HOME2)) {
19406
+ import_fs16.default.mkdirSync(RUDI_HOME2, { recursive: true });
19236
19407
  }
19237
19408
  db2 = new import_better_sqlite32.default(DB_PATH2, {
19238
19409
  readonly: options.readonly || false
@@ -19390,7 +19561,7 @@ function getBeforeCrashLogs() {
19390
19561
  }
19391
19562
 
19392
19563
  // src/commands/logs.js
19393
- var import_fs16 = __toESM(require("fs"), 1);
19564
+ var import_fs17 = __toESM(require("fs"), 1);
19394
19565
  function parseTimeAgo(str) {
19395
19566
  const match = str.match(/^(\d+)([smhd])$/);
19396
19567
  if (!match) return null;
@@ -19490,7 +19661,7 @@ function exportLogs(logs, filepath, format) {
19490
19661
  });
19491
19662
  content = JSON.stringify(formatted, null, 2);
19492
19663
  }
19493
- import_fs16.default.writeFileSync(filepath, content, "utf-8");
19664
+ import_fs17.default.writeFileSync(filepath, content, "utf-8");
19494
19665
  return filepath;
19495
19666
  }
19496
19667
  function printStats(stats) {
@@ -19616,8 +19787,8 @@ async function handleLogsCommand(args, flags) {
19616
19787
  }
19617
19788
 
19618
19789
  // src/commands/which.js
19619
- var fs17 = __toESM(require("fs/promises"), 1);
19620
- var path15 = __toESM(require("path"), 1);
19790
+ var fs18 = __toESM(require("fs/promises"), 1);
19791
+ var path16 = __toESM(require("path"), 1);
19621
19792
  var import_child_process4 = require("child_process");
19622
19793
  init_src();
19623
19794
  async function cmdWhich(args, flags) {
@@ -19686,7 +19857,7 @@ Installed stacks:`);
19686
19857
  if (runtimeInfo.entry) {
19687
19858
  console.log("");
19688
19859
  console.log("Run MCP server directly:");
19689
- const entryPath = path15.join(stackPath, runtimeInfo.entry);
19860
+ const entryPath = path16.join(stackPath, runtimeInfo.entry);
19690
19861
  if (runtimeInfo.runtime === "node") {
19691
19862
  console.log(` echo '{"jsonrpc":"2.0","method":"tools/list","id":1}' | node ${entryPath}`);
19692
19863
  } else if (runtimeInfo.runtime === "python") {
@@ -19705,27 +19876,27 @@ Installed stacks:`);
19705
19876
  async function detectRuntime(stackPath) {
19706
19877
  const runtimes = ["node", "python"];
19707
19878
  for (const runtime of runtimes) {
19708
- const runtimePath = path15.join(stackPath, runtime);
19879
+ const runtimePath = path16.join(stackPath, runtime);
19709
19880
  try {
19710
- await fs17.access(runtimePath);
19881
+ await fs18.access(runtimePath);
19711
19882
  if (runtime === "node") {
19712
- const distEntry = path15.join(runtimePath, "dist", "index.js");
19713
- const srcEntry = path15.join(runtimePath, "src", "index.ts");
19883
+ const distEntry = path16.join(runtimePath, "dist", "index.js");
19884
+ const srcEntry = path16.join(runtimePath, "src", "index.ts");
19714
19885
  try {
19715
- await fs17.access(distEntry);
19886
+ await fs18.access(distEntry);
19716
19887
  return { runtime: "node", entry: `${runtime}/dist/index.js` };
19717
19888
  } catch {
19718
19889
  try {
19719
- await fs17.access(srcEntry);
19890
+ await fs18.access(srcEntry);
19720
19891
  return { runtime: "node", entry: `${runtime}/src/index.ts` };
19721
19892
  } catch {
19722
19893
  return { runtime: "node", entry: null };
19723
19894
  }
19724
19895
  }
19725
19896
  } else if (runtime === "python") {
19726
- const entry = path15.join(runtimePath, "src", "index.py");
19897
+ const entry = path16.join(runtimePath, "src", "index.py");
19727
19898
  try {
19728
- await fs17.access(entry);
19899
+ await fs18.access(entry);
19729
19900
  return { runtime: "python", entry: `${runtime}/src/index.py` };
19730
19901
  } catch {
19731
19902
  return { runtime: "python", entry: null };
@@ -19741,21 +19912,21 @@ async function checkAuth(stackPath, runtime) {
19741
19912
  const authFiles = [];
19742
19913
  let configured = false;
19743
19914
  if (runtime === "node" || runtime === "python") {
19744
- const runtimePath = path15.join(stackPath, runtime);
19745
- const tokenPath = path15.join(runtimePath, "token.json");
19915
+ const runtimePath = path16.join(stackPath, runtime);
19916
+ const tokenPath = path16.join(runtimePath, "token.json");
19746
19917
  try {
19747
- await fs17.access(tokenPath);
19918
+ await fs18.access(tokenPath);
19748
19919
  authFiles.push(`${runtime}/token.json`);
19749
19920
  configured = true;
19750
19921
  } catch {
19751
- const accountsPath = path15.join(runtimePath, "accounts");
19922
+ const accountsPath = path16.join(runtimePath, "accounts");
19752
19923
  try {
19753
- const accounts = await fs17.readdir(accountsPath);
19924
+ const accounts = await fs18.readdir(accountsPath);
19754
19925
  for (const account of accounts) {
19755
19926
  if (account.startsWith(".")) continue;
19756
- const accountTokenPath = path15.join(accountsPath, account, "token.json");
19927
+ const accountTokenPath = path16.join(accountsPath, account, "token.json");
19757
19928
  try {
19758
- await fs17.access(accountTokenPath);
19929
+ await fs18.access(accountTokenPath);
19759
19930
  authFiles.push(`${runtime}/accounts/${account}/token.json`);
19760
19931
  configured = true;
19761
19932
  } catch {
@@ -19765,9 +19936,9 @@ async function checkAuth(stackPath, runtime) {
19765
19936
  }
19766
19937
  }
19767
19938
  }
19768
- const envPath = path15.join(stackPath, ".env");
19939
+ const envPath = path16.join(stackPath, ".env");
19769
19940
  try {
19770
- const envContent = await fs17.readFile(envPath, "utf-8");
19941
+ const envContent = await fs18.readFile(envPath, "utf-8");
19771
19942
  const hasValues = envContent.split("\n").some((line) => {
19772
19943
  const trimmed = line.trim();
19773
19944
  if (!trimmed || trimmed.startsWith("#")) return false;
@@ -19811,8 +19982,8 @@ function checkIfRunning(stackName) {
19811
19982
  }
19812
19983
 
19813
19984
  // src/commands/auth.js
19814
- var fs18 = __toESM(require("fs/promises"), 1);
19815
- var path16 = __toESM(require("path"), 1);
19985
+ var fs19 = __toESM(require("fs/promises"), 1);
19986
+ var path17 = __toESM(require("path"), 1);
19816
19987
  var import_child_process5 = require("child_process");
19817
19988
  init_src();
19818
19989
  var net = __toESM(require("net"), 1);
@@ -19844,26 +20015,26 @@ function isPortAvailable(port) {
19844
20015
  async function detectRuntime2(stackPath) {
19845
20016
  const runtimes = ["node", "python"];
19846
20017
  for (const runtime of runtimes) {
19847
- const runtimePath = path16.join(stackPath, runtime);
20018
+ const runtimePath = path17.join(stackPath, runtime);
19848
20019
  try {
19849
- await fs18.access(runtimePath);
20020
+ await fs19.access(runtimePath);
19850
20021
  if (runtime === "node") {
19851
- const authTs = path16.join(runtimePath, "src", "auth.ts");
19852
- const authJs = path16.join(runtimePath, "dist", "auth.js");
20022
+ const authTs = path17.join(runtimePath, "src", "auth.ts");
20023
+ const authJs = path17.join(runtimePath, "dist", "auth.js");
19853
20024
  try {
19854
- await fs18.access(authTs);
20025
+ await fs19.access(authTs);
19855
20026
  return { runtime: "node", authScript: authTs, useTsx: true };
19856
20027
  } catch {
19857
20028
  try {
19858
- await fs18.access(authJs);
20029
+ await fs19.access(authJs);
19859
20030
  return { runtime: "node", authScript: authJs, useTsx: false };
19860
20031
  } catch {
19861
20032
  }
19862
20033
  }
19863
20034
  } else if (runtime === "python") {
19864
- const authPy = path16.join(runtimePath, "src", "auth.py");
20035
+ const authPy = path17.join(runtimePath, "src", "auth.py");
19865
20036
  try {
19866
- await fs18.access(authPy);
20037
+ await fs19.access(authPy);
19867
20038
  return { runtime: "python", authScript: authPy, useTsx: false };
19868
20039
  } catch {
19869
20040
  }
@@ -19913,14 +20084,14 @@ Installed stacks:`);
19913
20084
  console.log(`Using port: ${port}`);
19914
20085
  console.log("");
19915
20086
  let cmd;
19916
- const cwd = path16.dirname(authInfo.authScript);
20087
+ const cwd = path17.dirname(authInfo.authScript);
19917
20088
  if (authInfo.runtime === "node") {
19918
- const distAuth = path16.join(cwd, "..", "dist", "auth.js");
20089
+ const distAuth = path17.join(cwd, "..", "dist", "auth.js");
19919
20090
  let useBuiltInPort = false;
19920
20091
  let tempAuthScript = null;
19921
20092
  try {
19922
- await fs18.access(distAuth);
19923
- const distContent = await fs18.readFile(distAuth, "utf-8");
20093
+ await fs19.access(distAuth);
20094
+ const distContent = await fs19.readFile(distAuth, "utf-8");
19924
20095
  if (distContent.includes("findAvailablePort")) {
19925
20096
  console.log("Using compiled authentication script...");
19926
20097
  cmd = `node ${distAuth}${accountEmail ? ` ${accountEmail}` : ""}`;
@@ -19929,11 +20100,11 @@ Installed stacks:`);
19929
20100
  } catch {
19930
20101
  }
19931
20102
  if (!useBuiltInPort) {
19932
- const authContent = await fs18.readFile(authInfo.authScript, "utf-8");
20103
+ const authContent = await fs19.readFile(authInfo.authScript, "utf-8");
19933
20104
  const tempExt = authInfo.useTsx ? ".ts" : ".mjs";
19934
- tempAuthScript = path16.join(cwd, "..", `auth-temp${tempExt}`);
20105
+ tempAuthScript = path17.join(cwd, "..", `auth-temp${tempExt}`);
19935
20106
  const modifiedContent = authContent.replace(/localhost:3456/g, `localhost:${port}`).replace(/server\.listen\(3456/g, `server.listen(${port}`);
19936
- await fs18.writeFile(tempAuthScript, modifiedContent);
20107
+ await fs19.writeFile(tempAuthScript, modifiedContent);
19937
20108
  if (authInfo.useTsx) {
19938
20109
  cmd = `npx tsx ${tempAuthScript}${accountEmail ? ` ${accountEmail}` : ""}`;
19939
20110
  } else {
@@ -19948,12 +20119,12 @@ Installed stacks:`);
19948
20119
  stdio: "inherit"
19949
20120
  });
19950
20121
  if (tempAuthScript) {
19951
- await fs18.unlink(tempAuthScript);
20122
+ await fs19.unlink(tempAuthScript);
19952
20123
  }
19953
20124
  } catch (error) {
19954
20125
  if (tempAuthScript) {
19955
20126
  try {
19956
- await fs18.unlink(tempAuthScript);
20127
+ await fs19.unlink(tempAuthScript);
19957
20128
  } catch {
19958
20129
  }
19959
20130
  }
@@ -20051,6 +20222,28 @@ async function main() {
20051
20222
  case "login":
20052
20223
  await cmdAuth(args, flags);
20053
20224
  break;
20225
+ case "home":
20226
+ case "status":
20227
+ await cmdHome(args, flags);
20228
+ break;
20229
+ // Shortcuts for listing specific package types
20230
+ case "stacks":
20231
+ await cmdList(["stacks"], flags);
20232
+ break;
20233
+ case "prompts":
20234
+ await cmdList(["prompts"], flags);
20235
+ break;
20236
+ case "runtimes":
20237
+ await cmdList(["runtimes"], flags);
20238
+ break;
20239
+ case "binaries":
20240
+ case "bins":
20241
+ case "tools":
20242
+ await cmdList(["binaries"], flags);
20243
+ break;
20244
+ case "agents":
20245
+ await cmdList(["agents"], flags);
20246
+ break;
20054
20247
  case "help":
20055
20248
  printHelp(args[0]);
20056
20249
  break;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@learnrudi/cli",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "description": "RUDI CLI - Install and manage MCP stacks, runtimes, and AI agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",