@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.
- package/dist/index.cjs +282 -44
- 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
|
|
18182
|
-
var
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
18665
|
+
if (!(0, import_fs11.existsSync)(dir)) return files;
|
|
18428
18666
|
try {
|
|
18429
|
-
for (const entry of (0,
|
|
18430
|
-
const fullPath = (0,
|
|
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,
|
|
18444
|
-
const content = (0,
|
|
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,
|
|
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,
|
|
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
|
|
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 =
|
|
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(() =>
|
|
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
|
|
18597
|
-
var
|
|
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 (!
|
|
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 =
|
|
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
|
-
|
|
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 (!
|
|
18684
|
-
const entries =
|
|
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 =
|
|
18704
|
-
if (
|
|
18705
|
-
const pkgJson = JSON.parse(
|
|
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 =
|
|
18709
|
-
if (
|
|
18710
|
-
const rootPkg = JSON.parse(
|
|
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 =
|
|
18957
|
+
const metaPath = import_path12.default.join(installPath, "runtime.json");
|
|
18720
18958
|
try {
|
|
18721
18959
|
let meta = {};
|
|
18722
|
-
if (
|
|
18723
|
-
meta = JSON.parse(
|
|
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
|
-
|
|
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
|
|
18971
|
+
var import_path13 = __toESM(require("path"), 1);
|
|
18734
18972
|
var import_os4 = __toESM(require("os"), 1);
|
|
18735
|
-
var
|
|
18736
|
-
var PROMPT_STACK_HOME =
|
|
18737
|
-
var DB_PATH2 =
|
|
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 (!
|
|
18742
|
-
|
|
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
|
|
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
|
-
|
|
19238
|
+
import_fs15.default.writeFileSync(filepath, content, "utf-8");
|
|
19001
19239
|
return filepath;
|
|
19002
19240
|
}
|
|
19003
19241
|
function printStats(stats) {
|