@learnrudi/cli 1.1.0 → 1.2.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 +282 -44
  2. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -14961,10 +14961,26 @@ COMMANDS
14961
14961
  stats Show usage statistics
14962
14962
  search <query> Search conversation history
14963
14963
  init Initialize or migrate database
14964
+ path Show database file path
14965
+ reset Delete all data (requires --force)
14966
+ vacuum Compact database and reclaim space
14967
+ backup [file] Create database backup
14968
+ prune [days] Delete sessions older than N days (default: 90)
14969
+ tables Show table row counts
14970
+
14971
+ OPTIONS
14972
+ --force Required for destructive operations
14973
+ --dry-run Preview without making changes
14974
+ --json Output as JSON
14964
14975
 
14965
14976
  EXAMPLES
14966
14977
  rudi db stats
14967
14978
  rudi db search "authentication bug"
14979
+ rudi db reset --force
14980
+ rudi db vacuum
14981
+ rudi db backup ~/backups/rudi.db
14982
+ rudi db prune 30 --dry-run
14983
+ rudi db tables
14968
14984
  `,
14969
14985
  import: `
14970
14986
  rudi import - Import sessions from AI providers
@@ -17238,6 +17254,10 @@ function promptSecret(prompt) {
17238
17254
  });
17239
17255
  }
17240
17256
 
17257
+ // src/commands/db.js
17258
+ var import_fs10 = require("fs");
17259
+ var import_path10 = require("path");
17260
+
17241
17261
  // ../packages/db/src/index.js
17242
17262
  var import_better_sqlite3 = __toESM(require("better-sqlite3"), 1);
17243
17263
  var import_path9 = __toESM(require("path"), 1);
@@ -18036,6 +18056,21 @@ async function cmdDb(args, flags) {
18036
18056
  case "path":
18037
18057
  console.log(getDbPath());
18038
18058
  break;
18059
+ case "reset":
18060
+ await dbReset(flags);
18061
+ break;
18062
+ case "vacuum":
18063
+ dbVacuum(flags);
18064
+ break;
18065
+ case "backup":
18066
+ dbBackup(args.slice(1), flags);
18067
+ break;
18068
+ case "prune":
18069
+ dbPrune(args.slice(1), flags);
18070
+ break;
18071
+ case "tables":
18072
+ dbTables(flags);
18073
+ break;
18039
18074
  default:
18040
18075
  console.log(`
18041
18076
  rudi db - Database operations
@@ -18045,11 +18080,24 @@ COMMANDS
18045
18080
  search <query> Search conversation history
18046
18081
  init Initialize or migrate database
18047
18082
  path Show database file path
18083
+ reset Delete all data (requires --force)
18084
+ vacuum Compact database and reclaim space
18085
+ backup [file] Create database backup
18086
+ prune [days] Delete sessions older than N days (default: 90)
18087
+ tables Show table row counts
18088
+
18089
+ OPTIONS
18090
+ --force Required for destructive operations
18091
+ --dry-run Preview without making changes
18048
18092
 
18049
18093
  EXAMPLES
18050
18094
  rudi db stats
18051
18095
  rudi db search "authentication bug"
18052
18096
  rudi db init
18097
+ rudi db reset --force
18098
+ rudi db vacuum
18099
+ rudi db backup ~/backups/rudi-backup.db
18100
+ rudi db prune 30 --dry-run
18053
18101
  `);
18054
18102
  }
18055
18103
  }
