codexuse-cli 6.0.2 → 6.0.3

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.js CHANGED
@@ -2026,7 +2026,7 @@ var require_toml = __commonJS({
2026
2026
  });
2027
2027
 
2028
2028
  // src/commands/accountPool.ts
2029
- var import_node_crypto12 = require("crypto");
2029
+ var import_node_crypto13 = require("crypto");
2030
2030
  var import_node_path13 = __toESM(require("path"));
2031
2031
 
2032
2032
  // ../../packages/contracts/src/settings/types.ts
@@ -2078,8 +2078,8 @@ function migrateLegacyAccountPoolExposedReasoningDefaults(efforts) {
2078
2078
 
2079
2079
  // ../../packages/runtime-app-state/src/app/state.ts
2080
2080
  var import_node_async_hooks = require("async_hooks");
2081
- var import_node_crypto = require("crypto");
2082
- var import_node_path2 = __toESM(require("path"), 1);
2081
+ var import_node_crypto2 = require("crypto");
2082
+ var import_node_path3 = __toESM(require("path"), 1);
2083
2083
  var import_node_os = __toESM(require("os"), 1);
2084
2084
 
2085
2085
  // ../../packages/contracts/src/settings/auto-roll.ts
@@ -2211,16 +2211,98 @@ function normalizeAutoRollSettings(raw) {
2211
2211
  }
2212
2212
 
2213
2213
  // ../../packages/runtime-app-state/src/storage/documents.ts
2214
+ var import_node_fs2 = require("fs");
2215
+ var import_node_fs3 = require("fs");
2216
+ var import_node_crypto = require("crypto");
2217
+ var import_node_path2 = __toESM(require("path"), 1);
2218
+
2219
+ // ../../packages/runtime-app-state/src/storage/fileLock.ts
2214
2220
  var import_node_fs = require("fs");
2215
2221
  var import_node_path = __toESM(require("path"), 1);
2222
+ function isSqliteBusyError(error) {
2223
+ if (!error || typeof error !== "object") {
2224
+ return false;
2225
+ }
2226
+ const value3 = error;
2227
+ if (value3.cause && value3.cause !== error && isSqliteBusyError(value3.cause)) {
2228
+ return true;
2229
+ }
2230
+ if (value3.error && value3.error !== error && isSqliteBusyError(value3.error)) {
2231
+ return true;
2232
+ }
2233
+ const message = typeof value3.message === "string" ? value3.message.toLowerCase() : String(error).toLowerCase();
2234
+ return value3.code === "SQLITE_BUSY" || value3.errno === 5 || message.includes("sqlite_busy") || message.includes("database is locked");
2235
+ }
2236
+ async function openLockDatabase(databasePath) {
2237
+ await import_node_fs.promises.mkdir(import_node_path.default.dirname(databasePath), { recursive: true, mode: 448 });
2238
+ const sqlite = process.versions.bun ? await Function("return import('bun:sqlite')")() : await Function("return import('node:sqlite')")();
2239
+ const database = process.versions.bun ? new sqlite.Database(databasePath) : new sqlite.DatabaseSync(databasePath);
2240
+ try {
2241
+ if (process.platform !== "win32") {
2242
+ await import_node_fs.promises.chmod(databasePath, 384);
2243
+ }
2244
+ return {
2245
+ exec: database.exec.bind(database),
2246
+ close: database.close.bind(database)
2247
+ };
2248
+ } catch (error) {
2249
+ database.close();
2250
+ throw error;
2251
+ }
2252
+ }
2253
+ async function acquireCrossProcessFileLockTransaction(filePath, mode) {
2254
+ const databasePath = `${import_node_path.default.resolve(filePath)}.codexuse-lock.sqlite`;
2255
+ let database = null;
2256
+ try {
2257
+ database = await openLockDatabase(databasePath);
2258
+ database.exec(`PRAGMA busy_timeout = ${mode === "write" ? 1e3 : 0};`);
2259
+ database.exec("CREATE TABLE IF NOT EXISTS codexuse_file_lock (id INTEGER PRIMARY KEY);");
2260
+ if (mode === "write") {
2261
+ database.exec("BEGIN EXCLUSIVE;");
2262
+ } else {
2263
+ database.exec("BEGIN;");
2264
+ database.exec("SELECT COUNT(*) FROM codexuse_file_lock;");
2265
+ }
2266
+ } catch (error) {
2267
+ database?.close();
2268
+ if (isSqliteBusyError(error)) {
2269
+ return null;
2270
+ }
2271
+ throw error;
2272
+ }
2273
+ const acquiredDatabase = database;
2274
+ let released = false;
2275
+ return async () => {
2276
+ if (released) {
2277
+ return;
2278
+ }
2279
+ released = true;
2280
+ try {
2281
+ acquiredDatabase.exec("ROLLBACK;");
2282
+ } finally {
2283
+ acquiredDatabase.close();
2284
+ }
2285
+ };
2286
+ }
2287
+ async function acquireCrossProcessFileLock(filePath) {
2288
+ return acquireCrossProcessFileLockTransaction(filePath, "write");
2289
+ }
2290
+ async function acquireCrossProcessFileReadLock(filePath) {
2291
+ return acquireCrossProcessFileLockTransaction(filePath, "read");
2292
+ }
2293
+
2294
+ // ../../packages/runtime-app-state/src/storage/documents.ts
2216
2295
  var APP_STORAGE_TABLE = "app_storage_documents";
2217
2296
  var APP_STORAGE_DB_DIR = "app-state";
2218
2297
  var APP_STORAGE_DB_NAME = "state.sqlite";
2298
+ var APP_STORAGE_QUARANTINE_DIR = "quarantine";
2299
+ var APP_STORAGE_RECOVERY_LOG_LIMIT = 50;
2300
+ var APP_STORAGE_QUARANTINE_LIMIT = 3;
2219
2301
  var SQLITE_BUSY_TIMEOUT_MS = 5e3;
2220
2302
  var SQLITE_BUSY_MAX_ATTEMPTS = 3;
2221
2303
  var SQLITE_BUSY_RETRY_DELAY_MS = 100;
2222
2304
  var writeQueueByDbPath = /* @__PURE__ */ new Map();
2223
- var initializedDbPaths = /* @__PURE__ */ new Set();
2305
+ var databaseRecoveryByDbPath = /* @__PURE__ */ new Map();
2224
2306
  var AppStorageCorruptionError = class extends Error {
2225
2307
  constructor(message, options) {
2226
2308
  super(message);
@@ -2232,6 +2314,13 @@ var AppStorageCorruptionError = class extends Error {
2232
2314
  }
2233
2315
  }
2234
2316
  };
2317
+ var recoveryLog = [];
2318
+ function recordRecovery(event) {
2319
+ recoveryLog.push(event);
2320
+ if (recoveryLog.length > APP_STORAGE_RECOVERY_LOG_LIMIT) {
2321
+ recoveryLog.splice(0, recoveryLog.length - APP_STORAGE_RECOVERY_LOG_LIMIT);
2322
+ }
2323
+ }
2235
2324
  function isRecord(value3) {
2236
2325
  return Boolean(value3) && typeof value3 === "object" && !Array.isArray(value3);
2237
2326
  }
@@ -2251,53 +2340,239 @@ function safeParseJson(raw) {
2251
2340
  return null;
2252
2341
  }
2253
2342
  }
