@learnrudi/cli 1.0.0 → 1.1.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 +387 -39
  2. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -223,7 +223,7 @@ async function fetchIndex(options = {}) {
223
223
  const response = await fetch(url, {
224
224
  headers: {
225
225
  "Accept": "application/json",
226
- "User-Agent": "pstack-cli/2.0"
226
+ "User-Agent": "rudi-cli/2.0"
227
227
  }
228
228
  });
229
229
  if (!response.ok) {
@@ -401,7 +401,7 @@ async function downloadRuntime(runtime, version, destPath, options = {}) {
401
401
  try {
402
402
  const response = await fetch(url, {
403
403
  headers: {
404
- "User-Agent": "pstack-cli/2.0",
404
+ "User-Agent": "rudi-cli/2.0",
405
405
  "Accept": "application/octet-stream"
406
406
  }
407
407
  });
@@ -470,7 +470,7 @@ async function downloadTool(toolName, destPath, options = {}) {
470
470
  try {
471
471
  const response = await fetch(url, {
472
472
  headers: {
473
- "User-Agent": "pstack-cli/2.0",
473
+ "User-Agent": "rudi-cli/2.0",
474
474
  "Accept": "application/octet-stream"
475
475
  }
476
476
  });
@@ -522,7 +522,7 @@ async function downloadTool(toolName, destPath, options = {}) {
522
522
  try {
523
523
  const response = await fetch(upstreamUrl, {
524
524
  headers: {
525
- "User-Agent": "pstack-cli/2.0",
525
+ "User-Agent": "rudi-cli/2.0",
526
526
  "Accept": "application/octet-stream"
527
527
  }
528
528
  });
@@ -620,10 +620,10 @@ async function loadToolManifest(toolName) {
620
620
  }
621
621
  }
622
622
  try {
623
- const url = `https://raw.githubusercontent.com/prompt/registry/main/catalog/binaries/${toolName}.json`;
623
+ const url = `https://raw.githubusercontent.com/learn-rudi/registry/main/catalog/binaries/${toolName}.json`;
624
624
  const response = await fetch(url, {
625
625
  headers: {
626
- "User-Agent": "pstack-cli/2.0",
626
+ "User-Agent": "rudi-cli/2.0",
627
627
  "Accept": "application/json"
628
628
  }
629
629
  });
@@ -683,13 +683,13 @@ var init_src2 = __esm({
683
683
  import_path2 = __toESM(require("path"), 1);
684
684
  import_crypto = __toESM(require("crypto"), 1);
685
685
  init_src();
686
- DEFAULT_REGISTRY_URL = "https://raw.githubusercontent.com/prompt/registry/main/index.json";
687
- RUNTIMES_DOWNLOAD_BASE = "https://github.com/prompt/registry/releases/download";
686
+ DEFAULT_REGISTRY_URL = "https://raw.githubusercontent.com/learn-rudi/registry/main/index.json";
687
+ RUNTIMES_DOWNLOAD_BASE = "https://github.com/learn-rudi/registry/releases/download";
688
688
  CACHE_TTL = 24 * 60 * 60 * 1e3;
689
689
  LOCAL_REGISTRY_PATHS = process.env.USE_LOCAL_REGISTRY === "true" ? [
690
690
  import_path2.default.join(process.cwd(), "registry", "index.json"),
691
691
  import_path2.default.join(process.cwd(), "..", "registry", "index.json"),
692
- "/Users/hoff/dev/prompt/registry/index.json"
692
+ "/Users/hoff/dev/RUDI/registry/index.json"
693
693
  ] : [];
694
694
  PACKAGE_KINDS2 = ["stack", "prompt", "runtime", "binary", "agent"];
695
695
  KIND_PLURALS = {
@@ -14830,6 +14830,9 @@ COMMANDS
14830
14830
  db stats Show database statistics
14831
14831
  db search <query> Search conversation history
14832
14832
 
14833
+ import sessions Import sessions from AI providers (claude, codex, gemini)
14834
+ import status Show import status for all providers
14835
+
14833
14836
  logs [options] Query agent visibility logs
14834
14837
 
14835
14838
  doctor Check system health and configuration
@@ -14962,6 +14965,27 @@ COMMANDS
14962
14965
  EXAMPLES
14963
14966
  rudi db stats
14964
14967
  rudi db search "authentication bug"
14968
+ `,
14969
+ import: `
14970
+ rudi import - Import sessions from AI providers
14971
+
14972
+ USAGE
14973
+ rudi import <command> [options]
14974
+
14975
+ COMMANDS
14976
+ sessions [provider] Import sessions from provider (claude, codex, gemini, or all)
14977
+ status Show import status for all providers
14978
+
14979
+ OPTIONS
14980
+ --dry-run Show what would be imported without making changes
14981
+ --max-age=DAYS Only import sessions newer than N days
14982
+ --verbose Show detailed progress
14983
+
14984
+ EXAMPLES
14985
+ rudi import sessions Import from all providers
14986
+ rudi import sessions claude Import only Claude sessions
14987
+ rudi import sessions --dry-run Preview without importing
14988
+ rudi import status Check what's available to import
14965
14989
  `,
14966
14990
  doctor: `
14967
14991
  rudi doctor - System health check
@@ -17950,7 +17974,6 @@ function getToolsUsage(db3) {
17950
17974
  }
17951
17975
 
17952
17976
  // ../packages/db/src/index.js
17953
- var PROMPT_STACK_HOME2 = PATHS.home;
17954
17977
  var DB_PATH = PATHS.dbFile;
17955
17978
  var db = null;
17956
17979
  function getDb(options = {}) {
@@ -18154,8 +18177,330 @@ function stripHighlight(str) {
18154
18177
  return str.replace(/>>>/g, "").replace(/<<</g, "");
18155
18178
  }
18156
18179
 
18180
+ // src/commands/import.js
18181
+ var import_fs10 = require("fs");
18182
+ var import_path10 = require("path");
18183
+ var import_os3 = require("os");
18184
+ var import_crypto2 = require("crypto");
18185
+ var PROVIDERS = {
18186
+ claude: {
18187
+ name: "Claude Code",
18188
+ baseDir: (0, import_path10.join)((0, import_os3.homedir)(), ".claude", "projects"),
18189
+ pattern: /\.jsonl$/
18190
+ },
18191
+ codex: {
18192
+ name: "Codex",
18193
+ baseDir: (0, import_path10.join)((0, import_os3.homedir)(), ".codex", "sessions"),
18194
+ pattern: /\.jsonl$/
18195
+ },
18196
+ gemini: {
18197
+ name: "Gemini",
18198
+ baseDir: (0, import_path10.join)((0, import_os3.homedir)(), ".gemini", "sessions"),
18199
+ pattern: /\.jsonl$/
18200
+ }
18201
+ };
18202
+ async function cmdImport(args, flags) {
18203
+ const subcommand = args[0];
18204
+ switch (subcommand) {
18205
+ case "sessions":
18206
+ await importSessions(args.slice(1), flags);
18207
+ break;
18208
+ case "status":
18209
+ showImportStatus(flags);
18210
+ break;
18211
+ default:
18212
+ console.log(`
18213
+ rudi import - Import data from AI agent providers
18214
+
18215
+ COMMANDS
18216
+ sessions [provider] Import sessions from provider (claude, codex, gemini, or all)
18217
+ status Show import status for all providers
18218
+
18219
+ OPTIONS
18220
+ --dry-run Show what would be imported without making changes
18221
+ --max-age=DAYS Only import sessions newer than N days
18222
+ --verbose Show detailed progress
18223
+
18224
+ EXAMPLES
18225
+ rudi import sessions # Import from all providers
18226
+ rudi import sessions claude # Import only Claude sessions
18227
+ rudi import sessions --dry-run # Preview without importing
18228
+ rudi import status # Check what's available to import
18229
+ `);
18230
+ }
18231
+ }
18232
+ async function importSessions(args, flags) {
18233
+ const providerArg = args[0] || "all";
18234
+ const dryRun = flags["dry-run"] || flags.dryRun;
18235
+ const verbose = flags.verbose;
18236
+ const maxAgeDays = flags["max-age"] ? parseInt(flags["max-age"]) : null;
18237
+ if (!isDatabaseInitialized()) {
18238
+ console.log("Initializing database...");
18239
+ initSchema();
18240
+ }
18241
+ const db3 = getDb();
18242
+ const providers = providerArg === "all" ? Object.keys(PROVIDERS) : [providerArg];
18243
+ for (const p of providers) {
18244
+ if (!PROVIDERS[p]) {
18245
+ console.error(`Unknown provider: ${p}`);
18246
+ console.error(`Available: ${Object.keys(PROVIDERS).join(", ")}`);
18247
+ process.exit(1);
18248
+ }
18249
+ }
18250
+ console.log("\u2550".repeat(60));
18251
+ console.log("RUDI Session Import");
18252
+ console.log("\u2550".repeat(60));
18253
+ console.log(`Providers: ${providers.join(", ")}`);
18254
+ console.log(`Database: ${getDbPath()}`);
18255
+ console.log(`Max age: ${maxAgeDays ? `${maxAgeDays} days` : "all"}`);
18256
+ console.log(`Dry run: ${dryRun ? "yes" : "no"}`);
18257
+ console.log("\u2550".repeat(60));
18258
+ let totalImported = 0;
18259
+ let totalSkipped = 0;
18260
+ for (const providerKey of providers) {
18261
+ const provider = PROVIDERS[providerKey];
18262
+ console.log(`
18263
+ \u25B6 ${provider.name}`);
18264
+ console.log(` Source: ${provider.baseDir}`);
18265
+ if (!(0, import_fs10.existsSync)(provider.baseDir)) {
18266
+ console.log(` \u26A0 Directory not found, skipping`);
18267
+ continue;
18268
+ }
18269
+ const existingIds = /* @__PURE__ */ new Set();
18270
+ try {
18271
+ const rows = db3.prepare(
18272
+ "SELECT provider_session_id FROM sessions WHERE provider = ? AND provider_session_id IS NOT NULL"
18273
+ ).all(providerKey);
18274
+ for (const row of rows) {
18275
+ existingIds.add(row.provider_session_id);
18276
+ }
18277
+ } catch (e) {
18278
+ }
18279
+ console.log(` Existing: ${existingIds.size} sessions`);
18280
+ const files = findSessionFiles(provider.baseDir, provider.pattern);
18281
+ console.log(` Found: ${files.length} session files`);
18282
+ const insertStmt = db3.prepare(`
18283
+ INSERT INTO sessions (
18284
+ id, provider, provider_session_id, project_id,
18285
+ origin, origin_imported_at, origin_native_file,
18286
+ title, snippet, status, model,
18287
+ inherit_project_prompt,
18288
+ cwd, dir_scope, native_storage_path,
18289
+ created_at, last_active_at,
18290
+ turn_count, total_cost, total_input_tokens, total_output_tokens, total_duration_ms,
18291
+ is_warmup, parent_session_id, agent_id, is_sidechain, session_type, version, user_type
18292
+ ) VALUES (
18293
+ ?, ?, ?, NULL,
18294
+ 'provider-import', ?, ?,
18295
+ ?, '', 'active', ?,
18296
+ 1,
18297
+ ?, 'project', ?,
18298
+ ?, ?,
18299
+ 0, 0, 0, 0, 0,
18300
+ 0, ?, ?, ?, ?, '2.0.76', 'external'
18301
+ )
18302
+ `);
18303
+ let imported = 0;
18304
+ let skipped = { existing: 0, empty: 0, old: 0, error: 0 };
18305
+ const now = Date.now();
18306
+ const maxAgeMs = maxAgeDays ? maxAgeDays * 24 * 60 * 60 * 1e3 : null;
18307
+ for (const filepath of files) {
18308
+ const sessionId = (0, import_path10.basename)(filepath, ".jsonl");
18309
+ if (existingIds.has(sessionId)) {
18310
+ skipped.existing++;
18311
+ continue;
18312
+ }
18313
+ let stat;
18314
+ try {
18315
+ stat = (0, import_fs10.statSync)(filepath);
18316
+ } catch (e) {
18317
+ skipped.error++;
18318
+ continue;
18319
+ }
18320
+ if (stat.size === 0) {
18321
+ skipped.empty++;
18322
+ continue;
18323
+ }
18324
+ if (maxAgeMs && now - stat.mtimeMs > maxAgeMs) {
18325
+ skipped.old++;
18326
+ continue;
18327
+ }
18328
+ const session = parseSessionFile(filepath, providerKey);
18329
+ if (!session) {
18330
+ skipped.error++;
18331
+ continue;
18332
+ }
18333
+ if (dryRun) {
18334
+ if (verbose || imported < 5) {
18335
+ console.log(` [would import] ${sessionId}: ${session.title.slice(0, 40)}`);
18336
+ }
18337
+ imported++;
18338
+ continue;
18339
+ }
18340
+ try {
18341
+ const nowIso = (/* @__PURE__ */ new Date()).toISOString();
18342
+ insertStmt.run(
18343
+ (0, import_crypto2.randomUUID)(),
18344
+ providerKey,
18345
+ sessionId,
18346
+ nowIso,
18347
+ filepath,
18348
+ session.title,
18349
+ session.model || "unknown",
18350
+ session.cwd,
18351
+ filepath,
18352
+ session.createdAt,
18353
+ session.lastActiveAt,
18354
+ session.parentSessionId,
18355
+ session.agentId,
18356
+ session.isAgent ? 1 : 0,
18357
+ session.sessionType
18358
+ );
18359
+ imported++;
18360
+ if (verbose) {
18361
+ console.log(` \u2713 ${sessionId}: ${session.title.slice(0, 40)}`);
18362
+ } else if (imported % 100 === 0) {
18363
+ console.log(` Imported ${imported}...`);
18364
+ }
18365
+ } catch (e) {
18366
+ skipped.error++;
18367
+ if (verbose) {
18368
+ console.log(` \u2717 ${sessionId}: ${e.message}`);
18369
+ }
18370
+ }
18371
+ }
18372
+ console.log(` \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`);
18373
+ console.log(` Imported: ${imported}`);
18374
+ console.log(` Skipped: ${skipped.existing} existing, ${skipped.empty} empty, ${skipped.old} old, ${skipped.error} errors`);
18375
+ totalImported += imported;
18376
+ totalSkipped += skipped.existing + skipped.empty + skipped.old + skipped.error;
18377
+ }
18378
+ console.log("\n" + "\u2550".repeat(60));
18379
+ console.log(`Total imported: ${totalImported}`);
18380
+ console.log(`Total skipped: ${totalSkipped}`);
18381
+ console.log("\u2550".repeat(60));
18382
+ if (dryRun) {
18383
+ console.log("\n(Dry run - no changes made)");
18384
+ }
18385
+ if (!dryRun && totalImported > 0) {
18386
+ const count = db3.prepare("SELECT COUNT(*) as count FROM sessions").get();
18387
+ console.log(`
18388
+ Total sessions in database: ${count.count}`);
18389
+ }
18390
+ }
18391
+ function showImportStatus(flags) {
18392
+ console.log("\u2550".repeat(60));
18393
+ console.log("Import Status");
18394
+ console.log("\u2550".repeat(60));
18395
+ if (!isDatabaseInitialized()) {
18396
+ console.log("\nDatabase: Not initialized");
18397
+ console.log("Run: rudi db init");
18398
+ } else {
18399
+ const db3 = getDb();
18400
+ const stats = db3.prepare(`
18401
+ SELECT provider, COUNT(*) as count
18402
+ FROM sessions
18403
+ WHERE status = 'active'
18404
+ GROUP BY provider
18405
+ `).all();
18406
+ console.log("\nDatabase sessions:");
18407
+ for (const row of stats) {
18408
+ console.log(` ${row.provider}: ${row.count}`);
18409
+ }
18410
+ }
18411
+ console.log("\nProvider directories:");
18412
+ for (const [key, provider] of Object.entries(PROVIDERS)) {
18413
+ const exists = (0, import_fs10.existsSync)(provider.baseDir);
18414
+ let count = 0;
18415
+ if (exists) {
18416
+ const files = findSessionFiles(provider.baseDir, provider.pattern);
18417
+ count = files.length;
18418
+ }
18419
+ console.log(` ${provider.name}:`);
18420
+ console.log(` Path: ${provider.baseDir}`);
18421
+ console.log(` Status: ${exists ? `${count} session files` : "not found"}`);
18422
+ }
18423
+ console.log("\n" + "\u2550".repeat(60));
18424
+ console.log("To import: rudi import sessions [provider]");
18425
+ }
18426
+ function findSessionFiles(dir, pattern, files = []) {
18427
+ if (!(0, import_fs10.existsSync)(dir)) return files;
18428
+ try {
18429
+ for (const entry of (0, import_fs10.readdirSync)(dir, { withFileTypes: true })) {
18430
+ const fullPath = (0, import_path10.join)(dir, entry.name);
18431
+ if (entry.isDirectory()) {
18432
+ findSessionFiles(fullPath, pattern, files);
18433
+ } else if (pattern.test(entry.name)) {
18434
+ files.push(fullPath);
18435
+ }
18436
+ }
18437
+ } catch (e) {
18438
+ }
18439
+ return files;
18440
+ }
18441
+ function parseSessionFile(filepath, provider) {
18442
+ try {
18443
+ const stat = (0, import_fs10.statSync)(filepath);
18444
+ const content = (0, import_fs10.readFileSync)(filepath, "utf-8");
18445
+ const lines = content.split("\n").filter((l) => l.trim());
18446
+ if (lines.length === 0) return null;
18447
+ const sessionId = (0, import_path10.basename)(filepath, ".jsonl");
18448
+ const isAgent = sessionId.startsWith("agent-");
18449
+ let title = null;
18450
+ let cwd = null;
18451
+ let createdAt = null;
18452
+ let model = null;
18453
+ let parentSessionId = null;
18454
+ let agentId = isAgent ? sessionId.replace("agent-", "") : null;
18455
+ for (const line of lines.slice(0, 50)) {
18456
+ try {
18457
+ const data = JSON.parse(line);
18458
+ if (!cwd && data.cwd) cwd = data.cwd;
18459
+ if (!createdAt && data.timestamp) createdAt = data.timestamp;
18460
+ if (!model && data.model) model = data.model;
18461
+ if (!parentSessionId && (data.parentSessionId || data.parentUuid)) {
18462
+ parentSessionId = data.parentSessionId || data.parentUuid;
18463
+ }
18464
+ if (!agentId && data.agentId) agentId = data.agentId;
18465
+ if (!title) {
18466
+ const msg = data.message?.content || data.userMessage || (data.type === "user" ? data.message?.content : null);
18467
+ if (msg && msg.length > 2) {
18468
+ title = msg.split("\n")[0].slice(0, 50).trim();
18469
+ }
18470
+ }
18471
+ } catch (e) {
18472
+ continue;
18473
+ }
18474
+ }
18475
+ if (!title || title.length < 3) {
18476
+ title = isAgent ? "Agent Session" : "Imported Session";
18477
+ }
18478
+ if (!cwd) {
18479
+ const parentDir = (0, import_path10.basename)((0, import_path10.dirname)(filepath));
18480
+ if (parentDir.startsWith("-")) {
18481
+ cwd = parentDir.replace(/-/g, "/").replace(/^\//, "/");
18482
+ } else {
18483
+ cwd = (0, import_os3.homedir)();
18484
+ }
18485
+ }
18486
+ return {
18487
+ title,
18488
+ cwd,
18489
+ createdAt: createdAt || stat.birthtime.toISOString(),
18490
+ lastActiveAt: stat.mtime.toISOString(),
18491
+ model,
18492
+ isAgent,
18493
+ agentId,
18494
+ parentSessionId,
18495
+ sessionType: isAgent ? "agent" : "main"
18496
+ };
18497
+ } catch (e) {
18498
+ return null;
18499
+ }
18500
+ }
18501
+
18157
18502
  // src/commands/doctor.js
18158
- var import_fs10 = __toESM(require("fs"), 1);
18503
+ var import_fs11 = __toESM(require("fs"), 1);
18159
18504
  async function cmdDoctor(args, flags) {
18160
18505
  console.log("RUDI Health Check");
18161
18506
  console.log("\u2550".repeat(50));
@@ -18173,12 +18518,12 @@ async function cmdDoctor(args, flags) {
18173
18518
  { path: PATHS.cache, name: "Cache" }
18174
18519
  ];
18175
18520
  for (const dir of dirs) {
18176
- const exists = import_fs10.default.existsSync(dir.path);
18521
+ const exists = import_fs11.default.existsSync(dir.path);
18177
18522
  const status = exists ? "\u2713" : "\u2717";
18178
18523
  console.log(` ${status} ${dir.name}: ${dir.path}`);
18179
18524
  if (!exists) {
18180
18525
  issues.push(`Missing directory: ${dir.name}`);
18181
- fixes.push(() => import_fs10.default.mkdirSync(dir.path, { recursive: true }));
18526
+ fixes.push(() => import_fs11.default.mkdirSync(dir.path, { recursive: true }));
18182
18527
  }
18183
18528
  }
18184
18529
  console.log("\n\u{1F4BE} Database");
@@ -18248,8 +18593,8 @@ async function cmdDoctor(args, flags) {
18248
18593
  }
18249
18594
 
18250
18595
  // src/commands/update.js
18251
- var import_fs11 = __toESM(require("fs"), 1);
18252
- var import_path10 = __toESM(require("path"), 1);
18596
+ var import_fs12 = __toESM(require("fs"), 1);
18597
+ var import_path11 = __toESM(require("path"), 1);
18253
18598
  var import_child_process2 = require("child_process");
18254
18599
  init_src();
18255
18600
  init_src2();
@@ -18275,7 +18620,7 @@ async function cmdUpdate(args, flags) {
18275
18620
  async function updatePackage(pkgId, flags) {
18276
18621
  const [kind, name] = parsePackageId(pkgId);
18277
18622
  const installPath = getPackagePath(pkgId);
18278
- if (!import_fs11.default.existsSync(installPath)) {
18623
+ if (!import_fs12.default.existsSync(installPath)) {
18279
18624
  return { success: false, error: "Package not installed" };
18280
18625
  }
18281
18626
  const pkg = await getPackage(pkgId);
@@ -18298,7 +18643,7 @@ async function updatePackage(pkgId, flags) {
18298
18643
  }
18299
18644
  if (pkg.pipPackage) {
18300
18645
  try {
18301
- const venvPip = import_path10.default.join(installPath, "venv", "bin", "pip");
18646
+ const venvPip = import_path11.default.join(installPath, "venv", "bin", "pip");
18302
18647
  (0, import_child_process2.execSync)(`"${venvPip}" install --upgrade ${pkg.pipPackage}`, {
18303
18648
  stdio: flags.verbose ? "inherit" : "pipe"
18304
18649
  });
@@ -18315,7 +18660,7 @@ async function updatePackage(pkgId, flags) {
18315
18660
  if (kind === "runtime" && !pkg.npmPackage && !pkg.pipPackage) {
18316
18661
  try {
18317
18662
  const { downloadRuntime: downloadRuntime2 } = await Promise.resolve().then(() => (init_src2(), src_exports));
18318
- import_fs11.default.rmSync(installPath, { recursive: true, force: true });
18663
+ import_fs12.default.rmSync(installPath, { recursive: true, force: true });
18319
18664
  await downloadRuntime2(name, pkg.version || "latest", installPath, {
18320
18665
  onProgress: (p) => {
18321
18666
  if (flags.verbose) console.log(` ${p.phase}...`);
@@ -18335,8 +18680,8 @@ async function updateAll(flags) {
18335
18680
  let failed = 0;
18336
18681
  for (const kind of kinds) {
18337
18682
  const dir = kind === "runtime" ? PATHS.runtimes : kind === "stack" ? PATHS.stacks : PATHS.prompts;
18338
- if (!import_fs11.default.existsSync(dir)) continue;
18339
- const entries = import_fs11.default.readdirSync(dir, { withFileTypes: true });
18683
+ if (!import_fs12.default.existsSync(dir)) continue;
18684
+ const entries = import_fs12.default.readdirSync(dir, { withFileTypes: true });
18340
18685
  for (const entry of entries) {
18341
18686
  if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
18342
18687
  const pkgId = `${kind}:${entry.name}`;
@@ -18355,14 +18700,14 @@ Updated ${updated} package(s)${failed > 0 ? `, ${failed} failed` : ""}`);
18355
18700
  }
18356
18701
  function getInstalledVersion(installPath, npmPackage) {
18357
18702
  try {
18358
- const pkgJsonPath = import_path10.default.join(installPath, "node_modules", npmPackage.replace("@", "").split("/")[0], "package.json");
18359
- if (import_fs11.default.existsSync(pkgJsonPath)) {
18360
- const pkgJson = JSON.parse(import_fs11.default.readFileSync(pkgJsonPath, "utf-8"));
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"));
18361
18706
  return pkgJson.version;
18362
18707
  }
18363
- const rootPkgPath = import_path10.default.join(installPath, "package.json");
18364
- if (import_fs11.default.existsSync(rootPkgPath)) {
18365
- const rootPkg = JSON.parse(import_fs11.default.readFileSync(rootPkgPath, "utf-8"));
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"));
18366
18711
  const dep = rootPkg.dependencies?.[npmPackage];
18367
18712
  if (dep) return dep.replace(/[\^~]/, "");
18368
18713
  }
@@ -18371,30 +18716,30 @@ function getInstalledVersion(installPath, npmPackage) {
18371
18716
  return null;
18372
18717
  }
18373
18718
  function updateRuntimeMetadata(installPath, updates) {
18374
- const metaPath = import_path10.default.join(installPath, "runtime.json");
18719
+ const metaPath = import_path11.default.join(installPath, "runtime.json");
18375
18720
  try {
18376
18721
  let meta = {};
18377
- if (import_fs11.default.existsSync(metaPath)) {
18378
- meta = JSON.parse(import_fs11.default.readFileSync(metaPath, "utf-8"));
18722
+ if (import_fs12.default.existsSync(metaPath)) {
18723
+ meta = JSON.parse(import_fs12.default.readFileSync(metaPath, "utf-8"));
18379
18724
  }
18380
18725
  meta = { ...meta, ...updates };
18381
- import_fs11.default.writeFileSync(metaPath, JSON.stringify(meta, null, 2));
18726
+ import_fs12.default.writeFileSync(metaPath, JSON.stringify(meta, null, 2));
18382
18727
  } catch {
18383
18728
  }
18384
18729
  }
18385
18730
 
18386
18731
  // db/index.js
18387
18732
  var import_better_sqlite32 = __toESM(require("better-sqlite3"), 1);
18388
- var import_path11 = __toESM(require("path"), 1);
18389
- var import_os3 = __toESM(require("os"), 1);
18390
- var import_fs12 = __toESM(require("fs"), 1);
18391
- var PROMPT_STACK_HOME3 = import_path11.default.join(import_os3.default.homedir(), ".prompt-stack");
18392
- var DB_PATH2 = import_path11.default.join(PROMPT_STACK_HOME3, "prompt-stack.db");
18733
+ var import_path12 = __toESM(require("path"), 1);
18734
+ 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");
18393
18738
  var db2 = null;
18394
18739
  function getDb2(options = {}) {
18395
18740
  if (!db2) {
18396
- if (!import_fs12.default.existsSync(PROMPT_STACK_HOME3)) {
18397
- import_fs12.default.mkdirSync(PROMPT_STACK_HOME3, { recursive: true });
18741
+ if (!import_fs13.default.existsSync(PROMPT_STACK_HOME)) {
18742
+ import_fs13.default.mkdirSync(PROMPT_STACK_HOME, { recursive: true });
18398
18743
  }
18399
18744
  db2 = new import_better_sqlite32.default(DB_PATH2, {
18400
18745
  readonly: options.readonly || false
@@ -18552,7 +18897,7 @@ function getBeforeCrashLogs() {
18552
18897
  }
18553
18898
 
18554
18899
  // src/commands/logs.js
18555
- var import_fs13 = __toESM(require("fs"), 1);
18900
+ var import_fs14 = __toESM(require("fs"), 1);
18556
18901
  function parseTimeAgo(str) {
18557
18902
  const match = str.match(/^(\d+)([smhd])$/);
18558
18903
  if (!match) return null;
@@ -18652,7 +18997,7 @@ function exportLogs(logs, filepath, format) {
18652
18997
  });
18653
18998
  content = JSON.stringify(formatted, null, 2);
18654
18999
  }
18655
- import_fs13.default.writeFileSync(filepath, content, "utf-8");
19000
+ import_fs14.default.writeFileSync(filepath, content, "utf-8");
18656
19001
  return filepath;
18657
19002
  }
18658
19003
  function printStats(stats) {
@@ -19189,6 +19534,9 @@ async function main() {
19189
19534
  case "database":
19190
19535
  await cmdDb(args, flags);
19191
19536
  break;
19537
+ case "import":
19538
+ await cmdImport(args, flags);
19539
+ break;
19192
19540
  case "doctor":
19193
19541
  case "check":
19194
19542
  await cmdDoctor(args, flags);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@learnrudi/cli",
3
- "version": "1.0.0",
3
+ "version": "1.1.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",