@@ -18176,26 +18224,216 @@ function truncate(str, len) {
18176
18224
  function stripHighlight(str) {
18177
18225
  return str.replace(/>>>/g, "").replace(/<<</g, "");
18178
18226
  }
18227
+ async function dbReset(flags) {
18228
+ if (!isDatabaseInitialized()) {
18229
+ console.log("Database not initialized.");
18230
+ return;
18231
+ }
18232
+ if (!flags.force) {
18233
+ console.error("This will delete ALL data from the database.");
18234
+ console.error("Use --force to confirm.");
18235
+ process.exit(1);
18236
+ }
18237
+ const db3 = getDb();
18238
+ const dbPath = getDbPath();
18239
+ const tables = ["sessions", "turns", "tool_calls", "projects"];
18240
+ const counts = {};
18241
+ for (const table of tables) {
18242
+ try {
18243
+ const row = db3.prepare(`SELECT COUNT(*) as count FROM ${table}`).get();
18244
+ counts[table] = row.count;
18245
+ } catch (e) {
18246
+ counts[table] = 0;
18247
+ }
18248
+ }
18249
+ console.log("Deleting all data...");
18250
+ console.log("\u2500".repeat(40));
18251
+ const deleteOrder = ["tool_calls", "turns", "sessions", "projects"];
18252
+ for (const table of deleteOrder) {
18253
+ try {
18254
+ db3.prepare(`DELETE FROM ${table}`).run();
18255
+ console.log(` ${table}: ${counts[table]} rows deleted`);
18256
+ } catch (e) {
18257
+ }
18258
+ }
18259
+ try {
18260
+ db3.prepare("DELETE FROM turns_fts").run();
18261
+ console.log(" turns_fts: cleared");
18262
+ } catch (e) {
18263
+ }
18264
+ console.log("\u2500".repeat(40));
18265
+ console.log("Database reset complete.");
18266
+ console.log(`Path: ${dbPath}`);
18267
+ }
18268
+ function dbVacuum(flags) {
18269
+ if (!isDatabaseInitialized()) {
18270
+ console.log("Database not initialized.");
18271
+ return;
18272
+ }
18273
+ const dbPath = getDbPath();
18274
+ const sizeBefore = getDbSize();
18275
+ console.log("Compacting database...");
18276
+ console.log(` Before: ${formatBytes(sizeBefore)}`);
18277
+ const db3 = getDb();
18278
+ db3.exec("VACUUM");
18279
+ const sizeAfter = getDbSize();
18280
+ const saved = sizeBefore - sizeAfter;
18281
+ console.log(` After: ${formatBytes(sizeAfter)}`);
18282
+ if (saved > 0) {
18283
+ console.log(` Saved: ${formatBytes(saved)} (${(saved / sizeBefore * 100).toFixed(1)}%)`);
18284
+ } else {
18285
+ console.log(" No space reclaimed.");
18286
+ }
18287
+ }
18288
+ function dbBackup(args, flags) {
18289
+ if (!isDatabaseInitialized()) {
18290
+ console.log("Database not initialized.");
18291
+ return;
18292
+ }
18293
+ const dbPath = getDbPath();
18294
+ let backupPath = args[0];
18295
+ if (!backupPath) {
18296
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
18297
+ backupPath = (0, import_path10.join)((0, import_path10.dirname)(dbPath), `rudi-backup-${timestamp}.db`);
18298
+ }
18299
+ if (backupPath.startsWith("~")) {
18300
+ backupPath = (0, import_path10.join)(process.env.HOME || "", backupPath.slice(1));
18301
+ }
18302
+ if ((0, import_fs10.existsSync)(backupPath) && !flags.force) {
18303
+ console.error(`Backup file already exists: ${backupPath}`);
18304
+ console.error("Use --force to overwrite.");
18305
+ process.exit(1);
18306
+ }
18307
+ console.log("Creating backup...");
18308
+ console.log(` Source: ${dbPath}`);
18309
+ console.log(` Dest: ${backupPath}`);
18310
+ try {
18311
+ const db3 = getDb();
18312
+ db3.exec("VACUUM INTO ?", [backupPath]);
18313
+ } catch (e) {
18314
+ (0, import_fs10.copyFileSync)(dbPath, backupPath);
18315
+ }
18316
+ const size = getDbSize();
18317
+ console.log(` Size: ${formatBytes(size)}`);
18318
+ console.log("Backup complete.");
18319
+ }
18320
+ function dbPrune(args, flags) {
18321
+ if (!isDatabaseInitialized()) {
18322
+ console.log("Database not initialized.");
18323
+ return;
18324
+ }
18325
+ const days = parseInt(args[0]) || 90;
18326
+ const dryRun = flags["dry-run"] || flags.dryRun;
18327
+ const cutoffDate = new Date(Date.now() - days * 24 * 60 * 60 * 1e3).toISOString();
18328
+ const db3 = getDb();
18329
+ const toDelete = db3.prepare(`
18330
+ SELECT COUNT(*) as count FROM sessions
18331
+ WHERE last_active_at < ? OR (last_active_at IS NULL AND created_at < ?)
18332
+ `).get(cutoffDate, cutoffDate);
18333
+ const total = db3.prepare("SELECT COUNT(*) as count FROM sessions").get();
18334
+ console.log(`Sessions older than ${days} days: ${toDelete.count}`);
18335
+ console.log(`Total sessions: ${total.count}`);
18336
+ console.log(`Cutoff date: ${cutoffDate.slice(0, 10)}`);
18337
+ if (toDelete.count === 0) {
18338
+ console.log("\nNo sessions to prune.");
18339
+ return;
18340
+ }
18341
+ if (dryRun) {
18342
+ console.log("\n(Dry run - no changes made)");
18343
+ return;
18344
+ }
18345
+ if (!flags.force) {
18346
+ console.error(`
18347
+ This will delete ${toDelete.count} sessions and their turns.`);
18348
+ console.error("Use --force to confirm, or --dry-run to preview.");
18349
+ process.exit(1);
18350
+ }
18351
+ console.log("\nDeleting old sessions...");
18352
+ const sessionIds = db3.prepare(`
18353
+ SELECT id FROM sessions
18354
+ WHERE last_active_at < ? OR (last_active_at IS NULL AND created_at < ?)
18355
+ `).all(cutoffDate, cutoffDate).map((r) => r.id);
18356
+ let turnsDeleted = 0;
18357
+ let toolCallsDeleted = 0;
18358
+ for (const sessionId of sessionIds) {
18359
+ const turnIds = db3.prepare("SELECT id FROM turns WHERE session_id = ?").all(sessionId).map((r) => r.id);
18360
+ for (const turnId of turnIds) {
18361
+ const result = db3.prepare("DELETE FROM tool_calls WHERE turn_id = ?").run(turnId);
18362
+ toolCallsDeleted += result.changes;
18363
+ }
18364
+ const turnResult = db3.prepare("DELETE FROM turns WHERE session_id = ?").run(sessionId);
18365
+ turnsDeleted += turnResult.changes;
18366
+ }
18367
+ const sessionResult = db3.prepare(`
18368
+ DELETE FROM sessions
18369
+ WHERE last_active_at < ? OR (last_active_at IS NULL AND created_at < ?)
18370
+ `).run(cutoffDate, cutoffDate);
18371
+ console.log(` Sessions deleted: ${sessionResult.changes}`);
18372
+ console.log(` Turns deleted: ${turnsDeleted}`);
18373
+ console.log(` Tool calls deleted: ${toolCallsDeleted}`);
18374
+ console.log('\nPrune complete. Run "rudi db vacuum" to reclaim disk space.');
18375
+ }
18376
+ function dbTables(flags) {
18377
+ if (!isDatabaseInitialized()) {
18378
+ console.log("Database not initialized.");
18379
+ return;
18380
+ }
18381
+ const db3 = getDb();
18382
+ const tables = db3.prepare(`
18383
+ SELECT name FROM sqlite_master
18384
+ WHERE type = 'table' AND name NOT LIKE 'sqlite_%'
18385
+ ORDER BY name
18386
+ `).all();
18387
+ if (flags.json) {
18388
+ const result = {};
18389
+ for (const { name } of tables) {
18390
+ try {
18391
+ const row = db3.prepare(`SELECT COUNT(*) as count FROM "${name}"`).get();
18392
+ result[name] = row.count;
18393
+ } catch (e) {
18394
+ result[name] = -1;
18395
+ }
18396
+ }
18397
+ console.log(JSON.stringify(result, null, 2));
18398
+ return;
18399
+ }
18400
+ console.log("\nDatabase Tables");
18401
+ console.log("\u2550".repeat(40));
18402
+ let totalRows = 0;
18403
+ for (const { name } of tables) {
18404
+ try {
18405
+ const row = db3.prepare(`SELECT COUNT(*) as count FROM "${name}"`).get();
18406
+ console.log(` ${name.padEnd(25)} ${row.count.toLocaleString().padStart(10)}`);
18407
+ totalRows += row.count;
18408
+ } catch (e) {
18409
+ console.log(` ${name.padEnd(25)} ${"error".padStart(10)}`);
18410
+ }
18411
+ }
18412
+ console.log("\u2500".repeat(40));
18413
+ console.log(` ${"Total".padEnd(25)} ${totalRows.toLocaleString().padStart(10)}`);
18414
+ console.log(`
18415
+ Size: ${formatBytes(getDbSize())}`);
18416
+ }
18179
18417
 
18180
18418
  // src/commands/import.js
18181
- var import_fs10 = require("fs");
18182
- var import_path10 = require("path");
18419
+ var import_fs11 = require("fs");
18420
+ var import_path11 = require("path");
18183
18421
  var import_os3 = require("os");
18184
18422
  var import_crypto2 = require("crypto");
18185
18423
  var PROVIDERS = {
18186
18424
  claude: {
18187
18425
  name: "Claude Code",
18188
- baseDir: (0, import_path10.join)((0, import_os3.homedir)(), ".claude", "projects"),
18426
+ baseDir: (0, import_path11.join)((0, import_os3.homedir)(), ".claude", "projects"),
18189
18427
  pattern: /\.jsonl$/
18190
18428
  },
18191
18429
  codex: {
18192
18430
  name: "Codex",
18193
- baseDir: (0, import_path10.join)((0, import_os3.homedir)(), ".codex", "sessions"),
18431
+ baseDir: (0, import_path11.join)((0, import_os3.homedir)(), ".codex", "sessions"),
18194
18432
  pattern: /\.jsonl$/
18195
18433
  },
18196
18434
  gemini: {
18197
18435
  name: "Gemini",
18198
- baseDir: (0, import_path10.join)((0, import_os3.homedir)(), ".gemini", "sessions"),
18436
+ baseDir: (0, import_path11.join)((0, import_os3.homedir)(), ".gemini", "sessions"),
18199
18437
  pattern: /\.jsonl$/
18200
18438
  }
18201
18439
  };
@@ -18262,7 +18500,7 @@ async function importSessions(args, flags) {
18262
18500
  console.log(`
18263
18501
  \u25B6 ${provider.name}`);
18264
18502
  console.log(` Source: ${provider.baseDir}`);
18265
- if (!(0, import_fs10.existsSync)(provider.baseDir)) {
18503
+ if (!(0, import_fs11.existsSync)(provider.baseDir)) {
18266
18504
  console.log(` \u26A0 Directory not found, skipping`);
18267
18505
  continue;
18268
18506
  }
@@ -18305,14 +18543,14 @@ async function importSessions(args, flags) {
18305
18543
  const now = Date.now();
18306
18544
  const maxAgeMs = maxAgeDays ? maxAgeDays * 24 * 60 * 60 * 1e3 : null;
18307
18545
  for (const filepath of files) {
18308
- const sessionId = (0, import_path10.basename)(filepath, ".jsonl");
18546
+ const sessionId = (0, import_path11.basename)(filepath, ".jsonl");
18309
18547
  if (existingIds.has(sessionId)) {
18310
18548
  skipped.existing++;
18311
18549
  continue;
18312
18550
  }
18313
18551
  let stat;
18314
18552
  try {
18315
- stat = (0, import_fs10.statSync)(filepath);
18553
+ stat = (0, import_fs11.statSync)(filepath);
18316
18554
  } catch (e) {
18317
18555
  skipped.error++;
18318
18556
  continue;
@@ -18410,7 +18648,7 @@ function showImportStatus(flags) {
18410
18648
  }
18411
18649
  console.log("\nProvider directories:");
18412
18650
  for (const [key, provider] of Object.entries(PROVIDERS)) {
18413
- const exists = (0, import_fs10.existsSync)(provider.baseDir);
18651
+ const exists = (0, import_fs11.existsSync)(provider.baseDir);
18414
18652
  let count = 0;
18415
18653
  if (exists) {
18416
18654
  const files = findSessionFiles(provider.baseDir, provider.pattern);
@@ -18424,10 +18662,10 @@ function showImportStatus(flags) {
18424
18662
  console.log("To import: rudi import sessions [provider]");
18425
18663
  }
18426
18664
  function findSessionFiles(dir, pattern, files = []) {
18427
- if (!(0, import_fs10.existsSync)(dir)) return files;
18665
+ if (!(0, import_fs11.existsSync)(dir)) return files;
18428
18666
  try {
18429
- for (const entry of (0, import_fs10.readdirSync)(dir, { withFileTypes: true })) {
18430
- const fullPath = (0, import_path10.join)(dir, entry.name);
18667
+ for (const entry of (0, import_fs11.readdirSync)(dir, { withFileTypes: true })) {
18668
+ const fullPath = (0, import_path11.join)(dir, entry.name);
18431
18669
  if (entry.isDirectory()) {
18432
18670
  findSessionFiles(fullPath, pattern, files);
18433
18671
  } else if (pattern.test(entry.name)) {
@@ -18440,11 +18678,11 @@ function findSessionFiles(dir, pattern, files = []) {
18440
18678
  }
18441
18679
  function parseSessionFile(filepath, provider) {
18442
18680
  try {
18443
- const stat = (0, import_fs10.statSync)(filepath);
18444
- const content = (0, import_fs10.readFileSync)(filepath, "utf-8");
18681
+ const stat = (0, import_fs11.statSync)(filepath);
18682
+ const content = (0, import_fs11.readFileSync)(filepath, "utf-8");
18445
18683
  const lines = content.split("\n").filter((l) => l.trim());
18446
18684
  if (lines.length === 0) return null;
18447
- const sessionId = (0, import_path10.basename)(filepath, ".jsonl");
18685
+ const sessionId = (0, import_path11.basename)(filepath, ".jsonl");
18448
18686
  const isAgent = sessionId.startsWith("agent-");
18449
18687
  let title = null;
18450
18688
  let cwd = null;
@@ -18476,7 +18714,7 @@ function parseSessionFile(filepath, provider) {
18476
18714
  title = isAgent ? "Agent Session" : "Imported Session";
18477
18715
  }
18478
18716
  if (!cwd) {
18479
- const parentDir = (0, import_path10.basename)((0, import_path10.dirname)(filepath));
18717
+ const parentDir = (0, import_path11.basename)((0, import_path11.dirname)(filepath));
18480
18718
  if (parentDir.startsWith("-")) {
18481
18719
  cwd = parentDir.replace(/-/g, "/").replace(/^\//, "/");
18482
18720
  } else {
@@ -18500,7 +18738,7 @@ function parseSessionFile(filepath, provider) {
18500
18738
  }
18501
18739
 
18502
18740
  // src/commands/doctor.js
18503
- var import_fs11 = __toESM(require("fs"), 1);
18741
+ var import_fs12 = __toESM(require("fs"), 1);
18504
18742
  async function cmdDoctor(args, flags) {
18505
18743
  console.log("RUDI Health Check");
18506
18744
  console.log("\u2550".repeat(50));
@@ -18518,12 +18756,12 @@ async function cmdDoctor(args, flags) {
18518
18756
  { path: PATHS.cache, name: "Cache" }
18519
18757
  ];
18520
18758
  for (const dir of dirs) {
18521
- const exists = import_fs11.default.existsSync(dir.path);
18759
+ const exists = import_fs12.default.existsSync(dir.path);
18522
18760
  const status = exists ? "\u2713" : "\u2717";
18523
18761
  console.log(` ${status} ${dir.name}: ${dir.path}`);
18524
18762
  if (!exists) {
18525
18763
  issues.push(`Missing directory: ${dir.name}`);
18526
- fixes.push(() => import_fs11.default.mkdirSync(dir.path, { recursive: true }));
18764
+ fixes.push(() => import_fs12.default.mkdirSync(dir.path, { recursive: true }));
18527
18765
  }
18528
18766
  }
18529
18767
  console.log("\n\u{1F4BE} Database");
@@ -18593,8 +18831,8 @@ async function cmdDoctor(args, flags) {
18593
18831
  }
18594
18832
 
18595
18833
  // src/commands/update.js
18596
- var import_fs12 = __toESM(require("fs"), 1);
18597
- var import_path11 = __toESM(require("path"), 1);
18834
+ var import_fs13 = __toESM(require("fs"), 1);
18835
+ var import_path12 = __toESM(require("path"), 1);
18598
18836
  var import_child_process2 = require("child_process");
18599
18837
  init_src();
18600
18838
  init_src2();
@@ -18620,7 +18858,7 @@ async function cmdUpdate(args, flags) {
18620
18858
  async function updatePackage(pkgId, flags) {
18621
18859
  const [kind, name] = parsePackageId(pkgId);
18622
18860
  const installPath = getPackagePath(pkgId);
18623
- if (!import_fs12.default.existsSync(installPath)) {
18861
+ if (!import_fs13.default.existsSync(installPath)) {
18624
18862
  return { success: false, error: "Package not installed" };
18625
18863
  }
18626
18864
  const pkg = await getPackage(pkgId);
@@ -18643,7 +18881,7 @@ async function updatePackage(pkgId, flags) {
18643
18881
  }
18644
18882
  if (pkg.pipPackage) {
18645
18883
  try {
18646
- const venvPip = import_path11.default.join(installPath, "venv", "bin", "pip");
18884
+ const venvPip = import_path12.default.join(installPath, "venv", "bin", "pip");
18647
18885
  (0, import_child_process2.execSync)(`"${venvPip}" install --upgrade ${pkg.pipPackage}`, {
18648
18886
  stdio: flags.verbose ? "inherit" : "pipe"
18649
18887
  });
@@ -18660,7 +18898,7 @@ async function updatePackage(pkgId, flags) {
18660
18898
  if (kind === "runtime" && !pkg.npmPackage && !pkg.pipPackage) {
18661
18899
  try {
18662
18900
  const { downloadRuntime: downloadRuntime2 } = await Promise.resolve().then(() => (init_src2(), src_exports));
18663
- import_fs12.default.rmSync(installPath, { recursive: true, force: true });
18901
+ import_fs13.default.rmSync(installPath, { recursive: true, force: true });
18664
18902
  await downloadRuntime2(name, pkg.version || "latest", installPath, {
18665
18903
  onProgress: (p) => {
18666
18904
  if (flags.verbose) console.log(` ${p.phase}...`);
@@ -18680,8 +18918,8 @@ async function updateAll(flags) {
18680
18918
  let failed = 0;
18681
18919
  for (const kind of kinds) {
18682
18920
  const dir = kind === "runtime" ? PATHS.runtimes : kind === "stack" ? PATHS.stacks : PATHS.prompts;
18683
- if (!import_fs12.default.existsSync(dir)) continue;
18684
- const entries = import_fs12.default.readdirSync(dir, { withFileTypes: true });
18921
+ if (!import_fs13.default.existsSync(dir)) continue;
18922
+ const entries = import_fs13.default.readdirSync(dir, { withFileTypes: true });
18685
18923
  for (const entry of entries) {
18686
18924
  if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
18687
18925
  const pkgId = `${kind}:${entry.name}`;
@@ -18700,14 +18938,14 @@ Updated ${updated} package(s)${failed > 0 ? `, ${failed} failed` : ""}`);
18700
18938
  }
18701
18939
  function getInstalledVersion(installPath, npmPackage) {
18702
18940
  try {
18703
- const pkgJsonPath = import_path11.default.join(installPath, "node_modules", npmPackage.replace("@", "").split("/")[0], "package.json");
18704
- if (import_fs12.default.existsSync(pkgJsonPath)) {
18705
- const pkgJson = JSON.parse(import_fs12.default.readFileSync(pkgJsonPath, "utf-8"));
18941
+ const pkgJsonPath = import_path12.default.join(installPath, "node_modules", npmPackage.replace("@", "").split("/")[0], "package.json");
18942
+ if (import_fs13.default.existsSync(pkgJsonPath)) {
18943
+ const pkgJson = JSON.parse(import_fs13.default.readFileSync(pkgJsonPath, "utf-8"));
18706
18944
  return pkgJson.version;
18707
18945
  }
18708
- const rootPkgPath = import_path11.default.join(installPath, "package.json");
18709
- if (import_fs12.default.existsSync(rootPkgPath)) {
18710
- const rootPkg = JSON.parse(import_fs12.default.readFileSync(rootPkgPath, "utf-8"));
18946
+ const rootPkgPath = import_path12.default.join(installPath, "package.json");
18947
+ if (import_fs13.default.existsSync(rootPkgPath)) {
18948
+ const rootPkg = JSON.parse(import_fs13.default.readFileSync(rootPkgPath, "utf-8"));
18711
18949
  const dep = rootPkg.dependencies?.[npmPackage];
18712
18950
  if (dep) return dep.replace(/[\^~]/, "");
18713
18951
  }
@@ -18716,30 +18954,30 @@ function getInstalledVersion(installPath, npmPackage) {
18716
18954
  return null;
18717
18955
  }
18718
18956
  function updateRuntimeMetadata(installPath, updates) {
18719
- const metaPath = import_path11.default.join(installPath, "runtime.json");
18957
+ const metaPath = import_path12.default.join(installPath, "runtime.json");
18720
18958
  try {
18721
18959
  let meta = {};
18722
- if (import_fs12.default.existsSync(metaPath)) {
18723
- meta = JSON.parse(import_fs12.default.readFileSync(metaPath, "utf-8"));
18960
+ if (import_fs13.default.existsSync(metaPath)) {
18961
+ meta = JSON.parse(import_fs13.default.readFileSync(metaPath, "utf-8"));
18724
18962
  }
18725
18963
  meta = { ...meta, ...updates };
18726
- import_fs12.default.writeFileSync(metaPath, JSON.stringify(meta, null, 2));
18964
+ import_fs13.default.writeFileSync(metaPath, JSON.stringify(meta, null, 2));
18727
18965
  } catch {
18728
18966
  }
18729
18967
  }
18730
18968
 
18731
18969
  // db/index.js
18732
18970
  var import_better_sqlite32 = __toESM(require("better-sqlite3"), 1);
18733
- var import_path12 = __toESM(require("path"), 1);
18971
+ var import_path13 = __toESM(require("path"), 1);
18734
18972
  var import_os4 = __toESM(require("os"), 1);
18735
- var import_fs13 = __toESM(require("fs"), 1);
18736
- var PROMPT_STACK_HOME = import_path12.default.join(import_os4.default.homedir(), ".prompt-stack");
18737
- var DB_PATH2 = import_path12.default.join(PROMPT_STACK_HOME, "prompt-stack.db");
18973
+ var import_fs14 = __toESM(require("fs"), 1);
18974
+ var PROMPT_STACK_HOME = import_path13.default.join(import_os4.default.homedir(), ".prompt-stack");
18975
+ var DB_PATH2 = import_path13.default.join(PROMPT_STACK_HOME, "prompt-stack.db");
18738
18976
  var db2 = null;
18739
18977
  function getDb2(options = {}) {
18740
18978
  if (!db2) {
18741
- if (!import_fs13.default.existsSync(PROMPT_STACK_HOME)) {
18742
- import_fs13.default.mkdirSync(PROMPT_STACK_HOME, { recursive: true });
18979
+ if (!import_fs14.default.existsSync(PROMPT_STACK_HOME)) {
18980
+ import_fs14.default.mkdirSync(PROMPT_STACK_HOME, { recursive: true });
18743
18981
  }
18744
18982
  db2 = new import_better_sqlite32.default(DB_PATH2, {
18745
18983
  readonly: options.readonly || false
@@ -18897,7 +19135,7 @@ function getBeforeCrashLogs() {
18897
19135
  }
18898
19136
 
18899
19137
  // src/commands/logs.js
18900
- var import_fs14 = __toESM(require("fs"), 1);
19138
+ var import_fs15 = __toESM(require("fs"), 1);
18901
19139
  function parseTimeAgo(str) {
18902
19140
  const match = str.match(/^(\d+)([smhd])$/);
18903
19141
  if (!match) return null;
@@ -18997,7 +19235,7 @@ function exportLogs(logs, filepath, format) {
18997
19235
  });
18998
19236
  content = JSON.stringify(formatted, null, 2);
18999
19237
  }
19000
- import_fs14.default.writeFileSync(filepath, content, "utf-8");
19238
+ import_fs15.default.writeFileSync(filepath, content, "utf-8");
19001
19239
  return filepath;
19002
19240
  }
19003
19241
  function printStats(stats) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@learnrudi/cli",
3
- "version": "1.1.0",
3
+ "version": "1.2.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",