2254
- function parseJsonStrict(raw, options) {
2255
- if (typeof raw !== "string" || raw.trim().length === 0) {
2256
- return null;
2257
- }
2258
- try {
2259
- return JSON.parse(raw);
2260
- } catch (error) {
2261
- throw new AppStorageCorruptionError(
2262
- `App storage document ${options.namespace} contains invalid JSON.`,
2263
- {
2264
- dbPath: options.dbPath,
2265
- namespace: options.namespace,
2266
- cause: error
2267
- }
2268
- );
2269
- }
2343
+ function describeError(error) {
2344
+ return error instanceof Error ? error.message : String(error);
2270
2345
  }
2271
2346
  function sleep(ms) {
2272
2347
  return new Promise((resolve2) => setTimeout(resolve2, ms));
2273
2348
  }
2274
- function isSqliteBusyError(error) {
2349
+ function matchesErrorChain(error, predicate) {
2275
2350
  if (!error || typeof error !== "object") {
2276
2351
  return false;
2277
2352
  }
2278
- const sqliteError = error;
2279
- if (sqliteError.cause && sqliteError.cause !== error && isSqliteBusyError(sqliteError.cause)) {
2353
+ const candidate = error;
2354
+ if (predicate(candidate)) {
2280
2355
  return true;
2281
2356
  }
2282
- if (sqliteError.error && sqliteError.error !== error && isSqliteBusyError(sqliteError.error)) {
2283
- return true;
2357
+ for (const key of ["cause", "error"]) {
2358
+ const nested = candidate[key];
2359
+ if (nested && nested !== error && matchesErrorChain(nested, predicate)) {
2360
+ return true;
2361
+ }
2284
2362
  }
2285
- const message = typeof sqliteError.message === "string" ? sqliteError.message.toLowerCase() : String(error).toLowerCase();
2286
- return sqliteError.code === "SQLITE_BUSY" || sqliteError.errno === 5 || message.includes("sqlite_busy") || message.includes("database is locked");
2363
+ return false;
2364
+ }
2365
+ function isSqliteBusyError2(error) {
2366
+ return matchesErrorChain(error, (candidate) => {
2367
+ const message = typeof candidate.message === "string" ? candidate.message.toLowerCase() : "";
2368
+ return candidate.code === "SQLITE_BUSY" || candidate.errno === 5 || message.includes("sqlite_busy") || message.includes("database is locked");
2369
+ });
2287
2370
  }
2288
2371
  function isSqliteCorruptionError(error) {
2289
- if (!error || typeof error !== "object") {
2290
- return false;
2372
+ return matchesErrorChain(error, (candidate) => {
2373
+ const message = typeof candidate.message === "string" ? candidate.message.toLowerCase() : "";
2374
+ return candidate.code === "SQLITE_CORRUPT" || candidate.code === "SQLITE_NOTADB" || candidate.errno === 11 || candidate.errno === 26 || message.includes("database disk image is malformed") || message.includes("file is not a database") || message.includes("database corruption") || message.includes("sqlite_corrupt") || message.includes("sqlite_notadb");
2375
+ });
2376
+ }
2377
+ function isSqliteCantOpenError(error) {
2378
+ return matchesErrorChain(error, (candidate) => {
2379
+ const message = typeof candidate.message === "string" ? candidate.message.toLowerCase() : "";
2380
+ return candidate.code === "SQLITE_CANTOPEN" || message.includes("unable to open database file");
2381
+ });
2382
+ }
2383
+ var STORAGE_UNAVAILABLE_CODES = /* @__PURE__ */ new Set([
2384
+ "EACCES",
2385
+ "EPERM",
2386
+ "EROFS",
2387
+ "ENOSPC",
2388
+ "ENOTDIR",
2389
+ "ENAMETOOLONG",
2390
+ "ENOENT",
2391
+ "ELOOP",
2392
+ "EIO",
2393
+ "EMFILE",
2394
+ "ENFILE"
2395
+ ]);
2396
+ function isStorageUnavailableError(error) {
2397
+ return matchesErrorChain(error, (candidate) => {
2398
+ const message = typeof candidate.message === "string" ? candidate.message.toLowerCase() : "";
2399
+ return typeof candidate.code === "string" && (STORAGE_UNAVAILABLE_CODES.has(candidate.code) || candidate.code === "SQLITE_READONLY" || candidate.code === "SQLITE_CANTOPEN") || candidate.errno === 8 || message.includes("attempt to write a readonly database") || message.includes("unable to open database file");
2400
+ });
2401
+ }
2402
+ function isAppStorageCorruptionError(error) {
2403
+ return error instanceof AppStorageCorruptionError || isSqliteCorruptionError(error);
2404
+ }
2405
+ function classifyAppStorageFailure(error) {
2406
+ if (isAppStorageCorruptionError(error)) {
2407
+ return "corrupt";
2291
2408
  }
2292
- const sqliteError = error;
2293
- if (sqliteError.cause && sqliteError.cause !== error && isSqliteCorruptionError(sqliteError.cause)) {
2294
- return true;
2409
+ if (isSqliteBusyError2(error)) {
2410
+ return "busy";
2295
2411
  }
2296
- if (sqliteError.error && sqliteError.error !== error && isSqliteCorruptionError(sqliteError.error)) {
2297
- return true;
2412
+ if (isStorageUnavailableError(error)) {
2413
+ return "unavailable";
2414
+ }
2415
+ return "unknown";
2416
+ }
2417
+ function quarantineDirFor(dbPath) {
2418
+ return import_node_path2.default.join(import_node_path2.default.dirname(dbPath), APP_STORAGE_QUARANTINE_DIR);
2419
+ }
2420
+ function safeFileNamePart(value3) {
2421
+ const cleaned = value3.replace(/[^A-Za-z0-9._-]+/g, "_").slice(0, 80);
2422
+ return cleaned.length > 0 ? cleaned : "unknown";
2423
+ }
2424
+ function quarantineKey(scope2, value3) {
2425
+ const digest = (0, import_node_crypto.createHash)("sha256").update(value3).digest("hex").slice(0, 10);
2426
+ return `${scope2}-${safeFileNamePart(value3)}-${digest}`;
2427
+ }
2428
+ function uniqueQuarantinePath(dir, key, extension) {
2429
+ const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
2430
+ return import_node_path2.default.join(dir, `${key}-${stamp}-${(0, import_node_crypto.randomUUID)()}${extension}`);
2431
+ }
2432
+ async function pruneQuarantineCopies(input) {
2433
+ try {
2434
+ const prefix = `${input.key}-`;
2435
+ const names = (await import_node_fs3.promises.readdir(input.dir)).filter((name) => {
2436
+ if (name.startsWith(prefix) && name.endsWith(input.extension)) {
2437
+ return true;
2438
+ }
2439
+ if (!input.legacyPrefix || !name.startsWith(input.legacyPrefix)) {
2440
+ return false;
2441
+ }
2442
+ return input.databaseSidecars ? !name.endsWith("-wal") && !name.endsWith("-shm") : name.endsWith(input.extension);
2443
+ });
2444
+ const copies = await Promise.all(names.map(async (name) => ({
2445
+ name,
2446
+ modifiedAt: (await import_node_fs3.promises.stat(import_node_path2.default.join(input.dir, name))).mtimeMs
2447
+ })));
2448
+ copies.sort(
2449
+ (left, right) => right.modifiedAt - left.modifiedAt || right.name.localeCompare(left.name)
2450
+ );
2451
+ for (const { name } of copies.slice(APP_STORAGE_QUARANTINE_LIMIT)) {
2452
+ const candidate = import_node_path2.default.join(input.dir, name);
2453
+ await import_node_fs3.promises.rm(candidate, { force: true });
2454
+ if (input.databaseSidecars) {
2455
+ await Promise.all([
2456
+ import_node_fs3.promises.rm(`${candidate}-wal`, { force: true }),
2457
+ import_node_fs3.promises.rm(`${candidate}-shm`, { force: true })
2458
+ ]);
2459
+ }
2460
+ }
2461
+ } catch {
2462
+ }
2463
+ }
2464
+ function stageDamagedDocumentRecovery(input) {
2465
+ let backupPath = null;
2466
+ const key = quarantineKey("document", input.namespace);
2467
+ try {
2468
+ const dir = quarantineDirFor(input.dbPath);
2469
+ (0, import_node_fs2.mkdirSync)(dir, { recursive: true, mode: 448 });
2470
+ if (process.platform !== "win32") {
2471
+ (0, import_node_fs2.chmodSync)(dir, 448);
2472
+ }
2473
+ const candidate = uniqueQuarantinePath(dir, key, ".json");
2474
+ (0, import_node_fs2.writeFileSync)(candidate, input.raw ?? "", { flag: "wx", mode: 384 });
2475
+ backupPath = candidate;
2476
+ } catch {
2477
+ }
2478
+ try {
2479
+ withStatement(
2480
+ input.db,
2481
+ `DELETE FROM ${APP_STORAGE_TABLE} WHERE namespace = ?`,
2482
+ (statement) => statement.run(input.namespace)
2483
+ );
2484
+ } catch (error) {
2485
+ if (backupPath) {
2486
+ try {
2487
+ (0, import_node_fs2.rmSync)(backupPath, { force: true });
2488
+ } catch {
2489
+ }
2490
+ }
2491
+ throw error;
2492
+ }
2493
+ return {
2494
+ event: {
2495
+ at: (/* @__PURE__ */ new Date()).toISOString(),
2496
+ scope: "document",
2497
+ dbPath: input.dbPath,
2498
+ namespace: input.namespace,
2499
+ backupPath,
2500
+ reason: input.reason
2501
+ },
2502
+ quarantineKey: key
2503
+ };
2504
+ }
2505
+ function discardStagedDocumentRecovery(recovery) {
2506
+ if (!recovery?.event.backupPath) {
2507
+ return;
2508
+ }
2509
+ try {
2510
+ (0, import_node_fs2.rmSync)(recovery.event.backupPath, { force: true });
2511
+ } catch {
2512
+ }
2513
+ }
2514
+ async function finalizeDocumentRecovery(recovery) {
2515
+ if (!recovery) {
2516
+ return;
2517
+ }
2518
+ recordRecovery(recovery.event);
2519
+ await pruneQuarantineCopies({
2520
+ dir: quarantineDirFor(recovery.event.dbPath),
2521
+ key: recovery.quarantineKey,
2522
+ extension: ".json",
2523
+ legacyPrefix: `${safeFileNamePart(recovery.event.namespace ?? "unknown")}-`
2524
+ });
2525
+ }
2526
+ async function copyDatabaseToQuarantine(dbPath) {
2527
+ const dir = quarantineDirFor(dbPath);
2528
+ await import_node_fs3.promises.mkdir(dir, { recursive: true, mode: 448 });
2529
+ if (process.platform !== "win32") {
2530
+ await import_node_fs3.promises.chmod(dir, 448);
2531
+ }
2532
+ const key = quarantineKey("database", import_node_path2.default.basename(dbPath));
2533
+ const target = uniqueQuarantinePath(dir, key, ".sqlite");
2534
+ const copiedSuffixes = [];
2535
+ try {
2536
+ await import_node_fs3.promises.copyFile(dbPath, target);
2537
+ copiedSuffixes.push("");
2538
+ if (process.platform !== "win32") {
2539
+ await import_node_fs3.promises.chmod(target, 384);
2540
+ }
2541
+ for (const suffix of ["-wal", "-shm"]) {
2542
+ try {
2543
+ await import_node_fs3.promises.copyFile(`${dbPath}${suffix}`, `${target}${suffix}`);
2544
+ copiedSuffixes.push(suffix);
2545
+ if (process.platform !== "win32") {
2546
+ await import_node_fs3.promises.chmod(`${target}${suffix}`, 384);
2547
+ }
2548
+ } catch (error) {
2549
+ if (error.code !== "ENOENT") {
2550
+ throw error;
2551
+ }
2552
+ }
2553
+ }
2554
+ } catch (error) {
2555
+ for (const copiedSuffix of copiedSuffixes) {
2556
+ await import_node_fs3.promises.rm(`${target}${copiedSuffix}`, { force: true }).catch(() => void 0);
2557
+ }
2558
+ throw error;
2559
+ }
2560
+ return { backupPath: target, quarantineKey: key };
2561
+ }
2562
+ async function installReplacementDatabase(dbPath, replacementPath) {
2563
+ for (const suffix of ["-wal", "-shm"]) {
2564
+ await import_node_fs3.promises.rm(`${dbPath}${suffix}`, { force: true });
2565
+ }
2566
+ try {
2567
+ await import_node_fs3.promises.rename(replacementPath, dbPath);
2568
+ } catch (error) {
2569
+ const code = error.code;
2570
+ if (code !== "EEXIST" && code !== "EPERM") {
2571
+ throw error;
2572
+ }
2573
+ await import_node_fs3.promises.copyFile(replacementPath, dbPath);
2574
+ await import_node_fs3.promises.rm(replacementPath, { force: true }).catch(() => void 0);
2298
2575
  }
2299
- const message = typeof sqliteError.message === "string" ? sqliteError.message.toLowerCase() : "";
2300
- return sqliteError.code === "SQLITE_CORRUPT" || sqliteError.code === "SQLITE_NOTADB" || sqliteError.errno === 11 || sqliteError.errno === 26 || message.includes("database disk image is malformed") || message.includes("file is not a database") || message.includes("database corruption") || message.includes("sqlite_corrupt") || message.includes("sqlite_notadb");
2301
2576
  }
2302
2577
  function beginImmediate(db) {
2303
2578
  db.exec("BEGIN IMMEDIATE");
@@ -2311,7 +2586,7 @@ function rollback(db) {
2311
2586
  } catch {
2312
2587
  }
2313
2588
  }
2314
- function useStatement(db, sql, task) {
2589
+ function withStatement(db, sql, task) {
2315
2590
  const statement = db.prepare(sql);
2316
2591
  try {
2317
2592
  return task(statement);
@@ -2341,10 +2616,11 @@ function applyConnectionPragmas(db) {
2341
2616
  db.exec("PRAGMA journal_mode = WAL;");
2342
2617
  db.exec("PRAGMA foreign_keys = ON;");
2343
2618
  }
2344
- function ensureSchema(db, dbPath) {
2345
- if (initializedDbPaths.has(dbPath)) {
2346
- return;
2347
- }
2619
+ function applyReadConnectionPragmas(db) {
2620
+ db.exec(`PRAGMA busy_timeout = ${SQLITE_BUSY_TIMEOUT_MS};`);
2621
+ db.exec("PRAGMA foreign_keys = ON;");
2622
+ }
2623
+ function ensureSchema(db) {
2348
2624
  db.exec(`
2349
2625
  CREATE TABLE IF NOT EXISTS ${APP_STORAGE_TABLE} (
2350
2626
  namespace TEXT PRIMARY KEY,
@@ -2352,76 +2628,387 @@ function ensureSchema(db, dbPath) {
2352
2628
  updated_at TEXT NOT NULL
2353
2629
  )
2354
2630
  `);
2355
- initializedDbPaths.add(dbPath);
2356
2631
  }
2357
2632
  async function openDatabase(dbPath) {
2358
- const dbDir = import_node_path.default.dirname(dbPath);
2359
- await import_node_fs.promises.mkdir(dbDir, { recursive: true, mode: 448 });
2633
+ const dbDir = import_node_path2.default.dirname(dbPath);
2634
+ await import_node_fs3.promises.mkdir(dbDir, { recursive: true, mode: 448 });
2360
2635
  if (process.platform !== "win32") {
2361
- await import_node_fs.promises.chmod(dbDir, 448);
2636
+ await import_node_fs3.promises.chmod(dbDir, 448);
2362
2637
  }
2363
2638
  if (process.versions.bun !== void 0) {
2364
2639
  const sqlite2 = await Function("return import('bun:sqlite')")();
2365
2640
  const database2 = new sqlite2.Database(dbPath);
2366
- const result3 = {
2641
+ try {
2642
+ if (process.platform !== "win32") {
2643
+ await import_node_fs3.promises.chmod(dbPath, 384);
2644
+ }
2645
+ return {
2646
+ exec: database2.exec.bind(database2),
2647
+ prepare: database2.prepare.bind(database2),
2648
+ close: database2.close.bind(database2)
2649
+ };
2650
+ } catch (error) {
2651
+ database2.close();
2652
+ throw error;
2653
+ }
2654
+ }
2655
+ const sqlite = await Function("return import('node:sqlite')")();
2656
+ const database = new sqlite.DatabaseSync(dbPath);
2657
+ try {
2658
+ if (process.platform !== "win32") {
2659
+ await import_node_fs3.promises.chmod(dbPath, 384);
2660
+ }
2661
+ return {
2662
+ exec: database.exec.bind(database),
2663
+ prepare: database.prepare.bind(database),
2664
+ close: database.close.bind(database)
2665
+ };
2666
+ } catch (error) {
2667
+ database.close();
2668
+ throw error;
2669
+ }
2670
+ }
2671
+ async function openReadOnlyDatabase(dbPath) {
2672
+ if (process.versions.bun !== void 0) {
2673
+ const sqlite2 = await Function("return import('bun:sqlite')")();
2674
+ const database2 = new sqlite2.Database(dbPath, { readonly: true });
2675
+ return {
2367
2676
  exec: database2.exec.bind(database2),
2368
2677
  prepare: database2.prepare.bind(database2),
2369
2678
  close: database2.close.bind(database2)
2370
2679
  };
2371
- if (process.platform !== "win32") {
2372
- await import_node_fs.promises.chmod(dbPath, 384);
2373
- }
2374
- return result3;
2375
2680
  }
2376
2681
  const sqlite = await Function("return import('node:sqlite')")();
2377
- const database = new sqlite.DatabaseSync(dbPath);
2378
- const result2 = {
2682
+ const database = new sqlite.DatabaseSync(dbPath, { readOnly: true });
2683
+ return {
2379
2684
  exec: database.exec.bind(database),
2380
2685
  prepare: database.prepare.bind(database),
2381
2686
  close: database.close.bind(database)
2382
2687
  };
2383
- if (process.platform !== "win32") {
2384
- await import_node_fs.promises.chmod(dbPath, 384);
2688
+ }
2689
+ function sqliteBusyError(message) {
2690
+ return Object.assign(new Error(message), { code: "SQLITE_BUSY" });
2691
+ }
2692
+ function isMissingStorageTableError(error) {
2693
+ return matchesErrorChain(error, (candidate) => {
2694
+ const message = typeof candidate.message === "string" ? candidate.message.toLowerCase() : "";
2695
+ return message.includes(`no such table: ${APP_STORAGE_TABLE}`);
2696
+ });
2697
+ }
2698
+ async function acquireDatabaseFileLock(dbPath, mode) {
2699
+ const acquire = mode === "read" ? acquireCrossProcessFileReadLock : acquireCrossProcessFileLock;
2700
+ for (let attempt = 1; attempt <= SQLITE_BUSY_MAX_ATTEMPTS; attempt += 1) {
2701
+ const release = await acquire(dbPath);
2702
+ if (release) {
2703
+ return release;
2704
+ }
2705
+ if (attempt < SQLITE_BUSY_MAX_ATTEMPTS) {
2706
+ await sleep(SQLITE_BUSY_RETRY_DELAY_MS * attempt);
2707
+ }
2708
+ }
2709
+ throw sqliteBusyError(`App storage ${mode} lock is busy.`);
2710
+ }
2711
+ async function probeDatabaseHealth(dbPath) {
2712
+ if (!(0, import_node_fs2.existsSync)(dbPath)) {
2713
+ return "healthy";
2714
+ }
2715
+ let db = null;
2716
+ try {
2717
+ db = await openReadOnlyDatabase(dbPath);
2718
+ applyReadConnectionPragmas(db);
2719
+ const row = withStatement(
2720
+ db,
2721
+ "PRAGMA quick_check(1)",
2722
+ (statement) => statement.get()
2723
+ );
2724
+ return isRecord(row) && Object.values(row).some((value3) => value3 === "ok") ? "healthy" : "corrupt";
2725
+ } catch (error) {
2726
+ if (isAppStorageCorruptionError(error)) {
2727
+ return "corrupt";
2728
+ }
2729
+ throw error;
2730
+ } finally {
2731
+ db?.close();
2732
+ }
2733
+ }
2734
+ async function readSalvageableDocuments(dbPath) {
2735
+ let db = null;
2736
+ try {
2737
+ db = await openReadOnlyDatabase(dbPath);
2738
+ applyReadConnectionPragmas(db);
2739
+ const rows = withStatement(
2740
+ db,
2741
+ `
2742
+ SELECT
2743
+ namespace,
2744
+ value_json AS valueJson,
2745
+ updated_at AS updatedAt
2746
+ FROM ${APP_STORAGE_TABLE}
2747
+ `,
2748
+ (statement) => statement.all()
2749
+ );
2750
+ return rows.flatMap((row) => {
2751
+ if (!isRecord(row) || typeof row.namespace !== "string" || typeof row.valueJson !== "string" || typeof row.updatedAt !== "string") {
2752
+ return [];
2753
+ }
2754
+ return [{
2755
+ namespace: row.namespace,
2756
+ valueJson: row.valueJson,
2757
+ updatedAt: row.updatedAt
2758
+ }];
2759
+ });
2760
+ } catch (error) {
2761
+ if (isAppStorageCorruptionError(error) || isMissingStorageTableError(error)) {
2762
+ return [];
2763
+ }
2764
+ throw error;
2765
+ } finally {
2766
+ db?.close();
2767
+ }
2768
+ }
2769
+ async function buildReplacementDatabase(dbPath, rows) {
2770
+ const replacementPath = `${dbPath}.recovery-${(0, import_node_crypto.randomUUID)()}.sqlite`;
2771
+ try {
2772
+ const db = await openDatabase(replacementPath);
2773
+ try {
2774
+ db.exec(`PRAGMA busy_timeout = ${SQLITE_BUSY_TIMEOUT_MS};`);
2775
+ db.exec("PRAGMA journal_mode = DELETE;");
2776
+ db.exec("PRAGMA foreign_keys = ON;");
2777
+ ensureSchema(db);
2778
+ beginImmediate(db);
2779
+ try {
2780
+ for (const row of rows) {
2781
+ withStatement(
2782
+ db,
2783
+ `
2784
+ INSERT INTO ${APP_STORAGE_TABLE} (namespace, value_json, updated_at)
2785
+ VALUES (?, ?, ?)
2786
+ `,
2787
+ (statement) => statement.run(row.namespace, row.valueJson, row.updatedAt)
2788
+ );
2789
+ }
2790
+ commit(db);
2791
+ } catch (error) {
2792
+ rollback(db);
2793
+ throw error;
2794
+ }
2795
+ } finally {
2796
+ db.close();
2797
+ }
2798
+ return replacementPath;
2799
+ } catch (error) {
2800
+ await import_node_fs3.promises.rm(replacementPath, { force: true });
2801
+ throw error;
2802
+ }
2803
+ }
2804
+ async function restoreQuarantinedDatabase(dbPath, backupPath) {
2805
+ for (const suffix of ["", "-wal", "-shm"]) {
2806
+ if (!(0, import_node_fs2.existsSync)(`${backupPath}${suffix}`) || (0, import_node_fs2.existsSync)(`${dbPath}${suffix}`)) {
2807
+ continue;
2808
+ }
2809
+ try {
2810
+ await import_node_fs3.promises.rename(`${backupPath}${suffix}`, `${dbPath}${suffix}`);
2811
+ } catch {
2812
+ }
2813
+ }
2814
+ }
2815
+ async function performDatabaseRecovery(dbPath, reason) {
2816
+ const release = await acquireDatabaseFileLock(dbPath, "write");
2817
+ try {
2818
+ if (await probeDatabaseHealth(dbPath) === "healthy") {
2819
+ return;
2820
+ }
2821
+ const salvagedRows = await readSalvageableDocuments(dbPath);
2822
+ const replacementPath = await buildReplacementDatabase(dbPath, salvagedRows);
2823
+ let backup = null;
2824
+ try {
2825
+ backup = await copyDatabaseToQuarantine(dbPath);
2826
+ await installReplacementDatabase(dbPath, replacementPath);
2827
+ } catch (error) {
2828
+ await import_node_fs3.promises.rm(replacementPath, { force: true });
2829
+ if (backup) {
2830
+ await restoreQuarantinedDatabase(dbPath, backup.backupPath);
2831
+ }
2832
+ throw error;
2833
+ }
2834
+ recordRecovery({
2835
+ at: (/* @__PURE__ */ new Date()).toISOString(),
2836
+ scope: "database",
2837
+ dbPath,
2838
+ namespace: null,
2839
+ backupPath: backup.backupPath,
2840
+ reason: `${reason} Salvaged ${salvagedRows.length} document(s).`
2841
+ });
2842
+ await pruneQuarantineCopies({
2843
+ dir: quarantineDirFor(dbPath),
2844
+ key: backup.quarantineKey,
2845
+ extension: ".sqlite",
2846
+ databaseSidecars: true,
2847
+ legacyPrefix: `${safeFileNamePart(import_node_path2.default.basename(dbPath))}-`
2848
+ });
2849
+ } finally {
2850
+ await release();
2385
2851
  }
2386
- return result2;
2387
2852
  }
2388
- function resetAppStorageInitialization(dbPath) {
2389
- initializedDbPaths.delete(dbPath);
2853
+ async function recoverCorruptDatabase(dbPath, reason) {
2854
+ const activeRecovery = databaseRecoveryByDbPath.get(dbPath);
2855
+ if (activeRecovery) {
2856
+ return activeRecovery;
2857
+ }
2858
+ const recovery = performDatabaseRecovery(dbPath, reason);
2859
+ databaseRecoveryByDbPath.set(dbPath, recovery);
2860
+ try {
2861
+ await recovery;
2862
+ } finally {
2863
+ if (databaseRecoveryByDbPath.get(dbPath) === recovery) {
2864
+ databaseRecoveryByDbPath.delete(dbPath);
2865
+ }
2866
+ }
2390
2867
  }
2391
2868
  async function withDatabase(dbPath, task) {
2392
- for (let attempt = 1; attempt <= SQLITE_BUSY_MAX_ATTEMPTS; attempt += 1) {
2869
+ let busyAttempts = 0;
2870
+ let databaseRecovered = false;
2871
+ for (; ; ) {
2393
2872
  let db = null;
2873
+ let releaseFileLock = null;
2874
+ let corruption = null;
2394
2875
  try {
2876
+ releaseFileLock = await acquireDatabaseFileLock(dbPath, "read");
2395
2877
  db = await openDatabase(dbPath);
2396
2878
  applyConnectionPragmas(db);
2397
- ensureSchema(db, dbPath);
2879
+ ensureSchema(db);
2398
2880
  return task(db);
2399
2881
  } catch (error) {
2400
- if (error instanceof AppStorageCorruptionError) {
2882
+ if (isAppStorageCorruptionError(error)) {
2883
+ if (databaseRecovered) {
2884
+ throw error instanceof AppStorageCorruptionError ? error : new AppStorageCorruptionError("App storage database is corrupt.", {
2885
+ dbPath,
2886
+ cause: error
2887
+ });
2888
+ }
2889
+ databaseRecovered = true;
2890
+ corruption = error;
2891
+ } else if (!isSqliteBusyError2(error)) {
2401
2892
  throw error;
2893
+ } else {
2894
+ busyAttempts += 1;
2895
+ if (busyAttempts >= SQLITE_BUSY_MAX_ATTEMPTS) {
2896
+ throw error;
2897
+ }
2402
2898
  }
2403
- if (isSqliteCorruptionError(error)) {
2899
+ } finally {
2900
+ db?.close();
2901
+ await releaseFileLock?.();
2902
+ }
2903
+ if (corruption) {
2904
+ try {
2905
+ await recoverCorruptDatabase(dbPath, describeError(corruption));
2906
+ } catch (error) {
2907
+ if (isSqliteBusyError2(error) || isStorageUnavailableError(error)) {
2908
+ throw error;
2909
+ }
2404
2910
  throw new AppStorageCorruptionError(
2405
- "App storage database is corrupt.",
2911
+ "App storage database is corrupt and could not be moved aside.",
2406
2912
  { dbPath, cause: error }
2407
2913
  );
2408
2914
  }
2409
- if (!isSqliteBusyError(error) || attempt >= SQLITE_BUSY_MAX_ATTEMPTS) {
2915
+ continue;
2916
+ }
2917
+ await sleep(SQLITE_BUSY_RETRY_DELAY_MS * busyAttempts);
2918
+ }
2919
+ }
2920
+ async function withReadOnlyDatabase(dbPath, task) {
2921
+ let busyAttempts = 0;
2922
+ let databaseRecovered = false;
2923
+ for (; ; ) {
2924
+ let db = null;
2925
+ let releaseFileLock = null;
2926
+ let corruption = null;
2927
+ let requiresReadWriteFallback = false;
2928
+ try {
2929
+ try {
2930
+ releaseFileLock = await acquireDatabaseFileLock(dbPath, "read");
2931
+ } catch (error) {
2932
+ if (!isStorageUnavailableError(error)) {
2933
+ throw error;
2934
+ }
2935
+ }
2936
+ db = await openReadOnlyDatabase(dbPath);
2937
+ applyReadConnectionPragmas(db);
2938
+ return task(db);
2939
+ } catch (error) {
2940
+ if (isMissingStorageTableError(error) || isSqliteCantOpenError(error)) {
2941
+ requiresReadWriteFallback = true;
2942
+ } else if (isAppStorageCorruptionError(error)) {
2943
+ if (databaseRecovered) {
2944
+ throw error;
2945
+ }
2946
+ databaseRecovered = true;
2947
+ corruption = error;
2948
+ } else if (!isSqliteBusyError2(error)) {
2410
2949
  throw error;
2950
+ } else {
2951
+ busyAttempts += 1;
2952
+ if (busyAttempts >= SQLITE_BUSY_MAX_ATTEMPTS) {
2953
+ throw error;
2954
+ }
2411
2955
  }
2412
2956
  } finally {
2413
2957
  db?.close();
2958
+ await releaseFileLock?.();
2959
+ }
2960
+ if (requiresReadWriteFallback) {
2961
+ return withDatabase(dbPath, task);
2414
2962
  }
2415
- await sleep(SQLITE_BUSY_RETRY_DELAY_MS * attempt);
2963
+ if (corruption) {
2964
+ await recoverCorruptDatabase(dbPath, describeError(corruption));
2965
+ continue;
2966
+ }
2967
+ await sleep(SQLITE_BUSY_RETRY_DELAY_MS * busyAttempts);
2416
2968
  }
2417
- throw new Error("App storage database remained busy after retrying.");
2969
+ }
2970
+ async function withReadableDatabase(dbPath, task) {
2971
+ return (0, import_node_fs2.existsSync)(dbPath) ? withReadOnlyDatabase(dbPath, task) : withDatabase(dbPath, task);
2418
2972
  }
2419
2973
  function resolveAppStorageDbPath(userDataDir) {
2420
- return import_node_path.default.join(userDataDir, APP_STORAGE_DB_DIR, APP_STORAGE_DB_NAME);
2974
+ return import_node_path2.default.join(userDataDir, APP_STORAGE_DB_DIR, APP_STORAGE_DB_NAME);
2975
+ }
2976
+ function readStrictDocumentRow(input) {
2977
+ const row = withStatement(
2978
+ input.db,
2979
+ `SELECT value_json AS valueJson FROM ${APP_STORAGE_TABLE} WHERE namespace = ?`,
2980
+ (statement) => statement.get(input.namespace)
2981
+ );
2982
+ if (!isRecord(row)) {
2983
+ return { kind: "absent" };
2984
+ }
2985
+ const raw = typeof row.valueJson === "string" ? row.valueJson : null;
2986
+ if (raw === null || raw.trim().length === 0) {
2987
+ return { kind: "damaged", raw, reason: "Stored document is empty." };
2988
+ }
2989
+ let parsed;
2990
+ try {
2991
+ parsed = JSON.parse(raw);
2992
+ } catch (error) {
2993
+ return {
2994
+ kind: "damaged",
2995
+ raw,
2996
+ reason: `Stored document is not valid JSON: ${describeError(error)}`
2997
+ };
2998
+ }
2999
+ try {
3000
+ return { kind: "value", value: input.normalize(parsed) };
3001
+ } catch (error) {
3002
+ return {
3003
+ kind: "damaged",
3004
+ raw,
3005
+ reason: `Stored document failed validation: ${describeError(error)}`
3006
+ };
3007
+ }
2421
3008
  }
2422
3009
  async function readDocument(dbPath, namespace, normalize3) {
2423
- return withDatabase(dbPath, (db) => {
2424
- const row = useStatement(
3010
+ return withReadableDatabase(dbPath, (db) => {
3011
+ const row = withStatement(
2425
3012
  db,
2426
3013
  `SELECT value_json AS valueJson FROM ${APP_STORAGE_TABLE} WHERE namespace = ?`,
2427
3014
  (statement) => statement.get(namespace)
@@ -2434,38 +3021,46 @@ async function readDocument(dbPath, namespace, normalize3) {
2434
3021
  });
2435
3022
  }
2436
3023
  async function readDocumentStrict(dbPath, namespace, normalize3) {
2437
- return withDatabase(dbPath, (db) => {
2438
- const row = useStatement(
2439
- db,
2440
- `SELECT value_json AS valueJson FROM ${APP_STORAGE_TABLE} WHERE namespace = ?`,
2441
- (statement) => statement.get(namespace)
2442
- );
2443
- if (!isRecord(row)) {
2444
- return null;
2445
- }
2446
- const parsed = parseJsonStrict(row.valueJson, {
2447
- dbPath,
2448
- namespace
2449
- });
2450
- if (parsed === null) {
2451
- throw new AppStorageCorruptionError(
2452
- `App storage document ${namespace} is empty.`,
2453
- { dbPath, namespace }
2454
- );
2455
- }
2456
- try {
2457
- return normalize3(parsed);
2458
- } catch (error) {
2459
- throw new AppStorageCorruptionError(
2460
- `App storage document ${namespace} failed normalization.`,
2461
- {
2462
- dbPath,
2463
- namespace,
2464
- cause: error
3024
+ const initialRead = await withReadableDatabase(
3025
+ dbPath,
3026
+ (db) => readStrictDocumentRow({ db, namespace, normalize: normalize3 })
3027
+ );
3028
+ if (initialRead.kind === "value") {
3029
+ return initialRead.value;
3030
+ }
3031
+ if (initialRead.kind === "absent") {
3032
+ return null;
3033
+ }
3034
+ const recovered = await withWriteQueue(
3035
+ dbPath,
3036
+ async () => withDatabase(dbPath, (db) => {
3037
+ let stagedRecovery = null;
3038
+ beginImmediate(db);
3039
+ try {
3040
+ const read = readStrictDocumentRow({ db, namespace, normalize: normalize3 });
3041
+ let value3 = null;
3042
+ if (read.kind === "value") {
3043
+ value3 = read.value;
3044
+ } else if (read.kind === "damaged") {
3045
+ stagedRecovery = stageDamagedDocumentRecovery({
3046
+ db,
3047
+ dbPath,
3048
+ namespace,
3049
+ raw: read.raw,
3050
+ reason: read.reason
3051
+ });
2465
3052
  }
2466
- );
2467
- }
2468
- });
3053
+ commit(db);
3054
+ return { value: value3, stagedRecovery };
3055
+ } catch (error) {
3056
+ rollback(db);
3057
+ discardStagedDocumentRecovery(stagedRecovery);
3058
+ throw error;
3059
+ }
3060
+ })
3061
+ );
3062
+ await finalizeDocumentRecovery(recovered.stagedRecovery);
3063
+ return recovered.value;
2469
3064
  }
2470
3065
  async function writeDocument(dbPath, namespace, value3, options = {}) {
2471
3066
  return withWriteQueue(
@@ -2474,7 +3069,7 @@ async function writeDocument(dbPath, namespace, value3, options = {}) {
2474
3069
  const normalizedValue = options.cloneValue === false ? value3 : clone(value3);
2475
3070
  beginImmediate(db);
2476
3071
  try {
2477
- useStatement(
3072
+ withStatement(
2478
3073
  db,
2479
3074
  `
2480
3075
  INSERT INTO ${APP_STORAGE_TABLE} (namespace, value_json, updated_at)
@@ -2496,36 +3091,42 @@ async function writeDocument(dbPath, namespace, value3, options = {}) {
2496
3091
  );
2497
3092
  }
2498
3093
  async function updateDocument(input) {
2499
- return withWriteQueue(
3094
+ const updated = await withWriteQueue(
2500
3095
  input.dbPath,
2501
3096
  async () => withDatabase(input.dbPath, (db) => {
3097
+ let stagedRecovery = null;
2502
3098
  beginImmediate(db);
2503
3099
  try {
2504
- const row = useStatement(
2505
- db,
2506
- `SELECT value_json AS valueJson FROM ${APP_STORAGE_TABLE} WHERE namespace = ?`,
2507
- (statement) => statement.get(input.namespace)
2508
- );
2509
3100
  let current;
2510
- if (isRecord(row)) {
2511
- const parsed = input.strictExisting ? parseJsonStrict(row.valueJson, {
2512
- dbPath: input.dbPath,
2513
- namespace: input.namespace
2514
- }) : safeParseJson(row.valueJson);
2515
- if (parsed === null && input.strictExisting) {
2516
- throw new AppStorageCorruptionError(
2517
- `App storage document ${input.namespace} is empty.`,
2518
- { dbPath: input.dbPath, namespace: input.namespace }
2519
- );
3101
+ if (input.strictExisting) {
3102
+ const read = readStrictDocumentRow({
3103
+ db,
3104
+ namespace: input.namespace,
3105
+ normalize: input.normalize
3106
+ });
3107
+ if (read.kind === "damaged") {
3108
+ stagedRecovery = stageDamagedDocumentRecovery({
3109
+ db,
3110
+ dbPath: input.dbPath,
3111
+ namespace: input.namespace,
3112
+ raw: read.raw,
3113
+ reason: read.reason
3114
+ });
2520
3115
  }
2521
- current = input.normalize(parsed ?? input.fallback());
3116
+ current = read.kind === "value" ? read.value : input.fallback();
2522
3117
  } else {
2523
- current = input.fallback();
3118
+ const row = withStatement(
3119
+ db,
3120
+ `SELECT value_json AS valueJson FROM ${APP_STORAGE_TABLE} WHERE namespace = ?`,
3121
+ (statement) => statement.get(input.namespace)
3122
+ );
3123
+ const parsed = isRecord(row) ? safeParseJson(row.valueJson) : null;
3124
+ current = input.normalize(parsed ?? input.fallback());
2524
3125
  }
2525
3126
  const transformInput = input.cloneBeforeTransform === false ? current : clone(current);
2526
3127
  const transformed = input.transform(transformInput);
2527
3128
  const next = input.normalizeResult === false ? transformed : input.normalize(transformed);
2528
- useStatement(
3129
+ withStatement(
2529
3130
  db,
2530
3131
  `
2531
3132
  INSERT INTO ${APP_STORAGE_TABLE} (namespace, value_json, updated_at)
@@ -2538,13 +3139,19 @@ async function updateDocument(input) {
2538
3139
  (statement) => statement.run(input.namespace, JSON.stringify(next), (/* @__PURE__ */ new Date()).toISOString())
2539
3140
  );
2540
3141
  commit(db);
2541
- return input.cloneResult === false ? next : clone(next);
3142
+ return {
3143
+ value: input.cloneResult === false ? next : clone(next),
3144
+ stagedRecovery
3145
+ };
2542
3146
  } catch (error) {
2543
3147
  rollback(db);
3148
+ discardStagedDocumentRecovery(stagedRecovery);
2544
3149
  throw error;
2545
3150
  }
2546
3151
  })
2547
3152
  );
3153
+ await finalizeDocumentRecovery(updated.stagedRecovery);
3154
+ return updated.value;
2548
3155
  }
2549
3156
  async function deleteDocument(dbPath, namespace) {
2550
3157
  await withWriteQueue(
@@ -2552,7 +3159,7 @@ async function deleteDocument(dbPath, namespace) {
2552
3159
  async () => withDatabase(dbPath, (db) => {
2553
3160
  beginImmediate(db);
2554
3161
  try {
2555
- useStatement(
3162
+ withStatement(
2556
3163
  db,
2557
3164
  `DELETE FROM ${APP_STORAGE_TABLE} WHERE namespace = ?`,
2558
3165
  (statement) => statement.run(namespace)
@@ -2569,8 +3176,15 @@ async function deleteDocument(dbPath, namespace) {
2569
3176
  // ../../packages/runtime-app-state/src/app/state.ts
2570
3177
  var APP_STATE_DOCUMENT = "desktop.app-state";
2571
3178
  var APP_NAME = "codexuse-desktop";
3179
+ var PERSISTENCE_RETRY_COOLDOWN_MS = 5e3;
3180
+ var PERSISTENCE_READ_DEADLINE_MS = 8e3;
3181
+ var READ_TOO_SLOW = /* @__PURE__ */ Symbol("app-state-read-too-slow");
2572
3182
  var configuredUserDataDir = null;
2573
3183
  var appStateCache = null;
3184
+ var ephemeralAppState = null;
3185
+ var persistenceFailure = null;
3186
+ var pendingRendererUiPatch = null;
3187
+ var nextPersistenceRetryAt = 0;
2574
3188
  var writeLock = Promise.resolve();
2575
3189
  var writeLockContext = new import_node_async_hooks.AsyncLocalStorage();
2576
3190
  function isRecord2(value3) {
@@ -2601,7 +3215,7 @@ function resolveDefaultUserDataDir() {
2601
3215
  if (!home) {
2602
3216
  throw new Error("Unable to resolve home directory for app state.");
2603
3217
  }
2604
- return import_node_path2.default.join(home, "Library", "Application Support", APP_NAME);
3218
+ return import_node_path3.default.join(home, "Library", "Application Support", APP_NAME);
2605
3219
  }
2606
3220
  function getUserDataDir() {
2607
3221
  return configuredUserDataDir ?? resolveDefaultUserDataDir();
@@ -2638,7 +3252,7 @@ function createDefaultAppState() {
2638
3252
  desktopLlmEnabled: false,
2639
3253
  desktopLlmRegistry: {
2640
3254
  version: 3,
2641
- revision: (0, import_node_crypto.createHash)("sha256").update("empty").digest("hex"),
3255
+ revision: (0, import_node_crypto2.createHash)("sha256").update("empty").digest("hex"),
2642
3256
  providers: [],
2643
3257
  routes: [],
2644
3258
  externalProfiles: []
@@ -2933,7 +3547,7 @@ function normalizeOfficialCodexRelayProfile(value3) {
2933
3547
  }
2934
3548
  function migrateDesktopLlmRegistry(profiles) {
2935
3549
  const entries3 = Object.values(profiles).filter((profile) => Boolean(profile.model)).sort((left, right) => left.id.localeCompare(right.id));
2936
- const revision = (0, import_node_crypto.createHash)("sha256").update(
3550
+ const revision = (0, import_node_crypto2.createHash)("sha256").update(
2937
3551
  JSON.stringify(
2938
3552
  entries3.map((profile) => [
2939
3553
  profile.id,
@@ -3257,7 +3871,7 @@ function normalizeDesktopLlmRegistry(value3, profiles) {
3257
3871
  externalProfiles.sort((left, right) => left.updatedAt.localeCompare(right.updatedAt)).map((profile) => [profile.id, profile])
3258
3872
  ).values()
3259
3873
  ).sort((left, right) => left.id.localeCompare(right.id));
3260
- const revision = (0, import_node_crypto.createHash)("sha256").update(
3874
+ const revision = (0, import_node_crypto2.createHash)("sha256").update(
3261
3875
  JSON.stringify({
3262
3876
  providers: providers.map((provider) => ({
3263
3877
  id: provider.id,
@@ -3898,10 +4512,10 @@ function normalizeAppState(raw) {
3898
4512
  ([rootPath, profileName]) => {
3899
4513
  const normalizedRoot = asString(rootPath);
3900
4514
  const normalizedProfile = asString(profileName);
3901
- if (!normalizedRoot || !import_node_path2.default.isAbsolute(normalizedRoot) || !normalizedProfile) {
4515
+ if (!normalizedRoot || !import_node_path3.default.isAbsolute(normalizedRoot) || !normalizedProfile) {
3902
4516
  return [];
3903
4517
  }
3904
- return [[import_node_path2.default.normalize(normalizedRoot), normalizedProfile]];
4518
+ return [[import_node_path3.default.normalize(normalizedRoot), normalizedProfile]];
3905
4519
  }
3906
4520
  )
3907
4521
  );
@@ -3942,22 +4556,85 @@ async function readAppStateFromStorage() {
3942
4556
  normalizeAppState
3943
4557
  );
3944
4558
  }
3945
- async function ensureInitialized() {
3946
- if (appStateCache) {
3947
- return appStateCache;
4559
+ async function readStoredAppStateOrNull() {
4560
+ try {
4561
+ return await readStoredAppStateForInit();
4562
+ } catch (error) {
4563
+ persistenceFailure = {
4564
+ kind: classifyAppStorageFailure(error),
4565
+ message: error instanceof Error ? error.message : String(error)
4566
+ };
4567
+ nextPersistenceRetryAt = Date.now() + PERSISTENCE_RETRY_COOLDOWN_MS;
4568
+ return null;
3948
4569
  }
3949
- const stored = await updateDocument({
4570
+ }
4571
+ async function readStoredAppStateForInit() {
4572
+ const stored = await readAppStateFromStorage();
4573
+ if (stored && !pendingRendererUiPatch) {
4574
+ return stored;
4575
+ }
4576
+ const pendingUiPatch = pendingRendererUiPatch;
4577
+ const initialized = await updateDocument({
3950
4578
  dbPath: resolveStorageDbPath(),
3951
4579
  namespace: APP_STATE_DOCUMENT,
3952
4580
  normalize: normalizeAppState,
3953
4581
  fallback: () => normalizeAppState(null),
3954
- transform: (current) => current,
4582
+ transform: (current) => pendingUiPatch ? deepMerge(current, { ui: pendingUiPatch }) : current,
3955
4583
  cloneBeforeTransform: false,
3956
4584
  cloneResult: false,
3957
4585
  strictExisting: true
3958
4586
  });
3959
- appStateCache = freezeDeep(stored);
3960
- return appStateCache;
4587
+ if (pendingRendererUiPatch === pendingUiPatch) {
4588
+ pendingRendererUiPatch = null;
4589
+ }
4590
+ return initialized;
4591
+ }
4592
+ function degradeToMemory(kind, message) {
4593
+ persistenceFailure = { kind, message };
4594
+ nextPersistenceRetryAt = Date.now() + PERSISTENCE_RETRY_COOLDOWN_MS;
4595
+ if (appStateCache) {
4596
+ return appStateCache;
4597
+ }
4598
+ ephemeralAppState = ephemeralAppState ?? freezeDeep(normalizeAppState(null));
4599
+ return ephemeralAppState;
4600
+ }
4601
+ async function ensureInitialized() {
4602
+ if (appStateCache && !persistenceFailure) {
4603
+ return appStateCache;
4604
+ }
4605
+ const memoryState = appStateCache ?? ephemeralAppState;
4606
+ if (memoryState && Date.now() < nextPersistenceRetryAt) {
4607
+ return memoryState;
4608
+ }
4609
+ const attempt = readStoredAppStateForInit();
4610
+ attempt.catch(() => void 0);
4611
+ let deadlineTimer;
4612
+ const deadline = new Promise((resolve2) => {
4613
+ deadlineTimer = setTimeout(
4614
+ () => resolve2(READ_TOO_SLOW),
4615
+ PERSISTENCE_READ_DEADLINE_MS
4616
+ );
4617
+ });
4618
+ try {
4619
+ const outcome = await Promise.race([attempt, deadline]);
4620
+ if (outcome === READ_TOO_SLOW) {
4621
+ return degradeToMemory(
4622
+ "busy",
4623
+ `Saved app state did not load within ${PERSISTENCE_READ_DEADLINE_MS}ms.`
4624
+ );
4625
+ }
4626
+ appStateCache = freezeDeep(outcome);
4627
+ ephemeralAppState = null;
4628
+ persistenceFailure = null;
4629
+ return appStateCache;
4630
+ } catch (error) {
4631
+ return degradeToMemory(
4632
+ classifyAppStorageFailure(error),
4633
+ error instanceof Error ? error.message : String(error)
4634
+ );
4635
+ } finally {
4636
+ clearTimeout(deadlineTimer);
4637
+ }
3961
4638
  }
3962
4639
  async function withWriteLock(task) {
3963
4640
  if (writeLockContext.getStore()) {
@@ -3981,7 +4658,10 @@ async function initializeAppState(userDataDir) {
3981
4658
  if (configuredUserDataDir !== userDataDir) {
3982
4659
  configuredUserDataDir = userDataDir;
3983
4660
  appStateCache = null;
3984
- resetAppStorageInitialization(resolveStorageDbPath());
4661
+ ephemeralAppState = null;
4662
+ persistenceFailure = null;
4663
+ pendingRendererUiPatch = null;
4664
+ nextPersistenceRetryAt = 0;
3985
4665
  }
3986
4666
  const state = await ensureInitialized();
3987
4667
  return state;
@@ -3992,8 +4672,13 @@ async function getAppState() {
3992
4672
  }
3993
4673
  async function refreshAppStateCache() {
3994
4674
  return withWriteLock(async () => {
3995
- const current = await readAppStateFromStorage() ?? await ensureInitialized();
3996
- appStateCache = freezeDeep(current);
4675
+ const stored = await readStoredAppStateOrNull();
4676
+ if (!stored) {
4677
+ return ensureInitialized();
4678
+ }
4679
+ appStateCache = freezeDeep(stored);
4680
+ ephemeralAppState = null;
4681
+ persistenceFailure = null;
3997
4682
  return appStateCache;
3998
4683
  });
3999
4684
  }
@@ -4001,24 +4686,40 @@ async function updateAppState(transform3, options = {}) {
4001
4686
  const mode = options.mode ?? "patch";
4002
4687
  return withWriteLock(async () => {
4003
4688
  const shouldNormalize = options.normalize !== false;
4004
- const stored = await updateDocument({
4005
- dbPath: resolveStorageDbPath(),
4006
- namespace: APP_STATE_DOCUMENT,
4007
- normalize: normalizeAppState,
4008
- fallback: () => normalizeAppState(null),
4009
- cloneBeforeTransform: false,
4010
- normalizeResult: shouldNormalize,
4011
- cloneResult: false,
4012
- strictExisting: true,
4013
- transform: (current) => {
4014
- const transformed = transform3(
4015
- options.cloneCurrent === false ? current : clone2(current)
4016
- );
4017
- return mode === "replace" ? transformed : deepMerge(current, transformed);
4689
+ const pendingUiPatch = pendingRendererUiPatch;
4690
+ try {
4691
+ const stored = await updateDocument({
4692
+ dbPath: resolveStorageDbPath(),
4693
+ namespace: APP_STATE_DOCUMENT,
4694
+ normalize: normalizeAppState,
4695
+ fallback: () => normalizeAppState(null),
4696
+ cloneBeforeTransform: false,
4697
+ normalizeResult: shouldNormalize,
4698
+ cloneResult: false,
4699
+ strictExisting: true,
4700
+ transform: (current) => {
4701
+ const transformed = transform3(
4702
+ options.cloneCurrent === false ? current : clone2(current)
4703
+ );
4704
+ const next = mode === "replace" ? transformed : deepMerge(current, transformed);
4705
+ return pendingUiPatch ? deepMerge(next, { ui: pendingUiPatch }) : next;
4706
+ }
4707
+ });
4708
+ if (pendingRendererUiPatch === pendingUiPatch) {
4709
+ pendingRendererUiPatch = null;
4018
4710
  }
4019
- });
4020
- appStateCache = freezeDeep(stored);
4021
- return appStateCache;
4711
+ appStateCache = freezeDeep(stored);
4712
+ ephemeralAppState = null;
4713
+ persistenceFailure = null;
4714
+ return appStateCache;
4715
+ } catch (error) {
4716
+ persistenceFailure = {
4717
+ kind: classifyAppStorageFailure(error),
4718
+ message: error instanceof Error ? error.message : String(error)
4719
+ };
4720
+ nextPersistenceRetryAt = Date.now() + PERSISTENCE_RETRY_COOLDOWN_MS;
4721
+ throw error;
4722
+ }
4022
4723
  });
4023
4724
  }
4024
4725
  async function patchAppState(patch) {
@@ -4131,7 +4832,7 @@ async function updateAppSettings(transform3, onUpdated) {
4131
4832
  }
4132
4833
 
4133
4834
  // ../../packages/runtime-profiles/src/license/service.ts
4134
- var import_node_crypto6 = __toESM(require("crypto"), 1);
4835
+ var import_node_crypto7 = __toESM(require("crypto"), 1);
4135
4836
 
4136
4837
  // ../../packages/runtime-codex/src/codex/settings.ts
4137
4838
  function asString2(value3) {
@@ -4370,10 +5071,10 @@ async function writeCodexSettingsJsonRaw(payload) {
4370
5071
  }
4371
5072
 
4372
5073
  // ../../packages/runtime-profiles/src/license/secret.ts
4373
- var import_node_crypto2 = __toESM(require("crypto"), 1);
5074
+ var import_node_crypto3 = __toESM(require("crypto"), 1);
4374
5075
  var LICENSE_SECRET_DOCUMENT = "desktop.license-secret";
4375
5076
  async function generateSecret() {
4376
- return import_node_crypto2.default.randomBytes(32).toString("hex");
5077
+ return import_node_crypto3.default.randomBytes(32).toString("hex");
4377
5078
  }
4378
5079
  function normalizeSecret(value3) {
4379
5080
  return typeof value3 === "string" ? value3.trim() : "";
@@ -4434,10 +5135,10 @@ function buildCheckoutUrl(offer2, options) {
4434
5135
  }
4435
5136
 
4436
5137
  // ../../packages/runtime-profiles/src/license/trial.ts
4437
- var import_node_crypto5 = __toESM(require("crypto"), 1);
5138
+ var import_node_crypto6 = __toESM(require("crypto"), 1);
4438
5139
 
4439
5140
  // ../../packages/runtime-profiles/src/license/device-id.ts
4440
- var import_node_crypto3 = __toESM(require("crypto"), 1);
5141
+ var import_node_crypto4 = __toESM(require("crypto"), 1);
4441
5142
  var import_promises = require("fs/promises");
4442
5143
  var import_node_child_process = require("child_process");
4443
5144
  var import_node_util = require("util");
@@ -4480,7 +5181,7 @@ async function readLinuxMachineId() {
4480
5181
  return null;
4481
5182
  }
4482
5183
  function hashDeviceComponent(value3) {
4483
- return import_node_crypto3.default.createHash("sha256").update(`codexuse-device:${value3}`).digest("hex");
5184
+ return import_node_crypto4.default.createHash("sha256").update(`codexuse-device:${value3}`).digest("hex");
4484
5185
  }
4485
5186
  async function getDeviceId() {
4486
5187
  if (memoizedDeviceId) {
@@ -4501,7 +5202,7 @@ async function getDeviceId() {
4501
5202
  memoizedDeviceId = cached2;
4502
5203
  return cached2;
4503
5204
  }
4504
- const seed = import_node_crypto3.default.randomBytes(32).toString("hex");
5205
+ const seed = import_node_crypto4.default.randomBytes(32).toString("hex");
4505
5206
  const deviceId = hashDeviceComponent(seed);
4506
5207
  await writeDocument(dbPath, DEVICE_ID_DOCUMENT, deviceId);
4507
5208
  memoizedDeviceId = deviceId;
@@ -4512,7 +5213,7 @@ function hashEmail(email) {
4512
5213
  if (!normalized) {
4513
5214
  return null;
4514
5215
  }
4515
- return import_node_crypto3.default.createHash("sha256").update(`codexuse-email:${normalized}`).digest("hex");
5216
+ return import_node_crypto4.default.createHash("sha256").update(`codexuse-email:${normalized}`).digest("hex");
4516
5217
  }
4517
5218
 
4518
5219
  // ../../packages/runtime-profiles/src/license/trial-client.ts
@@ -4567,17 +5268,17 @@ async function registerTrialWithServer(input) {
4567
5268
  }
4568
5269
 
4569
5270
  // ../../packages/runtime-profiles/src/license/trial-token-store.ts
4570
- var import_node_crypto4 = require("crypto");
5271
+ var import_node_crypto5 = require("crypto");
4571
5272
  var import_node_child_process2 = require("child_process");
4572
5273
  var KEYCHAIN_SERVICE = "CODEXUSE_TRIAL_TOKEN";
4573
5274
  var KEYCHAIN_ACCOUNT_PREFIX = "device-sha256:";
4574
5275
  var FALLBACK_DOCUMENT_PREFIX = "desktop.trial-token.";
4575
5276
  function keychainAccountForDevice(deviceId) {
4576
- const digest = (0, import_node_crypto4.createHash)("sha256").update(deviceId).digest("hex");
5277
+ const digest = (0, import_node_crypto5.createHash)("sha256").update(deviceId).digest("hex");
4577
5278
  return KEYCHAIN_ACCOUNT_PREFIX + digest;
4578
5279
  }
4579
5280
  function fallbackDocumentForDevice(deviceId) {
4580
- const digest = (0, import_node_crypto4.createHash)("sha256").update(deviceId).digest("hex");
5281
+ const digest = (0, import_node_crypto5.createHash)("sha256").update(deviceId).digest("hex");
4581
5282
  return FALLBACK_DOCUMENT_PREFIX + digest;
4582
5283
  }
4583
5284
  function normalizeToken(value3) {
@@ -4681,7 +5382,7 @@ function trialSignaturePayload(trial) {
4681
5382
  });
4682
5383
  }
4683
5384
  function signTrial(trial, secret) {
4684
- return import_node_crypto5.default.createHmac("sha256", secret).update(trialSignaturePayload(trial)).digest("hex");
5385
+ return import_node_crypto6.default.createHmac("sha256", secret).update(trialSignaturePayload(trial)).digest("hex");
4685
5386
  }
4686
5387
  function withTrialSignature(trial, secret) {
4687
5388
  return { ...trial, signature: signTrial(trial, secret) };
@@ -4995,7 +5696,7 @@ function licenseSignaturePayload(license) {
4995
5696
  return JSON.stringify(payload);
4996
5697
  }
4997
5698
  function signLicense(license, secret) {
4998
- return import_node_crypto6.default.createHmac("sha256", secret).update(licenseSignaturePayload(license)).digest("hex");
5699
+ return import_node_crypto7.default.createHmac("sha256", secret).update(licenseSignaturePayload(license)).digest("hex");
4999
5700
  }
5000
5701
  function withSignature(license, secret) {
5001
5702
  return {
@@ -5303,7 +6004,7 @@ var LicenseService = class {
5303
6004
  throw new Error("License key is required.");
5304
6005
  }
5305
6006
  const secret = await getLicenseSecret();
5306
- const digest = import_node_crypto6.default.createHash("sha256").update(trimmed).digest("hex");
6007
+ const digest = import_node_crypto7.default.createHash("sha256").update(trimmed).digest("hex");
5307
6008
  const result2 = await requestGumroadVerify(trimmed, "activation");
5308
6009
  ensureWithinUseLimit(result2);
5309
6010
  const normalized = normalizeVerificationResult(result2, "activation");
@@ -5366,7 +6067,7 @@ function shouldEnforceProfileLimit(status) {
5366
6067
  }
5367
6068
 
5368
6069
  // ../../packages/runtime-profiles/src/profiles/profile-manager.ts
5369
- var import_node_crypto11 = require("crypto");
6070
+ var import_node_crypto12 = require("crypto");
5370
6071
  var import_fs = require("fs");
5371
6072
  var import_node_os5 = __toESM(require("os"), 1);
5372
6073
  var import_path = __toESM(require("path"), 1);
@@ -5425,29 +6126,29 @@ function resolveProfileIdentityKeyFromProfile(profile) {
5425
6126
 
5426
6127
  // ../../packages/runtime-codex/src/codex/rpc.ts
5427
6128
  var import_node_child_process5 = require("child_process");
5428
- var import_node_crypto8 = require("crypto");
6129
+ var import_node_crypto9 = require("crypto");
5429
6130
  var import_node_readline = __toESM(require("readline"), 1);
5430
- var import_node_fs5 = require("fs");
6131
+ var import_node_fs6 = require("fs");
5431
6132
  var import_node_os3 = __toESM(require("os"), 1);
5432
6133
  var import_node_path9 = __toESM(require("path"), 1);
5433
6134
 
5434
6135
  // ../../packages/runtime-codex/src/codex/cli.ts
5435
- var import_node_fs2 = require("fs");
5436
- var import_node_path3 = __toESM(require("path"), 1);
6136
+ var import_node_fs4 = require("fs");
6137
+ var import_node_path4 = __toESM(require("path"), 1);
5437
6138
  var STABLE_CHANNEL = "stable";
5438
6139
  var ENV_HINTS = ["CODEX_BINARY", "CODEX_CLI_PATH", "CODEX_PATH"];
5439
6140
  var cachedStatus = null;
5440
6141
  function getPathHintEntries() {
5441
6142
  const homeDir = process.env.HOME ?? "";
5442
6143
  const homeEntries = homeDir ? [
5443
- import_node_path3.default.join(homeDir, ".local", "bin"),
5444
- import_node_path3.default.join(homeDir, ".fnm", "aliases", "default", "bin"),
5445
- import_node_path3.default.join(homeDir, ".fnm", "current", "bin"),
5446
- import_node_path3.default.join(homeDir, ".volta", "bin"),
5447
- import_node_path3.default.join(homeDir, ".asdf", "shims"),
5448
- import_node_path3.default.join(homeDir, ".bun", "bin")
6144
+ import_node_path4.default.join(homeDir, ".local", "bin"),
6145
+ import_node_path4.default.join(homeDir, ".fnm", "aliases", "default", "bin"),
6146
+ import_node_path4.default.join(homeDir, ".fnm", "current", "bin"),
6147
+ import_node_path4.default.join(homeDir, ".volta", "bin"),
6148
+ import_node_path4.default.join(homeDir, ".asdf", "shims"),
6149
+ import_node_path4.default.join(homeDir, ".bun", "bin")
5449
6150
  ] : [];
5450
- const configuredHints = (process.env.CODEX_PATH_HINTS ?? "").split(import_node_path3.default.delimiter).map((entry) => entry.trim()).filter(Boolean);
6151
+ const configuredHints = (process.env.CODEX_PATH_HINTS ?? "").split(import_node_path4.default.delimiter).map((entry) => entry.trim()).filter(Boolean);
5451
6152
  return [
5452
6153
  "/opt/homebrew/bin",
5453
6154
  "/usr/local/bin",
@@ -5459,9 +6160,9 @@ function fileExists(candidate) {
5459
6160
  if (!candidate) {
5460
6161
  return null;
5461
6162
  }
5462
- const normalized = import_node_path3.default.resolve(candidate);
6163
+ const normalized = import_node_path4.default.resolve(candidate);
5463
6164
  try {
5464
- const stats = (0, import_node_fs2.statSync)(normalized);
6165
+ const stats = (0, import_node_fs4.statSync)(normalized);
5465
6166
  if (stats.isFile()) {
5466
6167
  return normalized;
5467
6168
  }
@@ -5488,12 +6189,12 @@ function resolveCodexFromPath() {
5488
6189
  new Set(
5489
6190
  [
5490
6191
  ...getPathHintEntries(),
5491
- ...pathValue.split(import_node_path3.default.delimiter).map((entry) => entry.trim()).filter(Boolean)
6192
+ ...pathValue.split(import_node_path4.default.delimiter).map((entry) => entry.trim()).filter(Boolean)
5492
6193
  ].filter(Boolean)
5493
6194
  )
5494
6195
  );
5495
6196
  for (const entry of entries3) {
5496
- const candidate = fileExists(import_node_path3.default.join(entry, "codex"));
6197
+ const candidate = fileExists(import_node_path4.default.join(entry, "codex"));
5497
6198
  if (candidate) {
5498
6199
  return candidate;
5499
6200
  }
@@ -5557,7 +6258,7 @@ async function requireCodexCli() {
5557
6258
 
5558
6259
  // ../../packages/runtime-codex/src/codex/command.ts
5559
6260
  var import_node_child_process3 = require("child_process");
5560
- var import_node_path4 = __toESM(require("path"), 1);
6261
+ var import_node_path5 = __toESM(require("path"), 1);
5561
6262
  var cachedNodeRuntime = null;
5562
6263
  function isJavaScriptEntrypoint(binaryPath) {
5563
6264
  const normalized = binaryPath.trim().toLowerCase();
@@ -5573,19 +6274,19 @@ function resolveNodeRuntime(env) {
5573
6274
  }
5574
6275
  const runtimeEnv = { ...process.env, ...env };
5575
6276
  const homeDir = runtimeEnv.HOME ?? "";
5576
- const pathHints = (runtimeEnv.CODEX_PATH_HINTS ?? process.env.CODEX_PATH_HINTS ?? "").split(import_node_path4.default.delimiter).map((entry) => entry.trim()).filter(Boolean);
6277
+ const pathHints = (runtimeEnv.CODEX_PATH_HINTS ?? process.env.CODEX_PATH_HINTS ?? "").split(import_node_path5.default.delimiter).map((entry) => entry.trim()).filter(Boolean);
5577
6278
  const extraPathEntries = [
5578
6279
  "/usr/local/bin",
5579
6280
  "/opt/homebrew/bin",
5580
- import_node_path4.default.join(homeDir, ".local", "bin"),
5581
- import_node_path4.default.join(homeDir, ".fnm", "aliases", "default", "bin"),
5582
- import_node_path4.default.join(homeDir, ".fnm", "current", "bin"),
6281
+ import_node_path5.default.join(homeDir, ".local", "bin"),
6282
+ import_node_path5.default.join(homeDir, ".fnm", "aliases", "default", "bin"),
6283
+ import_node_path5.default.join(homeDir, ".fnm", "current", "bin"),
5583
6284
  ...pathHints
5584
6285
  ].filter(Boolean);
5585
6286
  const currentPath = runtimeEnv.PATH ?? "";
5586
6287
  runtimeEnv.PATH = Array.from(
5587
- /* @__PURE__ */ new Set([...extraPathEntries, ...currentPath.split(import_node_path4.default.delimiter).filter(Boolean)])
5588
- ).join(import_node_path4.default.delimiter);
6288
+ /* @__PURE__ */ new Set([...extraPathEntries, ...currentPath.split(import_node_path5.default.delimiter).filter(Boolean)])
6289
+ ).join(import_node_path5.default.delimiter);
5589
6290
  const candidates = Array.from(
5590
6291
  new Set(
5591
6292
  [
@@ -5624,11 +6325,11 @@ function buildCodexCommand(binaryPath, args2, env) {
5624
6325
  }
5625
6326
 
5626
6327
  // ../../packages/runtime-codex/src/codex/home.ts
5627
- var import_node_crypto7 = require("crypto");
5628
- var import_node_fs3 = require("fs");
6328
+ var import_node_crypto8 = require("crypto");
6329
+ var import_node_fs5 = require("fs");
5629
6330
  var import_promises2 = require("fs/promises");
5630
6331
  var import_node_os2 = __toESM(require("os"), 1);
5631
- var import_node_path5 = __toESM(require("path"), 1);
6332
+ var import_node_path6 = __toESM(require("path"), 1);
5632
6333
  function resolveHomeDir() {
5633
6334
  return process.env.HOME || import_node_os2.default.homedir();
5634
6335
  }
@@ -5637,7 +6338,7 @@ function expandHomePrefix(input, homeDir) {
5637
6338
  return homeDir;
5638
6339
  }
5639
6340
  if (input.startsWith("~/") || input.startsWith("~\\")) {
5640
- return import_node_path5.default.join(homeDir, input.slice(2));
6341
+ return import_node_path6.default.join(homeDir, input.slice(2));
5641
6342
  }
5642
6343
  return input;
5643
6344
  }
@@ -5653,25 +6354,25 @@ function normalizeCodexHomePath(input) {
5653
6354
  if (!configured) {
5654
6355
  return null;
5655
6356
  }
5656
- return import_node_path5.default.resolve(expandHomePrefix(configured, resolveHomeDir()));
6357
+ return import_node_path6.default.resolve(expandHomePrefix(configured, resolveHomeDir()));
5657
6358
  }
5658
6359
  function resolveDefaultCodexHomeDir() {
5659
- return normalizeCodexHomePath(process.env.CODEX_HOME) ?? import_node_path5.default.join(resolveHomeDir(), ".codex");
6360
+ return normalizeCodexHomePath(process.env.CODEX_HOME) ?? import_node_path6.default.join(resolveHomeDir(), ".codex");
5660
6361
  }
5661
6362
  function resolveCodexSqliteHomeDir(codexHomePath) {
5662
6363
  return normalizeCodexHomePath(process.env.CODEX_SQLITE_HOME) ?? resolveCodexHomeDir({ codexHomePath });
5663
6364
  }
5664
6365
  function resolveCurrentProfileCodexHomeDir(profileHomeId) {
5665
- return import_node_path5.default.join(
6366
+ return import_node_path6.default.join(
5666
6367
  resolveProfileCodexHomesRoot(),
5667
- (0, import_node_crypto7.createHash)("sha256").update(profileHomeId).digest("hex").slice(0, 20)
6368
+ (0, import_node_crypto8.createHash)("sha256").update(profileHomeId).digest("hex").slice(0, 20)
5668
6369
  );
5669
6370
  }
5670
6371
  function resolveProfileCodexHomeDir(profileHomeId) {
5671
6372
  const current = resolveCurrentProfileCodexHomeDir(profileHomeId);
5672
- const legacy = import_node_path5.default.join(resolveLegacyProfileCodexHomesRoot(), profileHomeId);
5673
- const currentExists = (0, import_node_fs3.existsSync)(current);
5674
- const legacyExists = (0, import_node_fs3.existsSync)(legacy);
6373
+ const legacy = import_node_path6.default.join(resolveLegacyProfileCodexHomesRoot(), profileHomeId);
6374
+ const currentExists = (0, import_node_fs5.existsSync)(current);
6375
+ const legacyExists = (0, import_node_fs5.existsSync)(legacy);
5675
6376
  if (currentExists && legacyExists) {
5676
6377
  return current;
5677
6378
  }
@@ -5679,15 +6380,15 @@ function resolveProfileCodexHomeDir(profileHomeId) {
5679
6380
  }
5680
6381
  function findProfileCodexHomeLocationConflict(profileHomeId) {
5681
6382
  const current = resolveCurrentProfileCodexHomeDir(profileHomeId);
5682
- const legacy = import_node_path5.default.join(resolveLegacyProfileCodexHomesRoot(), profileHomeId);
5683
- return (0, import_node_fs3.existsSync)(current) && (0, import_node_fs3.existsSync)(legacy) ? { current, legacy } : null;
6383
+ const legacy = import_node_path6.default.join(resolveLegacyProfileCodexHomesRoot(), profileHomeId);
6384
+ return (0, import_node_fs5.existsSync)(current) && (0, import_node_fs5.existsSync)(legacy) ? { current, legacy } : null;
5684
6385
  }
5685
6386
  function resolveProfileCodexHomesRoot() {
5686
- return import_node_path5.default.join(resolveHomeDir(), ".codexuse", "p");
6387
+ return import_node_path6.default.join(resolveHomeDir(), ".codexuse", "p");
5687
6388
  }
5688
6389
  async function ensureProfileCodexHomesRoot() {
5689
6390
  const root = resolveProfileCodexHomesRoot();
5690
- const parent = import_node_path5.default.dirname(root);
6391
+ const parent = import_node_path6.default.dirname(root);
5691
6392
  await (0, import_promises2.mkdir)(parent, { recursive: true, mode: 448 });
5692
6393
  await (0, import_promises2.mkdir)(root, { recursive: true, mode: 448 });
5693
6394
  if (process.platform !== "win32") {
@@ -5697,13 +6398,13 @@ async function ensureProfileCodexHomesRoot() {
5697
6398
  return root;
5698
6399
  }
5699
6400
  function resolveLegacyProfileCodexHomesRoot() {
5700
- return import_node_path5.default.join(getUserDataDir(), "profile-homes");
6401
+ return import_node_path6.default.join(getUserDataDir(), "profile-homes");
5701
6402
  }
5702
6403
  async function migrateProfileCodexHomeDir(profileHomeId) {
5703
- const legacy = import_node_path5.default.join(resolveLegacyProfileCodexHomesRoot(), profileHomeId);
6404
+ const legacy = import_node_path6.default.join(resolveLegacyProfileCodexHomesRoot(), profileHomeId);
5704
6405
  const current = resolveCurrentProfileCodexHomeDir(profileHomeId);
5705
- const currentExists = (0, import_node_fs3.existsSync)(current);
5706
- const legacyExists = (0, import_node_fs3.existsSync)(legacy);
6406
+ const currentExists = (0, import_node_fs5.existsSync)(current);
6407
+ const legacyExists = (0, import_node_fs5.existsSync)(legacy);
5707
6408
  if (currentExists && legacyExists) {
5708
6409
  return current;
5709
6410
  }
@@ -5779,7 +6480,7 @@ var import_toml = __toESM(require_toml(), 1);
5779
6480
  // ../../packages/runtime-codex/src/codex/config-metadata.ts
5780
6481
  var import_node_child_process4 = require("child_process");
5781
6482
  var import_promises3 = require("fs/promises");
5782
- var import_node_path6 = __toESM(require("path"), 1);
6483
+ var import_node_path7 = __toESM(require("path"), 1);
5783
6484
  var CONFIG_SCHEMA_URL = "https://raw.githubusercontent.com/openai/codex/main/codex-rs/core/config.schema.json";
5784
6485
  var METADATA_CACHE_TTL_MS = 6e4;
5785
6486
  var FALLBACK_SCHEMA_TOP_LEVEL_KEYS = [
@@ -5965,8 +6666,8 @@ function parseSchemaKeys(schemaRaw) {
5965
6666
  async function readSchemaFromLocal() {
5966
6667
  const candidates = [
5967
6668
  process.env.CODEX_CONFIG_SCHEMA_PATH,
5968
- import_node_path6.default.join(process.cwd(), "codex-rs", "core", "config.schema.json"),
5969
- import_node_path6.default.join(process.cwd(), "node_modules", "@openai", "codex", "codex-rs", "core", "config.schema.json")
6669
+ import_node_path7.default.join(process.cwd(), "codex-rs", "core", "config.schema.json"),
6670
+ import_node_path7.default.join(process.cwd(), "node_modules", "@openai", "codex", "codex-rs", "core", "config.schema.json")
5970
6671
  ].filter((candidate) => Boolean(candidate));
5971
6672
  for (const candidate of candidates) {
5972
6673
  try {
@@ -6071,7 +6772,7 @@ async function getCodexConfigMetadata(forceRefresh = false) {
6071
6772
 
6072
6773
  // ../../packages/runtime-codex/src/codex/config-io.ts
6073
6774
  var import_promises4 = require("fs/promises");
6074
- var import_node_path7 = __toESM(require("path"), 1);
6775
+ var import_node_path8 = __toESM(require("path"), 1);
6075
6776
 
6076
6777
  // ../../packages/runtime-codex/src/codex/config-presets.ts
6077
6778
  var DEFAULT_CONFIG_TEMPLATE = [
@@ -6114,10 +6815,10 @@ var YOLO_PRESET = {
6114
6815
 
6115
6816
  // ../../packages/runtime-codex/src/codex/config-io.ts
6116
6817
  function getConfigPath(options) {
6117
- return import_node_path7.default.join(resolveCodexHomeDir(options), "config.toml");
6818
+ return import_node_path8.default.join(resolveCodexHomeDir(options), "config.toml");
6118
6819
  }
6119
6820
  async function ensureConfigDirExists(filePath) {
6120
- const dir = import_node_path7.default.dirname(filePath);
6821
+ const dir = import_node_path8.default.dirname(filePath);
6121
6822
  await (0, import_promises4.mkdir)(dir, { recursive: true });
6122
6823
  }
6123
6824
  function normalizeLineEndings(content) {
@@ -6675,82 +7376,6 @@ async function saveCodexConfigContent(content, options) {
6675
7376
  return buildSnapshot(normalized, true, options);
6676
7377
  }
6677
7378
 
6678
- // ../../packages/runtime-app-state/src/storage/fileLock.ts
6679
- var import_node_fs4 = require("fs");
6680
- var import_node_path8 = __toESM(require("path"), 1);
6681
- function isSqliteBusyError2(error) {
6682
- if (!error || typeof error !== "object") {
6683
- return false;
6684
- }
6685
- const value3 = error;
6686
- if (value3.cause && value3.cause !== error && isSqliteBusyError2(value3.cause)) {
6687
- return true;
6688
- }
6689
- if (value3.error && value3.error !== error && isSqliteBusyError2(value3.error)) {
6690
- return true;
6691
- }
6692
- const message = typeof value3.message === "string" ? value3.message.toLowerCase() : String(error).toLowerCase();
6693
- return value3.code === "SQLITE_BUSY" || value3.errno === 5 || message.includes("sqlite_busy") || message.includes("database is locked");
6694
- }
6695
- async function openLockDatabase(databasePath) {
6696
- await import_node_fs4.promises.mkdir(import_node_path8.default.dirname(databasePath), { recursive: true, mode: 448 });
6697
- const sqlite = process.versions.bun ? await Function("return import('bun:sqlite')")() : await Function("return import('node:sqlite')")();
6698
- const database = process.versions.bun ? new sqlite.Database(databasePath) : new sqlite.DatabaseSync(databasePath);
6699
- try {
6700
- if (process.platform !== "win32") {
6701
- await import_node_fs4.promises.chmod(databasePath, 384);
6702
- }
6703
- return {
6704
- exec: database.exec.bind(database),
6705
- close: database.close.bind(database)
6706
- };
6707
- } catch (error) {
6708
- database.close();
6709
- throw error;
6710
- }
6711
- }
6712
- async function acquireCrossProcessFileLockTransaction(filePath, mode) {
6713
- const databasePath = `${import_node_path8.default.resolve(filePath)}.codexuse-lock.sqlite`;
6714
- let database = null;
6715
- try {
6716
- database = await openLockDatabase(databasePath);
6717
- database.exec("PRAGMA busy_timeout = 1000;");
6718
- database.exec("CREATE TABLE IF NOT EXISTS codexuse_file_lock (id INTEGER PRIMARY KEY);");
6719
- database.exec("PRAGMA busy_timeout = 0;");
6720
- if (mode === "write") {
6721
- database.exec("BEGIN EXCLUSIVE;");
6722
- } else {
6723
- database.exec("BEGIN;");
6724
- database.exec("SELECT COUNT(*) FROM codexuse_file_lock;");
6725
- }
6726
- } catch (error) {
6727
- database?.close();
6728
- if (isSqliteBusyError2(error)) {
6729
- return null;
6730
- }
6731
- throw error;
6732
- }
6733
- const acquiredDatabase = database;
6734
- let released = false;
6735
- return async () => {
6736
- if (released) {
6737
- return;
6738
- }
6739
- released = true;
6740
- try {
6741
- acquiredDatabase.exec("ROLLBACK;");
6742
- } finally {
6743
- acquiredDatabase.close();
6744
- }
6745
- };
6746
- }
6747
- async function acquireCrossProcessFileLock(filePath) {
6748
- return acquireCrossProcessFileLockTransaction(filePath, "write");
6749
- }
6750
- async function acquireCrossProcessFileReadLock(filePath) {
6751
- return acquireCrossProcessFileLockTransaction(filePath, "read");
6752
- }
6753
-
6754
7379
  // ../../packages/shared/src/core/logger.ts
6755
7380
  var isTestEnv = process.env.NODE_ENV === "test" || process.env.VITEST === "true" || process.env.VITEST === "1";
6756
7381
  function isMocked(fn2) {
@@ -23535,11 +24160,11 @@ function authWritebackPaths(filePath) {
23535
24160
  };
23536
24161
  }
23537
24162
  function fingerprintAuth(content) {
23538
- return (0, import_node_crypto8.createHash)("sha256").update(content).digest("hex");
24163
+ return (0, import_node_crypto9.createHash)("sha256").update(content).digest("hex");
23539
24164
  }
23540
24165
  async function readOptionalFile(filePath) {
23541
24166
  try {
23542
- return await import_node_fs5.promises.readFile(filePath, "utf8");
24167
+ return await import_node_fs6.promises.readFile(filePath, "utf8");
23543
24168
  } catch (error) {
23544
24169
  const code = error && typeof error === "object" && "code" in error ? error.code : null;
23545
24170
  if (code === "ENOENT") return null;
@@ -23550,9 +24175,9 @@ async function writeAtomicPath(filePath, content) {
23550
24175
  const dir = import_node_path9.default.dirname(filePath);
23551
24176
  const tempPath = import_node_path9.default.join(
23552
24177
  dir,
23553
- `.${import_node_path9.default.basename(filePath)}.${process.pid}.${(0, import_node_crypto8.randomUUID)()}.tmp`
24178
+ `.${import_node_path9.default.basename(filePath)}.${process.pid}.${(0, import_node_crypto9.randomUUID)()}.tmp`
23554
24179
  );
23555
- const handle = await import_node_fs5.promises.open(tempPath, "wx", 384);
24180
+ const handle = await import_node_fs6.promises.open(tempPath, "wx", 384);
23556
24181
  try {
23557
24182
  await handle.writeFile(content, "utf8");
23558
24183
  await handle.sync();
@@ -23560,9 +24185,9 @@ async function writeAtomicPath(filePath, content) {
23560
24185
  await handle.close();
23561
24186
  }
23562
24187
  try {
23563
- await import_node_fs5.promises.rename(tempPath, filePath);
24188
+ await import_node_fs6.promises.rename(tempPath, filePath);
23564
24189
  if (process.platform !== "win32") {
23565
- const dirHandle = await import_node_fs5.promises.open(dir, "r");
24190
+ const dirHandle = await import_node_fs6.promises.open(dir, "r");
23566
24191
  try {
23567
24192
  await dirHandle.sync();
23568
24193
  } finally {
@@ -23570,16 +24195,16 @@ async function writeAtomicPath(filePath, content) {
23570
24195
  }
23571
24196
  }
23572
24197
  } finally {
23573
- await import_node_fs5.promises.rm(tempPath, { force: true }).catch(() => void 0);
24198
+ await import_node_fs6.promises.rm(tempPath, { force: true }).catch(() => void 0);
23574
24199
  }
23575
24200
  }
23576
24201
  async function installAuthFileIfAbsent(filePath, content) {
23577
24202
  const dir = import_node_path9.default.dirname(filePath);
23578
24203
  const tempPath = import_node_path9.default.join(
23579
24204
  dir,
23580
- `.${import_node_path9.default.basename(filePath)}.${process.pid}.${(0, import_node_crypto8.randomUUID)()}.install`
24205
+ `.${import_node_path9.default.basename(filePath)}.${process.pid}.${(0, import_node_crypto9.randomUUID)()}.install`
23581
24206
  );
23582
- const handle = await import_node_fs5.promises.open(tempPath, "wx", 384);
24207
+ const handle = await import_node_fs6.promises.open(tempPath, "wx", 384);
23583
24208
  try {
23584
24209
  await handle.writeFile(content, "utf8");
23585
24210
  await handle.sync();
@@ -23587,25 +24212,25 @@ async function installAuthFileIfAbsent(filePath, content) {
23587
24212
  await handle.close();
23588
24213
  }
23589
24214
  try {
23590
- await import_node_fs5.promises.link(tempPath, filePath);
24215
+ await import_node_fs6.promises.link(tempPath, filePath);
23591
24216
  } finally {
23592
- await import_node_fs5.promises.rm(tempPath, { force: true }).catch(() => void 0);
24217
+ await import_node_fs6.promises.rm(tempPath, { force: true }).catch(() => void 0);
23593
24218
  }
23594
24219
  }
23595
24220
  async function linkAuthFileIfAbsent(sourcePath, targetPath) {
23596
- await import_node_fs5.promises.link(sourcePath, targetPath);
24221
+ await import_node_fs6.promises.link(sourcePath, targetPath);
23597
24222
  }
23598
24223
  async function hasExternalOpenFileHandle(filePath) {
23599
24224
  if (process.platform === "linux") {
23600
24225
  let target;
23601
24226
  try {
23602
- target = await import_node_fs5.promises.stat(filePath);
24227
+ target = await import_node_fs6.promises.stat(filePath);
23603
24228
  } catch {
23604
24229
  return true;
23605
24230
  }
23606
24231
  let processes;
23607
24232
  try {
23608
- processes = await import_node_fs5.promises.readdir("/proc", { withFileTypes: true });
24233
+ processes = await import_node_fs6.promises.readdir("/proc", { withFileTypes: true });
23609
24234
  } catch {
23610
24235
  return true;
23611
24236
  }
@@ -23616,7 +24241,7 @@ async function hasExternalOpenFileHandle(filePath) {
23616
24241
  }
23617
24242
  const processPath = `/proc/${entry.name}`;
23618
24243
  try {
23619
- const processStats = await import_node_fs5.promises.stat(processPath);
24244
+ const processStats = await import_node_fs6.promises.stat(processPath);
23620
24245
  if (currentUid !== void 0 && processStats.uid !== currentUid) {
23621
24246
  continue;
23622
24247
  }
@@ -23625,7 +24250,7 @@ async function hasExternalOpenFileHandle(filePath) {
23625
24250
  }
23626
24251
  let descriptors;
23627
24252
  try {
23628
- descriptors = await import_node_fs5.promises.readdir(`${processPath}/fd`);
24253
+ descriptors = await import_node_fs6.promises.readdir(`${processPath}/fd`);
23629
24254
  } catch (error) {
23630
24255
  const code = error && typeof error === "object" && "code" in error ? error.code : null;
23631
24256
  if (code === "ENOENT" || code === "ESRCH") continue;
@@ -23633,7 +24258,7 @@ async function hasExternalOpenFileHandle(filePath) {
23633
24258
  }
23634
24259
  for (const descriptor2 of descriptors) {
23635
24260
  try {
23636
- const descriptorStats = await import_node_fs5.promises.stat(`${processPath}/fd/${descriptor2}`);
24261
+ const descriptorStats = await import_node_fs6.promises.stat(`${processPath}/fd/${descriptor2}`);
23637
24262
  if (descriptorStats.dev === target.dev && descriptorStats.ino === target.ino) {
23638
24263
  return true;
23639
24264
  }
@@ -23680,9 +24305,9 @@ async function hasExternalOpenFileHandle(filePath) {
23680
24305
  async function cleanupAuthWriteback(filePath) {
23681
24306
  const paths = authWritebackPaths(filePath);
23682
24307
  await Promise.all([
23683
- import_node_fs5.promises.rm(paths.manifest, { force: true }),
23684
- import_node_fs5.promises.rm(paths.backup, { force: true }),
23685
- import_node_fs5.promises.rm(paths.replaced, { force: true })
24308
+ import_node_fs6.promises.rm(paths.manifest, { force: true }),
24309
+ import_node_fs6.promises.rm(paths.backup, { force: true }),
24310
+ import_node_fs6.promises.rm(paths.replaced, { force: true })
23686
24311
  ]);
23687
24312
  }
23688
24313
  async function rollbackAuthWriteback(filePath, manifest) {
@@ -23703,8 +24328,8 @@ async function rollbackAuthWriteback(filePath, manifest) {
23703
24328
  "Codex auth changed outside CodexUse during writeback rollback; recovery files were preserved."
23704
24329
  );
23705
24330
  }
23706
- await import_node_fs5.promises.rename(filePath, paths.replaced);
23707
- if (fingerprintAuth(await import_node_fs5.promises.readFile(paths.replaced, "utf8")) !== manifest.targetFingerprint) {
24331
+ await import_node_fs6.promises.rename(filePath, paths.replaced);
24332
+ if (fingerprintAuth(await import_node_fs6.promises.readFile(paths.replaced, "utf8")) !== manifest.targetFingerprint) {
23708
24333
  const replaced = await readOptionalFile(paths.replaced);
23709
24334
  if (await readOptionalFile(filePath) === null && replaced !== null) {
23710
24335
  await installAuthFileIfAbsent(filePath, replaced);
@@ -23741,7 +24366,7 @@ async function replaceAuthFileIfCurrent(filePath, expectedCurrent, replacement)
23741
24366
  await writeAtomicPath(paths.manifest, JSON.stringify(manifest));
23742
24367
  let committed = false;
23743
24368
  try {
23744
- await import_node_fs5.promises.rename(filePath, paths.backup);
24369
+ await import_node_fs6.promises.rename(filePath, paths.backup);
23745
24370
  if (await readOptionalFile(paths.backup) !== expectedCurrent) {
23746
24371
  throw new Error("Codex auth changed while writeback began.");
23747
24372
  }
@@ -23841,7 +24466,7 @@ async function acquireCodexAuthFileReadLock(filePath) {
23841
24466
  async function readAuthFileCached(filePath) {
23842
24467
  let stats;
23843
24468
  try {
23844
- stats = await import_node_fs5.promises.stat(filePath);
24469
+ stats = await import_node_fs6.promises.stat(filePath);
23845
24470
  } catch {
23846
24471
  authFileCache.delete(filePath);
23847
24472
  return null;
@@ -23850,7 +24475,7 @@ async function readAuthFileCached(filePath) {
23850
24475
  if (cached2 && cached2.mtimeMs === stats.mtimeMs && cached2.size === stats.size) {
23851
24476
  return cached2.content;
23852
24477
  }
23853
- const content = await import_node_fs5.promises.readFile(filePath, "utf8");
24478
+ const content = await import_node_fs6.promises.readFile(filePath, "utf8");
23854
24479
  authFileCache.set(filePath, {
23855
24480
  mtimeMs: stats.mtimeMs,
23856
24481
  size: stats.size,
@@ -23869,7 +24494,7 @@ async function writeAuthFileCached(filePath, content, expectedCurrent, options =
23869
24494
  );
23870
24495
  if (!written) return false;
23871
24496
  try {
23872
- const stats = await import_node_fs5.promises.stat(filePath);
24497
+ const stats = await import_node_fs6.promises.stat(filePath);
23873
24498
  authFileCache.set(filePath, {
23874
24499
  mtimeMs: stats.mtimeMs,
23875
24500
  size: stats.size,
@@ -24008,13 +24633,13 @@ function resolveRpcAuthPath(envOverride, authPath) {
24008
24633
  async function fetchRateLimitsViaRpc(envOverride, options = {}) {
24009
24634
  const binaryPath = options.codexPath ?? await requireCodexCli();
24010
24635
  const sourceAuthPath = resolveRpcAuthPath(envOverride, options.authPath);
24011
- const tempHome = await import_node_fs5.promises.mkdtemp(import_node_path9.default.join(import_node_os3.default.tmpdir(), "codex-rpc-"));
24636
+ const tempHome = await import_node_fs6.promises.mkdtemp(import_node_path9.default.join(import_node_os3.default.tmpdir(), "codex-rpc-"));
24012
24637
  const tempAuthPath = import_node_path9.default.join(tempHome, "auth.json");
24013
24638
  let initialSourceAuth;
24014
24639
  try {
24015
24640
  const authLock = await acquireCodexAuthFileReadLock(sourceAuthPath);
24016
24641
  if (!authLock) {
24017
- await import_node_fs5.promises.rm(tempHome, { recursive: true, force: true });
24642
+ await import_node_fs6.promises.rm(tempHome, { recursive: true, force: true });
24018
24643
  return null;
24019
24644
  }
24020
24645
  try {
@@ -24023,15 +24648,15 @@ async function fetchRateLimitsViaRpc(envOverride, options = {}) {
24023
24648
  await authLock.release();
24024
24649
  }
24025
24650
  if (!initialSourceAuth) {
24026
- await import_node_fs5.promises.rm(tempHome, { recursive: true, force: true });
24651
+ await import_node_fs6.promises.rm(tempHome, { recursive: true, force: true });
24027
24652
  return null;
24028
24653
  }
24029
- await import_node_fs5.promises.writeFile(tempAuthPath, initialSourceAuth, {
24654
+ await import_node_fs6.promises.writeFile(tempAuthPath, initialSourceAuth, {
24030
24655
  encoding: "utf8",
24031
24656
  mode: 384
24032
24657
  });
24033
24658
  } catch {
24034
- await import_node_fs5.promises.rm(tempHome, { recursive: true, force: true }).catch(() => {
24659
+ await import_node_fs6.promises.rm(tempHome, { recursive: true, force: true }).catch(() => {
24035
24660
  });
24036
24661
  return null;
24037
24662
  }
@@ -24098,7 +24723,7 @@ async function fetchRateLimitsViaRpc(envOverride, options = {}) {
24098
24723
  rl.close();
24099
24724
  await stopChildAndWait(child);
24100
24725
  try {
24101
- const updatedAuth = await import_node_fs5.promises.readFile(tempAuthPath, "utf8");
24726
+ const updatedAuth = await import_node_fs6.promises.readFile(tempAuthPath, "utf8");
24102
24727
  if (updatedAuth.trim().length > 0) {
24103
24728
  const currentSourceAuth = await readAuthFileCached(sourceAuthPath);
24104
24729
  if (shouldWriteBackAuth(initialSourceAuth, currentSourceAuth, updatedAuth)) {
@@ -24127,7 +24752,7 @@ async function fetchRateLimitsViaRpc(envOverride, options = {}) {
24127
24752
  } catch (error) {
24128
24753
  logWarn("Failed to sync refreshed auth after rate-limit probe:", error);
24129
24754
  }
24130
- await import_node_fs5.promises.rm(tempHome, { recursive: true, force: true }).catch(() => {
24755
+ await import_node_fs6.promises.rm(tempHome, { recursive: true, force: true }).catch(() => {
24131
24756
  });
24132
24757
  }
24133
24758
  }
@@ -24141,7 +24766,7 @@ async function activateResetWindowViaRpc(envOverride, options = {}) {
24141
24766
  }
24142
24767
  async function activateResetWindowViaRpcIsolated(envOverride, options, sourceAuthPath) {
24143
24768
  const binaryPath = options.codexPath ?? await requireCodexCli();
24144
- const tempHome = await import_node_fs5.promises.mkdtemp(
24769
+ const tempHome = await import_node_fs6.promises.mkdtemp(
24145
24770
  import_node_path9.default.join(import_node_os3.default.tmpdir(), "codex-activation-")
24146
24771
  );
24147
24772
  const tempAuthPath = import_node_path9.default.join(tempHome, "auth.json");
@@ -24149,7 +24774,7 @@ async function activateResetWindowViaRpcIsolated(envOverride, options, sourceAut
24149
24774
  try {
24150
24775
  const authLock = await acquireCodexAuthFileReadLock(sourceAuthPath);
24151
24776
  if (!authLock) {
24152
- await import_node_fs5.promises.rm(tempHome, { recursive: true, force: true });
24777
+ await import_node_fs6.promises.rm(tempHome, { recursive: true, force: true });
24153
24778
  return { status: "skipped", reason: "auth-busy" };
24154
24779
  }
24155
24780
  try {
@@ -24158,16 +24783,16 @@ async function activateResetWindowViaRpcIsolated(envOverride, options, sourceAut
24158
24783
  await authLock.release();
24159
24784
  }
24160
24785
  if (!initialSourceAuth) {
24161
- await import_node_fs5.promises.rm(tempHome, { recursive: true, force: true }).catch(() => {
24786
+ await import_node_fs6.promises.rm(tempHome, { recursive: true, force: true }).catch(() => {
24162
24787
  });
24163
24788
  return { status: "skipped", reason: "auth-missing" };
24164
24789
  }
24165
- await import_node_fs5.promises.writeFile(tempAuthPath, initialSourceAuth, {
24790
+ await import_node_fs6.promises.writeFile(tempAuthPath, initialSourceAuth, {
24166
24791
  encoding: "utf8",
24167
24792
  mode: 384
24168
24793
  });
24169
24794
  } catch {
24170
- await import_node_fs5.promises.rm(tempHome, { recursive: true, force: true }).catch(() => {
24795
+ await import_node_fs6.promises.rm(tempHome, { recursive: true, force: true }).catch(() => {
24171
24796
  });
24172
24797
  return { status: "skipped", reason: "auth-missing" };
24173
24798
  }
@@ -24180,7 +24805,7 @@ async function activateResetWindowViaRpcIsolated(envOverride, options, sourceAut
24180
24805
  } catch {
24181
24806
  }
24182
24807
  const activationModel = resolveActivationModel(configuredModel);
24183
- await import_node_fs5.promises.writeFile(
24808
+ await import_node_fs6.promises.writeFile(
24184
24809
  import_node_path9.default.join(tempHome, "config.toml"),
24185
24810
  `model = ${JSON.stringify(activationModel)}
24186
24811
  `,
@@ -24318,7 +24943,7 @@ async function activateResetWindowViaRpcIsolated(envOverride, options, sourceAut
24318
24943
  rl.close();
24319
24944
  await stopChildAndWait(child);
24320
24945
  try {
24321
- const updatedAuth = await import_node_fs5.promises.readFile(tempAuthPath, "utf8");
24946
+ const updatedAuth = await import_node_fs6.promises.readFile(tempAuthPath, "utf8");
24322
24947
  if (updatedAuth.trim().length > 0) {
24323
24948
  const currentSourceAuth = await readAuthFileCached(sourceAuthPath);
24324
24949
  if (shouldWriteBackAuth(initialSourceAuth, currentSourceAuth, updatedAuth)) {
@@ -24353,7 +24978,7 @@ async function activateResetWindowViaRpcIsolated(envOverride, options, sourceAut
24353
24978
  } catch (error) {
24354
24979
  writebackError = error instanceof Error ? error : new Error(String(error));
24355
24980
  }
24356
- await import_node_fs5.promises.rm(tempHome, { recursive: true, force: true }).catch(() => {
24981
+ await import_node_fs6.promises.rm(tempHome, { recursive: true, force: true }).catch(() => {
24357
24982
  });
24358
24983
  }
24359
24984
  if (activationError && writebackError) {
@@ -24376,13 +25001,13 @@ async function activateResetWindowViaRpcIsolated(envOverride, options, sourceAut
24376
25001
 
24377
25002
  // ../../packages/runtime-codex/src/codex/officialAppRestart.ts
24378
25003
  var import_node_child_process6 = require("child_process");
24379
- var import_node_crypto9 = require("crypto");
24380
- var import_node_fs7 = require("fs");
25004
+ var import_node_crypto10 = require("crypto");
25005
+ var import_node_fs8 = require("fs");
24381
25006
  var import_node_os4 = require("os");
24382
25007
  var import_node_path11 = __toESM(require("path"), 1);
24383
25008
 
24384
25009
  // ../../packages/runtime-codex/src/codex/threadUsage.ts
24385
- var import_node_fs6 = require("fs");
25010
+ var import_node_fs7 = require("fs");
24386
25011
  var import_node_path10 = __toESM(require("path"), 1);
24387
25012
  var ROLLOUT_DIRS = ["sessions", "archived_sessions"];
24388
25013
  var SQLITE_EXTENSIONS = /* @__PURE__ */ new Set([".db", ".sqlite", ".sqlite3"]);
@@ -24395,7 +25020,7 @@ async function collectRolloutFiles(root) {
24395
25020
  async function visit(dir) {
24396
25021
  let entries3;
24397
25022
  try {
24398
- entries3 = await import_node_fs6.promises.readdir(dir, {
25023
+ entries3 = await import_node_fs7.promises.readdir(dir, {
24399
25024
  withFileTypes: true,
24400
25025
  encoding: "utf8"
24401
25026
  });
@@ -24423,7 +25048,7 @@ async function collectRolloutFiles(root) {
24423
25048
  async function collectRolloutFilesStrict(root) {
24424
25049
  const files = [];
24425
25050
  async function visit(dir) {
24426
- const entries3 = await import_node_fs6.promises.readdir(dir, {
25051
+ const entries3 = await import_node_fs7.promises.readdir(dir, {
24427
25052
  withFileTypes: true,
24428
25053
  encoding: "utf8"
24429
25054
  });
@@ -24448,7 +25073,7 @@ async function readOfficialCodexRolloutActivityHeat(profileHome) {
24448
25073
  for (const dirname of ROLLOUT_DIRS) {
24449
25074
  const root = import_node_path10.default.join(profileHome, dirname);
24450
25075
  try {
24451
- await import_node_fs6.promises.access(root);
25076
+ await import_node_fs7.promises.access(root);
24452
25077
  } catch (error) {
24453
25078
  if (error.code === "ENOENT") {
24454
25079
  continue;
@@ -24457,7 +25082,7 @@ async function readOfficialCodexRolloutActivityHeat(profileHome) {
24457
25082
  }
24458
25083
  const files = await collectRolloutFilesStrict(root);
24459
25084
  for (const file of files) {
24460
- const stat2 = await import_node_fs6.promises.stat(file);
25085
+ const stat2 = await import_node_fs7.promises.stat(file);
24461
25086
  if (Number.isFinite(stat2.mtimeMs)) {
24462
25087
  latestUpdatedAtMs = Math.max(latestUpdatedAtMs ?? 0, stat2.mtimeMs);
24463
25088
  }
@@ -24485,7 +25110,7 @@ async function findRolloutFileByScan(profileHome, threadId) {
24485
25110
  if (!variants.some((variant) => basename.includes(variant))) {
24486
25111
  continue;
24487
25112
  }
24488
- const stat2 = await import_node_fs6.promises.stat(file).catch(() => null);
25113
+ const stat2 = await import_node_fs7.promises.stat(file).catch(() => null);
24489
25114
  const updatedAtMs = stat2 && Number.isFinite(stat2.mtimeMs) ? stat2.mtimeMs : null;
24490
25115
  if (!best || (updatedAtMs ?? 0) > (best.updatedAtMs ?? 0) || (updatedAtMs ?? 0) === (best.updatedAtMs ?? 0) && file > best.path) {
24491
25116
  best = { path: file, updatedAtMs };
@@ -24563,7 +25188,7 @@ async function collectSessionDatabasePaths(profileHome, sqliteHome = profileHome
24563
25188
  const paths = [];
24564
25189
  const sqliteDir = import_node_path10.default.join(sqliteHome, "sqlite");
24565
25190
  try {
24566
- const entries3 = await import_node_fs6.promises.readdir(sqliteDir, {
25191
+ const entries3 = await import_node_fs7.promises.readdir(sqliteDir, {
24567
25192
  withFileTypes: true,
24568
25193
  encoding: "utf8"
24569
25194
  });
@@ -24645,7 +25270,7 @@ function queryThreadRecordFromTable(db, profileHome, threadId, config) {
24645
25270
  }
24646
25271
  async function readThreadRecordFromDb(profileHome, dbPath, threadId) {
24647
25272
  try {
24648
- await import_node_fs6.promises.access(dbPath);
25273
+ await import_node_fs7.promises.access(dbPath);
24649
25274
  } catch {
24650
25275
  return null;
24651
25276
  }
@@ -25065,7 +25690,7 @@ function hashProfileKey(profileKey) {
25065
25690
  if (!profileKey) {
25066
25691
  return null;
25067
25692
  }
25068
- return (0, import_node_crypto9.createHash)("sha256").update(profileKey).digest("hex").slice(0, 12);
25693
+ return (0, import_node_crypto10.createHash)("sha256").update(profileKey).digest("hex").slice(0, 12);
25069
25694
  }
25070
25695
  function sanitizeOfficialCodexOverlayActionTargetsForRenderer(targets) {
25071
25696
  const sanitized = [];
@@ -28677,7 +29302,7 @@ async function runCdpCommandSequence(debuggerUrl, commands, timeoutMs = CODEX_CD
28677
29302
  });
28678
29303
  }
28679
29304
  async function verifyCdpBindingRoundTrip(debuggerUrl) {
28680
- const nonce = (0, import_node_crypto9.randomUUID)();
29305
+ const nonce = (0, import_node_crypto10.randomUUID)();
28681
29306
  const expression = `(() => {
28682
29307
  const binding = window[${JSON.stringify(CODEXUSE_BRIDGE_BINDING_NAME)}];
28683
29308
  if (typeof binding !== "function") return false;
@@ -29100,7 +29725,7 @@ async function startOfficialCodexBridgeActionListenerOnce(args2) {
29100
29725
  let closeNotified = false;
29101
29726
  let echoReceived = false;
29102
29727
  const requiredCommandIds = /* @__PURE__ */ new Set();
29103
- const echoId = (0, import_node_crypto9.randomUUID)();
29728
+ const echoId = (0, import_node_crypto10.randomUUID)();
29104
29729
  const readyTimeout = setTimeout(() => {
29105
29730
  settleReady(false);
29106
29731
  try {
@@ -29174,7 +29799,7 @@ async function startOfficialCodexBridgeActionListenerOnce(args2) {
29174
29799
  }
29175
29800
  };
29176
29801
  bridgeActionListenerVerifiers.set(args2.debuggerUrl, async () => {
29177
- const id2 = (0, import_node_crypto9.randomUUID)();
29802
+ const id2 = (0, import_node_crypto10.randomUUID)();
29178
29803
  return await new Promise((resolve2) => {
29179
29804
  const waiters = bridgeActionListenerHealthWaiters.get(args2.debuggerUrl) ?? /* @__PURE__ */ new Map();
29180
29805
  bridgeActionListenerHealthWaiters.set(args2.debuggerUrl, waiters);
@@ -29722,7 +30347,7 @@ async function recordOfficialCodexActivity(input) {
29722
30347
  };
29723
30348
  const finite2 = (value3, min4, max4) => typeof value3 === "number" && Number.isFinite(value3) ? Math.max(min4, Math.min(max4, value3)) : null;
29724
30349
  const entry = {
29725
- id: (0, import_node_crypto9.randomUUID)(),
30350
+ id: (0, import_node_crypto10.randomUUID)(),
29726
30351
  at: now2.toISOString(),
29727
30352
  kind: input.kind,
29728
30353
  status: bounded(input.status, 80) ?? "unknown",
@@ -30725,7 +31350,7 @@ var devToolsActivePortPaths = (appUserDataDir) => {
30725
31350
  };
30726
31351
  var readDevToolsActivePort = async (filePath) => {
30727
31352
  try {
30728
- const text = await import_node_fs7.promises.readFile(filePath, "utf8");
31353
+ const text = await import_node_fs8.promises.readFile(filePath, "utf8");
30729
31354
  const port = Number(text.split(/\r?\n/, 1)[0]);
30730
31355
  if (!Number.isInteger(port) || port <= 0 || port >= 65536) {
30731
31356
  return null;
@@ -30762,7 +31387,7 @@ function classifyOpenCodexLaunchFailure(error) {
30762
31387
  }
30763
31388
  async function openCodexWithProfileHome(candidate, profileHome, profileName, previousPids, options = {}) {
30764
31389
  const executablePath = getMainExecutablePath(candidate);
30765
- if (!(0, import_node_fs7.existsSync)(executablePath)) {
31390
+ if (!(0, import_node_fs8.existsSync)(executablePath)) {
30766
31391
  return {
30767
31392
  opened: false,
30768
31393
  pid: null,
@@ -30780,7 +31405,7 @@ async function openCodexWithProfileHome(candidate, profileHome, profileName, pre
30780
31405
  let child;
30781
31406
  try {
30782
31407
  if (appUserDataDir) {
30783
- (0, import_node_fs7.mkdirSync)(appUserDataDir, { recursive: true });
31408
+ (0, import_node_fs8.mkdirSync)(appUserDataDir, { recursive: true });
30784
31409
  }
30785
31410
  child = (0, import_node_child_process6.spawn)(
30786
31411
  "/usr/bin/open",
@@ -30935,7 +31560,7 @@ function resolveCodexLaunchHome(profileHome) {
30935
31560
  }
30936
31561
  async function readBundleString(appPath, key) {
30937
31562
  const plistPath = import_node_path11.default.join(appPath, "Contents", "Info.plist");
30938
- if (!(0, import_node_fs7.existsSync)(plistPath)) {
31563
+ if (!(0, import_node_fs8.existsSync)(plistPath)) {
30939
31564
  return null;
30940
31565
  }
30941
31566
  const result2 = await runCommand2("/usr/bin/plutil", [
@@ -30965,7 +31590,7 @@ function officialCodexAppPriority(appPath) {
30965
31590
  async function collectCodexAppCandidates(rawPaths) {
30966
31591
  const candidates = [];
30967
31592
  for (const appPath of rawPaths) {
30968
- if (!(0, import_node_fs7.existsSync)(appPath) || !OFFICIAL_CODEX_APP_NAMES.includes(import_node_path11.default.basename(appPath)) || !(0, import_node_fs7.existsSync)(import_node_path11.default.join(appPath, "Contents", "Resources", "codex"))) {
31593
+ if (!(0, import_node_fs8.existsSync)(appPath) || !OFFICIAL_CODEX_APP_NAMES.includes(import_node_path11.default.basename(appPath)) || !(0, import_node_fs8.existsSync)(import_node_path11.default.join(appPath, "Contents", "Resources", "codex"))) {
30969
31594
  continue;
30970
31595
  }
30971
31596
  const bundleId = await readBundleString(appPath, "CFBundleIdentifier");
@@ -31077,7 +31702,7 @@ function sharedCodexLaunchOptions(useDefaultUserData, profileIdentity) {
31077
31702
  const userDataDir = !useDefaultUserData && profileIdentity ? import_node_path11.default.join(
31078
31703
  SHARED_CODEX_HOME,
31079
31704
  "codex-app-user-data",
31080
- (0, import_node_crypto9.createHash)("sha256").update(profileIdentity).digest("hex").slice(0, 16)
31705
+ (0, import_node_crypto10.createHash)("sha256").update(profileIdentity).digest("hex").slice(0, 16)
31081
31706
  ) : void 0;
31082
31707
  return {
31083
31708
  useDefaultUserData,
@@ -33488,7 +34113,7 @@ async function attemptOfficialCodexManagedLiveLogin(args2) {
33488
34113
  }
33489
34114
  }
33490
34115
  async function applyOfficialCodexLiveAccountSwitchOnce(options = {}, takeoverTrace = {
33491
- operationId: (0, import_node_crypto9.randomUUID)(),
34116
+ operationId: (0, import_node_crypto10.randomUUID)(),
33492
34117
  attempt: 1
33493
34118
  }) {
33494
34119
  let expectedWindowPreflight = options.expectedWindowPreflight;
@@ -34556,7 +35181,7 @@ async function applyOfficialCodexLiveAccountSwitchOnce(options = {}, takeoverTra
34556
35181
  }
34557
35182
  function applyOfficialCodexLiveAccountSwitch(options = {}) {
34558
35183
  return enqueueProfileAction("shared-window", async () => {
34559
- const operationId = (0, import_node_crypto9.randomUUID)();
35184
+ const operationId = (0, import_node_crypto10.randomUUID)();
34560
35185
  let result2 = await applyOfficialCodexLiveAccountSwitchOnce(options, {
34561
35186
  operationId,
34562
35187
  attempt: 1
@@ -35281,7 +35906,7 @@ async function launchOfficialCodexProfileInstanceOnce(options) {
35281
35906
  }
35282
35907
 
35283
35908
  // ../../packages/runtime-app-state/src/app/profileHomeMutationCoordinator.ts
35284
- var import_node_crypto10 = require("crypto");
35909
+ var import_node_crypto11 = require("crypto");
35285
35910
 
35286
35911
  // ../../packages/runtime-app-state/src/app/processOwner.ts
35287
35912
  var import_node_child_process7 = require("child_process");
@@ -35319,12 +35944,12 @@ function isProcessEpochAlive(pid, expectedStartedAt) {
35319
35944
  // ../../packages/runtime-app-state/src/app/profileHomeMutationCoordinator.ts
35320
35945
  var PROFILE_HOME_MUTATION_TTL_MS = 10 * 60 * 1e3;
35321
35946
  var PROFILE_HOME_MUTATION_RENEW_MS = 30 * 1e3;
35322
- var PROCESS_OWNER_ID = (0, import_node_crypto10.randomUUID)();
35947
+ var PROCESS_OWNER_ID = (0, import_node_crypto11.randomUUID)();
35323
35948
  var PROCESS_STARTED_AT = readProcessStartedAt(process.pid);
35324
35949
  var activeRenewals = /* @__PURE__ */ new Map();
35325
35950
  async function acquireProfileHomeMutationIntent(input) {
35326
35951
  const now2 = Date.now();
35327
- const operationId = (0, import_node_crypto10.randomUUID)();
35952
+ const operationId = (0, import_node_crypto11.randomUUID)();
35328
35953
  const renewal = {
35329
35954
  timer: void 0,
35330
35955
  pending: Promise.resolve(),
@@ -35406,7 +36031,7 @@ async function releaseProfileHomeMutationIntent(homeId, operationId) {
35406
36031
  }
35407
36032
 
35408
36033
  // ../../packages/runtime-profiles/src/profiles/rate-limit-cache.ts
35409
- var import_node_fs8 = require("fs");
36034
+ var import_node_fs9 = require("fs");
35410
36035
  var import_node_path12 = __toESM(require("path"), 1);
35411
36036
  var memorySnapshots = /* @__PURE__ */ new Map();
35412
36037
  var persistedSnapshotWriteLock = Promise.resolve();
@@ -35420,7 +36045,7 @@ function snapshotCachePath() {
35420
36045
  async function loadPersistedSnapshots() {
35421
36046
  let raw;
35422
36047
  try {
35423
- raw = (await import_node_fs8.promises.readFile(snapshotCachePath(), "utf8")).trim();
36048
+ raw = (await import_node_fs9.promises.readFile(snapshotCachePath(), "utf8")).trim();
35424
36049
  } catch {
35425
36050
  return /* @__PURE__ */ new Map();
35426
36051
  }
@@ -35464,13 +36089,13 @@ async function writePersistedSnapshots(snapshots) {
35464
36089
  2
35465
36090
  );
35466
36091
  try {
35467
- await import_node_fs8.promises.mkdir(import_node_path12.default.dirname(filePath), { recursive: true });
35468
- await import_node_fs8.promises.writeFile(tmpPath, `${payload}
36092
+ await import_node_fs9.promises.mkdir(import_node_path12.default.dirname(filePath), { recursive: true });
36093
+ await import_node_fs9.promises.writeFile(tmpPath, `${payload}
35469
36094
  `, "utf8");
35470
- await import_node_fs8.promises.rename(tmpPath, filePath);
36095
+ await import_node_fs9.promises.rename(tmpPath, filePath);
35471
36096
  } catch {
35472
36097
  try {
35473
- await import_node_fs8.promises.rm(tmpPath, { force: true });
36098
+ await import_node_fs9.promises.rm(tmpPath, { force: true });
35474
36099
  } catch {
35475
36100
  }
35476
36101
  }
@@ -35535,7 +36160,7 @@ var AUTH_MUTATION_MANIFEST_NAME = ".codexuse-auth-transaction.json";
35535
36160
  var AUTH_MUTATION_BACKUP_NAME = ".codexuse-auth-transaction.backup";
35536
36161
  var AUTH_MUTATION_REPLACED_NAME = ".codexuse-auth-transaction.replaced";
35537
36162
  var PROFILE_HOME_MUTATION_MARKER_TTL_MS = 10 * 60 * 1e3;
35538
- var PROCESS_OWNER_ID2 = (0, import_node_crypto11.randomUUID)();
36163
+ var PROCESS_OWNER_ID2 = (0, import_node_crypto12.randomUUID)();
35539
36164
  var PROCESS_STARTED_AT2 = readProcessStartedAt(process.pid);
35540
36165
  var globalAuthSwapLock = Promise.resolve();
35541
36166
  var profileOperationLocks = /* @__PURE__ */ new Map();
@@ -36381,7 +37006,7 @@ var ProfileManager = class {
36381
37006
  let attempt = 0;
36382
37007
  let homeId;
36383
37008
  do {
36384
- homeId = `legacy-${(0, import_node_crypto11.createHash)("sha256").update(profileName).update("\0").update(String(attempt)).digest("hex").slice(0, 32)}`;
37009
+ homeId = `legacy-${(0, import_node_crypto12.createHash)("sha256").update(profileName).update("\0").update(String(attempt)).digest("hex").slice(0, 32)}`;
36385
37010
  attempt += 1;
36386
37011
  } while (profileNamesByHomeId.has(homeId.toLowerCase()));
36387
37012
  homeIdsByProfileName.set(profileName, homeId);
@@ -36591,7 +37216,7 @@ var ProfileManager = class {
36591
37216
  const dir = import_path.default.dirname(filePath);
36592
37217
  const tempPath = import_path.default.join(
36593
37218
  dir,
36594
- `.${import_path.default.basename(filePath)}.${process.pid}.${(0, import_node_crypto11.randomUUID)()}.tmp`
37219
+ `.${import_path.default.basename(filePath)}.${process.pid}.${(0, import_node_crypto12.randomUUID)()}.tmp`
36595
37220
  );
36596
37221
  await import_fs.promises.mkdir(dir, { recursive: true, mode: 448 });
36597
37222
  if (process.platform !== "win32") {
@@ -36878,7 +37503,7 @@ var ProfileManager = class {
36878
37503
  if (content === null) {
36879
37504
  return null;
36880
37505
  }
36881
- return (0, import_node_crypto11.createHash)("sha256").update(content).digest("hex");
37506
+ return (0, import_node_crypto12.createHash)("sha256").update(content).digest("hex");
36882
37507
  }
36883
37508
  async readOptionalFile(filePath) {
36884
37509
  try {
@@ -36936,7 +37561,7 @@ var ProfileManager = class {
36936
37561
  const dir = import_path.default.dirname(filePath);
36937
37562
  const tempPath = import_path.default.join(
36938
37563
  dir,
36939
- `.${import_path.default.basename(filePath)}.${process.pid}.${(0, import_node_crypto11.randomUUID)()}.install`
37564
+ `.${import_path.default.basename(filePath)}.${process.pid}.${(0, import_node_crypto12.randomUUID)()}.install`
36940
37565
  );
36941
37566
  const handle = await import_fs.promises.open(tempPath, "wx", 384);
36942
37567
  try {
@@ -37054,7 +37679,7 @@ var ProfileManager = class {
37054
37679
  });
37055
37680
  const manifest = {
37056
37681
  version: 1,
37057
- id: (0, import_node_crypto11.randomUUID)(),
37682
+ id: (0, import_node_crypto12.randomUUID)(),
37058
37683
  operation,
37059
37684
  phase: "prepared",
37060
37685
  sourceFingerprint: this.fingerprintAuthContent(sourceRaw),
@@ -37776,7 +38401,7 @@ var ProfileManager = class {
37776
38401
  const displayName = typeof options?.displayName === "string" && options.displayName.trim().length > 0 ? options.displayName.trim() : existingRecord?.displayName ?? resolvedName;
37777
38402
  const record2 = {
37778
38403
  name: resolvedName,
37779
- homeId: existingRecord?.homeId ?? (options?.homeId ? this.normalizeProfileHomeId(options.homeId, resolvedName) : (0, import_node_crypto11.randomUUID)()),
38404
+ homeId: existingRecord?.homeId ?? (options?.homeId ? this.normalizeProfileHomeId(options.homeId, resolvedName) : (0, import_node_crypto12.randomUUID)()),
37780
38405
  cloudHomeId: existingRecord?.cloudHomeId ?? null,
37781
38406
  displayName,
37782
38407
  data,
@@ -37881,7 +38506,7 @@ var ProfileManager = class {
37881
38506
  const safeName = record2.name.replace(/[^A-Za-z0-9._-]+/g, "-").slice(0, 48) || "profile";
37882
38507
  const destination = import_path.default.join(
37883
38508
  trashRoot,
37884
- `CodexUse-${safeName}-${(0, import_node_crypto11.randomUUID)()}`
38509
+ `CodexUse-${safeName}-${(0, import_node_crypto12.randomUUID)()}`
37885
38510
  );
37886
38511
  await import_fs.promises.rename(profileHome, destination);
37887
38512
  return destination;
@@ -38309,7 +38934,7 @@ var ProfileManager = class {
38309
38934
  async acquireProfileRuntimeLease(record2) {
38310
38935
  const leaseDir = this.getProfileRuntimeLeaseDir(record2.homeId);
38311
38936
  const deletingPath = (0, import_path2.join)(leaseDir, ".deleting");
38312
- const leaseId = (0, import_node_crypto11.randomUUID)();
38937
+ const leaseId = (0, import_node_crypto12.randomUUID)();
38313
38938
  const leasePath = (0, import_path2.join)(leaseDir, `${leaseId}.json`);
38314
38939
  const backupPath = (0, import_path2.join)(leaseDir, `${leaseId}.auth.backup`);
38315
38940
  const releaseIntent = await this.acquireProfileHomeWriteIntent(record2);
@@ -38520,7 +39145,7 @@ var ProfileManager = class {
38520
39145
  async acquireProfileHomeMutationGuard(record2) {
38521
39146
  const leaseDir = this.getProfileRuntimeLeaseDir(record2.homeId);
38522
39147
  const deletingPath = (0, import_path2.join)(leaseDir, ".deleting");
38523
- const mutationId = (0, import_node_crypto11.randomUUID)();
39148
+ const mutationId = (0, import_node_crypto12.randomUUID)();
38524
39149
  const mutationIntent = await acquireProfileHomeMutationIntent({
38525
39150
  homeId: record2.homeId,
38526
39151
  profileName: record2.name
@@ -39872,8 +40497,8 @@ var ProfileManager = class {
39872
40497
  }
39873
40498
  cloudRenamesByOldName.set(renamedExisting.name, name);
39874
40499
  }
39875
- const homeId = (0, import_node_crypto11.randomUUID)();
39876
- const cloudHomeId = remoteHomeId || existing?.cloudHomeId || existing?.homeId || renamedExisting?.cloudHomeId || renamedExisting?.homeId || (0, import_node_crypto11.randomUUID)();
40500
+ const homeId = (0, import_node_crypto12.randomUUID)();
40501
+ const cloudHomeId = remoteHomeId || existing?.cloudHomeId || existing?.homeId || renamedExisting?.cloudHomeId || renamedExisting?.homeId || (0, import_node_crypto12.randomUUID)();
39877
40502
  const sourceRecord = renamedExisting ?? existing;
39878
40503
  if (sourceRecord) {
39879
40504
  sourceHomeIdByTargetHomeId.set(homeId, sourceRecord.homeId);
@@ -40774,13 +41399,13 @@ async function listApiKeys(stateDir) {
40774
41399
  return Object.values(store.apiKeysById).filter((key) => key.revokedAt === null).sort((left, right) => right.createdAt.localeCompare(left.createdAt)).map(accountPoolApiKeyView);
40775
41400
  }
40776
41401
  function hashToken(token) {
40777
- return (0, import_node_crypto12.createHash)("sha256").update(token).digest("hex");
41402
+ return (0, import_node_crypto13.createHash)("sha256").update(token).digest("hex");
40778
41403
  }
40779
41404
  async function createApiKey(stateDir) {
40780
- const plaintextToken = `cux_pool_${(0, import_node_crypto12.randomBytes)(24).toString("hex")}`;
41405
+ const plaintextToken = `cux_pool_${(0, import_node_crypto13.randomBytes)(24).toString("hex")}`;
40781
41406
  const now2 = (/* @__PURE__ */ new Date()).toISOString();
40782
41407
  const keyRecord = {
40783
- id: (0, import_node_crypto12.randomUUID)(),
41408
+ id: (0, import_node_crypto13.randomUUID)(),
40784
41409
  tokenHash: hashToken(plaintextToken),
40785
41410
  tokenPreview: `${plaintextToken.slice(0, 8)}...${plaintextToken.slice(-6)}`,
40786
41411
  createdAt: now2,
@@ -41405,14 +42030,14 @@ async function assertProfileAccessAllowed(profileManager, profileName) {
41405
42030
  }
41406
42031
 
41407
42032
  // ../../packages/runtime-app-state/src/app/workspaceBindings.ts
41408
- var import_node_fs9 = require("fs");
42033
+ var import_node_fs10 = require("fs");
41409
42034
  var import_node_path14 = __toESM(require("path"), 1);
41410
42035
  async function canonicalizeWorkspacePath(input, options = {}) {
41411
42036
  const resolved = import_node_path14.default.resolve(input || process.cwd());
41412
42037
  try {
41413
- const canonical = await import_node_fs9.promises.realpath(resolved);
42038
+ const canonical = await import_node_fs10.promises.realpath(resolved);
41414
42039
  if (options.requireDirectory !== false) {
41415
- const stats = await import_node_fs9.promises.stat(canonical);
42040
+ const stats = await import_node_fs10.promises.stat(canonical);
41416
42041
  if (!stats.isDirectory()) {
41417
42042
  throw new Error(`Workspace path is not a directory: ${resolved}`);
41418
42043
  }
@@ -41497,14 +42122,14 @@ async function resolveWorkspaceProfileBinding(requestedPath) {
41497
42122
 
41498
42123
  // src/platform/codexCli.ts
41499
42124
  var import_node_child_process8 = require("child_process");
41500
- var import_node_fs10 = require("fs");
42125
+ var import_node_fs11 = require("fs");
41501
42126
  var import_node_path15 = __toESM(require("path"));
41502
42127
  var ENV_HINTS2 = ["CODEX_BINARY", "CODEX_CLI_PATH", "CODEX_PATH"];
41503
42128
  function fileExists2(candidate) {
41504
42129
  if (!candidate) return null;
41505
42130
  const resolved = import_node_path15.default.resolve(candidate);
41506
42131
  try {
41507
- const stat2 = (0, import_node_fs10.statSync)(resolved);
42132
+ const stat2 = (0, import_node_fs11.statSync)(resolved);
41508
42133
  if (stat2.isFile()) return resolved;
41509
42134
  } catch {
41510
42135
  return null;
@@ -41963,17 +42588,17 @@ async function handleLicense(args2, version) {
41963
42588
  }
41964
42589
 
41965
42590
  // src/commands/profile.ts
41966
- var import_node_fs12 = require("fs");
42591
+ var import_node_fs13 = require("fs");
41967
42592
  var import_node_os7 = __toESM(require("os"));
41968
42593
  var import_node_path17 = __toESM(require("path"));
41969
42594
 
41970
42595
  // ../../packages/runtime-app-state/src/app/officialCodexSwitchCoordinator.ts
41971
- var import_node_crypto13 = require("crypto");
41972
- var import_node_fs11 = require("fs");
42596
+ var import_node_crypto14 = require("crypto");
42597
+ var import_node_fs12 = require("fs");
41973
42598
  var import_node_path16 = __toESM(require("path"), 1);
41974
42599
  var DEFAULT_SWITCH_INTENT_TTL_MS = 10 * 60 * 1e3;
41975
42600
  var SWITCH_INTENT_RENEW_MS = 30 * 1e3;
41976
- var PROCESS_OWNER_ID3 = (0, import_node_crypto13.randomUUID)();
42601
+ var PROCESS_OWNER_ID3 = (0, import_node_crypto14.randomUUID)();
41977
42602
  var PROCESS_STARTED_AT3 = readProcessStartedAt(process.pid);
41978
42603
  var localIntentDepth = /* @__PURE__ */ new Map();
41979
42604
  var pendingLocalIntentAcquisitions = /* @__PURE__ */ new Map();
@@ -41983,7 +42608,7 @@ function nextSwitchIntentGeneration(current) {
41983
42608
  }
41984
42609
  async function acquireOfficialCodexSwitchIntent(input) {
41985
42610
  const now2 = Date.now();
41986
- const operationId = input.operationId?.trim() || (0, import_node_crypto13.randomUUID)();
42611
+ const operationId = input.operationId?.trim() || (0, import_node_crypto14.randomUUID)();
41987
42612
  const targetProfileName = input.targetProfileName.trim();
41988
42613
  if (!targetProfileName) {
41989
42614
  throw new Error("Profile name is required");
@@ -42477,7 +43102,7 @@ function formatProfileLabel(name, displayName) {
42477
43102
  }
42478
43103
  var AUTO_ROLL_ACCESS_REQUIRED_MESSAGE = "Auto-roll requires a Pro license or an active trial.";
42479
43104
  async function withIsolatedCodexLogin(mode, action) {
42480
- const home = await import_node_fs12.promises.mkdtemp(import_node_path17.default.join(import_node_os7.default.tmpdir(), "codexuse-cli-login-"));
43105
+ const home = await import_node_fs13.promises.mkdtemp(import_node_path17.default.join(import_node_os7.default.tmpdir(), "codexuse-cli-login-"));
42481
43106
  try {
42482
43107
  await runCodexLogin(mode, {
42483
43108
  HOME: home,
@@ -42487,7 +43112,7 @@ async function withIsolatedCodexLogin(mode, action) {
42487
43112
  });
42488
43113
  return await action(import_node_path17.default.join(home, "auth.json"));
42489
43114
  } finally {
42490
- await import_node_fs12.promises.rm(home, { recursive: true, force: true }).catch(() => void 0);
43115
+ await import_node_fs13.promises.rm(home, { recursive: true, force: true }).catch(() => void 0);
42491
43116
  }
42492
43117
  }
42493
43118
  async function assertOfficialCodexProfileStopped(profileName) {
@@ -44005,7 +44630,7 @@ async function pushRemoteSnapshot(access, snapshot2, options) {
44005
44630
 
44006
44631
  // ../../packages/runtime-profiles/src/cloud-sync/encryption.ts
44007
44632
  var import_node_child_process10 = require("child_process");
44008
- var import_node_crypto14 = require("crypto");
44633
+ var import_node_crypto15 = require("crypto");
44009
44634
  var KEYCHAIN_SERVICE2 = "CODEXUSE_CLOUD_SYNC_PASSPHRASE";
44010
44635
  var KEYCHAIN_ACCOUNT_PREFIX2 = "license-sha256:";
44011
44636
  var ENCRYPTION_AAD = Buffer.from("codexuse-cloud-sync-v2", "utf8");
@@ -44030,7 +44655,7 @@ function requireCloudSyncPassphrase(value3) {
44030
44655
  }
44031
44656
  async function deriveKey(passphrase, salt, params = SCRYPT_PARAMS) {
44032
44657
  return new Promise((resolve2, reject) => {
44033
- (0, import_node_crypto14.scrypt)(passphrase, salt, params.keyLength, {
44658
+ (0, import_node_crypto15.scrypt)(passphrase, salt, params.keyLength, {
44034
44659
  N: params.N,
44035
44660
  r: params.r,
44036
44661
  p: params.p,
@@ -44067,10 +44692,10 @@ function normalizeDecryptedSnapshot(value3) {
44067
44692
  };
44068
44693
  }
44069
44694
  async function encryptCloudSyncSnapshot(snapshot2, passphrase) {
44070
- const salt = (0, import_node_crypto14.randomBytes)(16);
44071
- const iv = (0, import_node_crypto14.randomBytes)(12);
44695
+ const salt = (0, import_node_crypto15.randomBytes)(16);
44696
+ const iv = (0, import_node_crypto15.randomBytes)(12);
44072
44697
  const key = await deriveKey(requireCloudSyncPassphrase(passphrase), salt);
44073
- const cipher = (0, import_node_crypto14.createCipheriv)("aes-256-gcm", key, iv);
44698
+ const cipher = (0, import_node_crypto15.createCipheriv)("aes-256-gcm", key, iv);
44074
44699
  cipher.setAAD(ENCRYPTION_AAD);
44075
44700
  const plaintext = Buffer.from(JSON.stringify(snapshot2), "utf8");
44076
44701
  const ciphertext = Buffer.concat([cipher.update(plaintext), cipher.final()]);
@@ -44097,7 +44722,7 @@ async function decryptCloudSyncSnapshot(snapshot2, passphrase) {
44097
44722
  const tag2 = fromBase64(snapshot2.encryption.tag);
44098
44723
  const ciphertext = fromBase64(snapshot2.encryption.ciphertext);
44099
44724
  const key = await deriveKey(requireCloudSyncPassphrase(passphrase), salt, snapshot2.encryption.kdfParams);
44100
- const decipher = (0, import_node_crypto14.createDecipheriv)("aes-256-gcm", key, iv);
44725
+ const decipher = (0, import_node_crypto15.createDecipheriv)("aes-256-gcm", key, iv);
44101
44726
  decipher.setAAD(ENCRYPTION_AAD);
44102
44727
  decipher.setAuthTag(tag2);
44103
44728
  const plaintext = Buffer.concat([decipher.update(ciphertext), decipher.final()]);
@@ -44112,7 +44737,7 @@ async function decryptCloudSyncSnapshot(snapshot2, passphrase) {
44112
44737
  }
44113
44738
  }
44114
44739
  function keychainAccountForLicense(licenseKey) {
44115
- const digest = (0, import_node_crypto14.createHash)("sha256").update(licenseKey).digest("hex");
44740
+ const digest = (0, import_node_crypto15.createHash)("sha256").update(licenseKey).digest("hex");
44116
44741
  return KEYCHAIN_ACCOUNT_PREFIX2 + digest;
44117
44742
  }
44118
44743
  function runSecurityCommand2(args2) {
@@ -44678,7 +45303,7 @@ async function handleSync(args2, version) {
44678
45303
  }
44679
45304
 
44680
45305
  // src/commands/workspace.ts
44681
- var import_node_fs13 = require("fs");
45306
+ var import_node_fs14 = require("fs");
44682
45307
  function printWorkspaceHelp() {
44683
45308
  console.log(`Usage:
44684
45309
  codexuse workspace bind <path> <profile>
@@ -44708,7 +45333,7 @@ async function handleWorkspaceCommand(args2) {
44708
45333
  return;
44709
45334
  }
44710
45335
  for (const binding of bindings) {
44711
- const pathState = await import_node_fs13.promises.stat(binding.rootPath).then(() => "").catch(() => " (path missing)");
45336
+ const pathState = await import_node_fs14.promises.stat(binding.rootPath).then(() => "").catch(() => " (path missing)");
44712
45337
  const profileState = profiles.has(binding.profileName) ? "" : " (profile missing)";
44713
45338
  console.log(`${binding.rootPath} -> ${binding.profileName}${pathState}${profileState}`);
44714
45339
  }
@@ -44772,7 +45397,7 @@ async function ensureCliStorageReady() {
44772
45397
  }
44773
45398
 
44774
45399
  // src/app/main.ts
44775
- var VERSION = true ? "6.0.2" : "0.0.0";
45400
+ var VERSION = true ? "6.0.3" : "0.0.0";
44776
45401
  async function runCli() {
44777
45402
  const args2 = process.argv.slice(2);
44778
45403
  if (args2.length === 0) {