codexuse-cli 3.9.8 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +862 -357
- package/dist/index.js.map +1 -1
- package/dist/server/{NodeSqliteClient-Cx2_VxdP.mjs → NodeSqliteClient-ColmybgR.mjs} +2 -2
- package/dist/server/{SqlError-CoqftVSq.mjs → SqlError-Bsa-lRNq.mjs} +1 -1
- package/dist/server/{SqliteClient-CXjquy8x.mjs → SqliteClient-CFZi0MEE.mjs} +2 -2
- package/dist/server/index.mjs +2934 -1749
- package/dist/server/{open-BWXrZXJl.mjs → open-qeX1IlWK.mjs} +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2216,6 +2216,17 @@ var SQLITE_BUSY_MAX_ATTEMPTS = 3;
|
|
|
2216
2216
|
var SQLITE_BUSY_RETRY_DELAY_MS = 100;
|
|
2217
2217
|
var writeQueueByDbPath = /* @__PURE__ */ new Map();
|
|
2218
2218
|
var initializedDbPaths = /* @__PURE__ */ new Set();
|
|
2219
|
+
var AppStorageCorruptionError = class extends Error {
|
|
2220
|
+
constructor(message, options) {
|
|
2221
|
+
super(message);
|
|
2222
|
+
this.name = "AppStorageCorruptionError";
|
|
2223
|
+
this.dbPath = options.dbPath;
|
|
2224
|
+
this.namespace = options.namespace ?? null;
|
|
2225
|
+
if (options.cause !== void 0) {
|
|
2226
|
+
this.cause = options.cause;
|
|
2227
|
+
}
|
|
2228
|
+
}
|
|
2229
|
+
};
|
|
2219
2230
|
function isRecord(value) {
|
|
2220
2231
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
2221
2232
|
}
|
|
@@ -2232,6 +2243,23 @@ function safeParseJson(raw) {
|
|
|
2232
2243
|
return null;
|
|
2233
2244
|
}
|
|
2234
2245
|
}
|
|
2246
|
+
function parseJsonStrict(raw, options) {
|
|
2247
|
+
if (typeof raw !== "string" || raw.trim().length === 0) {
|
|
2248
|
+
return null;
|
|
2249
|
+
}
|
|
2250
|
+
try {
|
|
2251
|
+
return JSON.parse(raw);
|
|
2252
|
+
} catch (error) {
|
|
2253
|
+
throw new AppStorageCorruptionError(
|
|
2254
|
+
`App storage document ${options.namespace} contains invalid JSON.`,
|
|
2255
|
+
{
|
|
2256
|
+
dbPath: options.dbPath,
|
|
2257
|
+
namespace: options.namespace,
|
|
2258
|
+
cause: error
|
|
2259
|
+
}
|
|
2260
|
+
);
|
|
2261
|
+
}
|
|
2262
|
+
}
|
|
2235
2263
|
function sleep(ms) {
|
|
2236
2264
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
2237
2265
|
}
|
|
@@ -2240,9 +2268,32 @@ function isSqliteBusyError(error) {
|
|
|
2240
2268
|
return false;
|
|
2241
2269
|
}
|
|
2242
2270
|
const sqliteError = error;
|
|
2243
|
-
|
|
2271
|
+
if (sqliteError.cause && sqliteError.cause !== error && isSqliteBusyError(sqliteError.cause)) {
|
|
2272
|
+
return true;
|
|
2273
|
+
}
|
|
2274
|
+
if (sqliteError.error && sqliteError.error !== error && isSqliteBusyError(sqliteError.error)) {
|
|
2275
|
+
return true;
|
|
2276
|
+
}
|
|
2277
|
+
const message = typeof sqliteError.message === "string" ? sqliteError.message.toLowerCase() : String(error).toLowerCase();
|
|
2244
2278
|
return sqliteError.code === "SQLITE_BUSY" || sqliteError.errno === 5 || message.includes("sqlite_busy") || message.includes("database is locked");
|
|
2245
2279
|
}
|
|
2280
|
+
function isSqliteCorruptionError(error) {
|
|
2281
|
+
if (!error || typeof error !== "object") {
|
|
2282
|
+
return false;
|
|
2283
|
+
}
|
|
2284
|
+
const sqliteError = error;
|
|
2285
|
+
if (sqliteError.cause && sqliteError.cause !== error && isSqliteCorruptionError(sqliteError.cause)) {
|
|
2286
|
+
return true;
|
|
2287
|
+
}
|
|
2288
|
+
if (sqliteError.error && sqliteError.error !== error && isSqliteCorruptionError(sqliteError.error)) {
|
|
2289
|
+
return true;
|
|
2290
|
+
}
|
|
2291
|
+
const message = typeof sqliteError.message === "string" ? sqliteError.message.toLowerCase() : "";
|
|
2292
|
+
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");
|
|
2293
|
+
}
|
|
2294
|
+
function isAppStorageCorruptionError(error) {
|
|
2295
|
+
return error instanceof AppStorageCorruptionError || isSqliteCorruptionError(error);
|
|
2296
|
+
}
|
|
2246
2297
|
function beginImmediate(db) {
|
|
2247
2298
|
db.exec("BEGIN IMMEDIATE");
|
|
2248
2299
|
}
|
|
@@ -2317,19 +2368,55 @@ async function openDatabase(dbPath) {
|
|
|
2317
2368
|
close: database.close.bind(database)
|
|
2318
2369
|
};
|
|
2319
2370
|
}
|
|
2371
|
+
function resetAppStorageInitialization(dbPath) {
|
|
2372
|
+
initializedDbPaths.delete(dbPath);
|
|
2373
|
+
}
|
|
2374
|
+
async function backupCorruptAppStorageDb(dbPath) {
|
|
2375
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
2376
|
+
const backupPath = `${dbPath}.corrupt-${stamp}`;
|
|
2377
|
+
let moved = false;
|
|
2378
|
+
for (const suffix of ["", "-wal", "-shm"]) {
|
|
2379
|
+
const source = `${dbPath}${suffix}`;
|
|
2380
|
+
const destination = `${backupPath}${suffix}`;
|
|
2381
|
+
try {
|
|
2382
|
+
const stats = await import_node_fs.promises.stat(source);
|
|
2383
|
+
if (!stats.isFile()) {
|
|
2384
|
+
continue;
|
|
2385
|
+
}
|
|
2386
|
+
await import_node_fs.promises.rename(source, destination);
|
|
2387
|
+
moved = true;
|
|
2388
|
+
} catch (error) {
|
|
2389
|
+
if (error.code !== "ENOENT") {
|
|
2390
|
+
throw error;
|
|
2391
|
+
}
|
|
2392
|
+
}
|
|
2393
|
+
}
|
|
2394
|
+
resetAppStorageInitialization(dbPath);
|
|
2395
|
+
return moved ? backupPath : null;
|
|
2396
|
+
}
|
|
2320
2397
|
async function withDatabase(dbPath, task) {
|
|
2321
2398
|
for (let attempt = 1; attempt <= SQLITE_BUSY_MAX_ATTEMPTS; attempt += 1) {
|
|
2322
|
-
|
|
2399
|
+
let db = null;
|
|
2323
2400
|
try {
|
|
2401
|
+
db = await openDatabase(dbPath);
|
|
2324
2402
|
applyConnectionPragmas(db);
|
|
2325
2403
|
ensureSchema(db, dbPath);
|
|
2326
2404
|
return task(db);
|
|
2327
2405
|
} catch (error) {
|
|
2406
|
+
if (error instanceof AppStorageCorruptionError) {
|
|
2407
|
+
throw error;
|
|
2408
|
+
}
|
|
2409
|
+
if (isSqliteCorruptionError(error)) {
|
|
2410
|
+
throw new AppStorageCorruptionError(
|
|
2411
|
+
"App storage database is corrupt.",
|
|
2412
|
+
{ dbPath, cause: error }
|
|
2413
|
+
);
|
|
2414
|
+
}
|
|
2328
2415
|
if (!isSqliteBusyError(error) || attempt >= SQLITE_BUSY_MAX_ATTEMPTS) {
|
|
2329
2416
|
throw error;
|
|
2330
2417
|
}
|
|
2331
2418
|
} finally {
|
|
2332
|
-
db
|
|
2419
|
+
db?.close();
|
|
2333
2420
|
}
|
|
2334
2421
|
await sleep(SQLITE_BUSY_RETRY_DELAY_MS * attempt);
|
|
2335
2422
|
}
|
|
@@ -2352,6 +2439,40 @@ async function readDocument(dbPath, namespace, normalize) {
|
|
|
2352
2439
|
return normalize(parsed);
|
|
2353
2440
|
});
|
|
2354
2441
|
}
|
|
2442
|
+
async function readDocumentStrict(dbPath, namespace, normalize) {
|
|
2443
|
+
return withDatabase(dbPath, (db) => {
|
|
2444
|
+
const row = useStatement(
|
|
2445
|
+
db,
|
|
2446
|
+
`SELECT value_json AS valueJson FROM ${APP_STORAGE_TABLE} WHERE namespace = ?`,
|
|
2447
|
+
(statement) => statement.get(namespace)
|
|
2448
|
+
);
|
|
2449
|
+
if (!isRecord(row)) {
|
|
2450
|
+
return null;
|
|
2451
|
+
}
|
|
2452
|
+
const parsed = parseJsonStrict(row.valueJson, {
|
|
2453
|
+
dbPath,
|
|
2454
|
+
namespace
|
|
2455
|
+
});
|
|
2456
|
+
if (parsed === null) {
|
|
2457
|
+
throw new AppStorageCorruptionError(
|
|
2458
|
+
`App storage document ${namespace} is empty.`,
|
|
2459
|
+
{ dbPath, namespace }
|
|
2460
|
+
);
|
|
2461
|
+
}
|
|
2462
|
+
try {
|
|
2463
|
+
return normalize(parsed);
|
|
2464
|
+
} catch (error) {
|
|
2465
|
+
throw new AppStorageCorruptionError(
|
|
2466
|
+
`App storage document ${namespace} failed normalization.`,
|
|
2467
|
+
{
|
|
2468
|
+
dbPath,
|
|
2469
|
+
namespace,
|
|
2470
|
+
cause: error
|
|
2471
|
+
}
|
|
2472
|
+
);
|
|
2473
|
+
}
|
|
2474
|
+
});
|
|
2475
|
+
}
|
|
2355
2476
|
async function writeDocument(dbPath, namespace, value) {
|
|
2356
2477
|
return withWriteQueue(
|
|
2357
2478
|
dbPath,
|
|
@@ -2624,7 +2745,7 @@ function normalizeAppState(raw) {
|
|
|
2624
2745
|
merged.officialCodex.activity = Array.isArray(merged.officialCodex.activity) ? merged.officialCodex.activity.filter((entry) => isRecord2(entry)).map((entry) => ({
|
|
2625
2746
|
id: asString(entry.id) ?? "",
|
|
2626
2747
|
at: asString(entry.at) ?? (/* @__PURE__ */ new Date(0)).toISOString(),
|
|
2627
|
-
kind: entry.kind === "auto-roll-eval" || entry.kind === "profile-switch" || entry.kind === "auth-verified" || entry.kind === "official-codex-restart" || entry.kind === "low-remaining-alert" ? entry.kind : "auto-roll-eval",
|
|
2748
|
+
kind: entry.kind === "auto-roll-eval" || entry.kind === "profile-switch" || entry.kind === "auth-verified" || entry.kind === "official-codex-restart" || entry.kind === "reset-window-activation" || entry.kind === "low-remaining-alert" ? entry.kind : "auto-roll-eval",
|
|
2628
2749
|
status: asString(entry.status) ?? "unknown",
|
|
2629
2750
|
reason: asString(entry.reason),
|
|
2630
2751
|
decisionId: asString(entry.decisionId),
|
|
@@ -2643,7 +2764,9 @@ function normalizeAppState(raw) {
|
|
|
2643
2764
|
restartResult: asString(entry.restartResult),
|
|
2644
2765
|
observedProfileName: asString(entry.observedProfileName),
|
|
2645
2766
|
observedProfileKeyHash: asString(entry.observedProfileKeyHash),
|
|
2646
|
-
observedProfileMatchSource: asString(
|
|
2767
|
+
observedProfileMatchSource: asString(
|
|
2768
|
+
entry.observedProfileMatchSource
|
|
2769
|
+
)
|
|
2647
2770
|
})).filter((entry) => entry.id && entry.at).slice(-50) : [];
|
|
2648
2771
|
if (!isRecord2(merged.officialCodex.instancesByProfileName)) {
|
|
2649
2772
|
merged.officialCodex.instancesByProfileName = {};
|
|
@@ -2767,7 +2890,9 @@ function normalizeAppState(raw) {
|
|
|
2767
2890
|
merged.ui.profiles.groupBy = asString(merged.ui.profiles.groupBy);
|
|
2768
2891
|
merged.ui.profiles.planFilter = asString(merged.ui.profiles.planFilter);
|
|
2769
2892
|
merged.ui.profiles.healthFilter = asString(merged.ui.profiles.healthFilter);
|
|
2770
|
-
merged.ui.profiles.customGroupFilter = asString(
|
|
2893
|
+
merged.ui.profiles.customGroupFilter = asString(
|
|
2894
|
+
merged.ui.profiles.customGroupFilter
|
|
2895
|
+
);
|
|
2771
2896
|
if (typeof merged.ui.profiles.toolbarOpen !== "boolean") {
|
|
2772
2897
|
merged.ui.profiles.toolbarOpen = null;
|
|
2773
2898
|
}
|
|
@@ -2775,13 +2900,15 @@ function normalizeAppState(raw) {
|
|
|
2775
2900
|
merged.ui.profiles.collapsedSections = {};
|
|
2776
2901
|
} else {
|
|
2777
2902
|
merged.ui.profiles.collapsedSections = Object.fromEntries(
|
|
2778
|
-
Object.entries(merged.ui.profiles.collapsedSections).flatMap(
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2903
|
+
Object.entries(merged.ui.profiles.collapsedSections).flatMap(
|
|
2904
|
+
([key, value]) => {
|
|
2905
|
+
const normalizedKey = asString(key);
|
|
2906
|
+
if (!normalizedKey || typeof value !== "boolean") {
|
|
2907
|
+
return [];
|
|
2908
|
+
}
|
|
2909
|
+
return [[normalizedKey, value]];
|
|
2782
2910
|
}
|
|
2783
|
-
|
|
2784
|
-
})
|
|
2911
|
+
)
|
|
2785
2912
|
);
|
|
2786
2913
|
}
|
|
2787
2914
|
if (!isRecord2(merged.ui.onboarding)) {
|
|
@@ -2810,26 +2937,30 @@ function normalizeAppState(raw) {
|
|
|
2810
2937
|
merged.ui.onboarding.nudgeCooldowns = {};
|
|
2811
2938
|
} else {
|
|
2812
2939
|
merged.ui.onboarding.nudgeCooldowns = Object.fromEntries(
|
|
2813
|
-
Object.entries(merged.ui.onboarding.nudgeCooldowns).flatMap(
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2940
|
+
Object.entries(merged.ui.onboarding.nudgeCooldowns).flatMap(
|
|
2941
|
+
([key, value]) => {
|
|
2942
|
+
const normalizedKey = asString(key);
|
|
2943
|
+
if (!normalizedKey || !Number.isFinite(value)) {
|
|
2944
|
+
return [];
|
|
2945
|
+
}
|
|
2946
|
+
return [[normalizedKey, Number(value)]];
|
|
2817
2947
|
}
|
|
2818
|
-
|
|
2819
|
-
})
|
|
2948
|
+
)
|
|
2820
2949
|
);
|
|
2821
2950
|
}
|
|
2822
2951
|
if (!isRecord2(merged.ui.onboarding.nudgeDismissCount)) {
|
|
2823
2952
|
merged.ui.onboarding.nudgeDismissCount = {};
|
|
2824
2953
|
} else {
|
|
2825
2954
|
merged.ui.onboarding.nudgeDismissCount = Object.fromEntries(
|
|
2826
|
-
Object.entries(merged.ui.onboarding.nudgeDismissCount).flatMap(
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2955
|
+
Object.entries(merged.ui.onboarding.nudgeDismissCount).flatMap(
|
|
2956
|
+
([key, value]) => {
|
|
2957
|
+
const normalizedKey = asString(key);
|
|
2958
|
+
if (!normalizedKey || !Number.isFinite(value)) {
|
|
2959
|
+
return [];
|
|
2960
|
+
}
|
|
2961
|
+
return [[normalizedKey, Number(value)]];
|
|
2830
2962
|
}
|
|
2831
|
-
|
|
2832
|
-
})
|
|
2963
|
+
)
|
|
2833
2964
|
);
|
|
2834
2965
|
}
|
|
2835
2966
|
if (typeof merged.ui.onboarding.proUnlockedCelebrated !== "boolean") {
|
|
@@ -2839,17 +2970,21 @@ function normalizeAppState(raw) {
|
|
|
2839
2970
|
merged.ui.projectThreadSelections = {};
|
|
2840
2971
|
} else {
|
|
2841
2972
|
merged.ui.projectThreadSelections = Object.fromEntries(
|
|
2842
|
-
Object.entries(merged.ui.projectThreadSelections).flatMap(
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2973
|
+
Object.entries(merged.ui.projectThreadSelections).flatMap(
|
|
2974
|
+
([projectId, threadId]) => {
|
|
2975
|
+
const normalizedProjectId = asString(projectId);
|
|
2976
|
+
if (!normalizedProjectId) {
|
|
2977
|
+
return [];
|
|
2978
|
+
}
|
|
2979
|
+
const normalizedThreadId = typeof threadId === "string" && threadId.trim().length > 0 ? threadId.trim() : null;
|
|
2980
|
+
return [[normalizedProjectId, normalizedThreadId]];
|
|
2846
2981
|
}
|
|
2847
|
-
|
|
2848
|
-
return [[normalizedProjectId, normalizedThreadId]];
|
|
2849
|
-
})
|
|
2982
|
+
)
|
|
2850
2983
|
);
|
|
2851
2984
|
}
|
|
2852
|
-
merged.ui.duplicateWarningDismissedKey = asString(
|
|
2985
|
+
merged.ui.duplicateWarningDismissedKey = asString(
|
|
2986
|
+
merged.ui.duplicateWarningDismissedKey
|
|
2987
|
+
);
|
|
2853
2988
|
if (typeof merged.ui.pendingLicenseActivation !== "boolean") {
|
|
2854
2989
|
merged.ui.pendingLicenseActivation = false;
|
|
2855
2990
|
}
|
|
@@ -2868,14 +3003,16 @@ function normalizeAppState(raw) {
|
|
|
2868
3003
|
merged.profileDashboard.customGroupsByAccountKey = {};
|
|
2869
3004
|
} else {
|
|
2870
3005
|
merged.profileDashboard.customGroupsByAccountKey = Object.fromEntries(
|
|
2871
|
-
Object.entries(merged.profileDashboard.customGroupsByAccountKey).flatMap(
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
3006
|
+
Object.entries(merged.profileDashboard.customGroupsByAccountKey).flatMap(
|
|
3007
|
+
([key, value]) => {
|
|
3008
|
+
const normalizedKey = asString(key);
|
|
3009
|
+
const normalizedValue = asString(value);
|
|
3010
|
+
if (!normalizedKey || !normalizedValue) {
|
|
3011
|
+
return [];
|
|
3012
|
+
}
|
|
3013
|
+
return [[normalizedKey, normalizedValue]];
|
|
2876
3014
|
}
|
|
2877
|
-
|
|
2878
|
-
})
|
|
3015
|
+
)
|
|
2879
3016
|
);
|
|
2880
3017
|
}
|
|
2881
3018
|
{
|
|
@@ -2942,7 +3079,9 @@ function normalizeAppState(raw) {
|
|
|
2942
3079
|
}
|
|
2943
3080
|
merged.analytics.anonymousId = asString(merged.analytics.anonymousId);
|
|
2944
3081
|
if (!merged.analytics.anonymousId) {
|
|
2945
|
-
const legacyInstallId = asString(
|
|
3082
|
+
const legacyInstallId = asString(
|
|
3083
|
+
merged.telemetry?.installId
|
|
3084
|
+
);
|
|
2946
3085
|
merged.analytics.anonymousId = legacyInstallId;
|
|
2947
3086
|
}
|
|
2948
3087
|
if (typeof merged.analytics.enabled !== "boolean") {
|
|
@@ -3013,16 +3152,55 @@ async function readLegacyAppStateFromDisk() {
|
|
|
3013
3152
|
}
|
|
3014
3153
|
}
|
|
3015
3154
|
async function readAppStateFromStorage() {
|
|
3016
|
-
return
|
|
3155
|
+
return readDocumentStrict(
|
|
3156
|
+
resolveStorageDbPath(),
|
|
3157
|
+
APP_STATE_DOCUMENT,
|
|
3158
|
+
normalizeAppState
|
|
3159
|
+
);
|
|
3017
3160
|
}
|
|
3018
3161
|
async function writeAppStateToStorage(state) {
|
|
3019
|
-
return writeDocument(
|
|
3162
|
+
return writeDocument(
|
|
3163
|
+
resolveStorageDbPath(),
|
|
3164
|
+
APP_STATE_DOCUMENT,
|
|
3165
|
+
normalizeAppState(state)
|
|
3166
|
+
);
|
|
3167
|
+
}
|
|
3168
|
+
function compactRecoveryMessage(error) {
|
|
3169
|
+
const message = error instanceof Error ? error.message : typeof error === "string" ? error : String(error);
|
|
3170
|
+
return message.replace(/\s+/g, " ").trim().slice(0, 240) || "unknown corruption";
|
|
3171
|
+
}
|
|
3172
|
+
async function recoverCorruptAppStateStorage(error) {
|
|
3173
|
+
const dbPath = resolveStorageDbPath();
|
|
3174
|
+
if (error instanceof AppStorageCorruptionError && error.namespace === APP_STATE_DOCUMENT) {
|
|
3175
|
+
appStateCache = null;
|
|
3176
|
+
resetAppStorageInitialization(dbPath);
|
|
3177
|
+
const legacyState2 = await readLegacyAppStateFromDisk().catch(() => null);
|
|
3178
|
+
const recovered2 = normalizeAppState(legacyState2 ?? null);
|
|
3179
|
+
recovered2.migration.lastError = `Recovered app-state document after corruption (${compactRecoveryMessage(error)}). Shared storage database preserved.`;
|
|
3180
|
+
return writeAppStateToStorage(recovered2);
|
|
3181
|
+
}
|
|
3182
|
+
const backupPath = await backupCorruptAppStorageDb(dbPath);
|
|
3183
|
+
appStateCache = null;
|
|
3184
|
+
resetAppStorageInitialization(dbPath);
|
|
3185
|
+
const legacyState = await readLegacyAppStateFromDisk().catch(() => null);
|
|
3186
|
+
const recovered = normalizeAppState(legacyState ?? null);
|
|
3187
|
+
recovered.migration.lastError = backupPath ? `Recovered app-state storage after corruption (${compactRecoveryMessage(error)}). Backup: ${import_node_path2.default.basename(backupPath)}` : `Recovered app-state storage after corruption (${compactRecoveryMessage(error)}). No existing DB file was present.`;
|
|
3188
|
+
return writeAppStateToStorage(recovered);
|
|
3020
3189
|
}
|
|
3021
3190
|
async function ensureInitialized() {
|
|
3022
3191
|
if (appStateCache) {
|
|
3023
3192
|
return appStateCache;
|
|
3024
3193
|
}
|
|
3025
|
-
|
|
3194
|
+
let loaded = null;
|
|
3195
|
+
try {
|
|
3196
|
+
loaded = await readAppStateFromStorage() ?? await readLegacyAppStateFromDisk();
|
|
3197
|
+
} catch (error) {
|
|
3198
|
+
if (!isAppStorageCorruptionError(error)) {
|
|
3199
|
+
throw error;
|
|
3200
|
+
}
|
|
3201
|
+
appStateCache = await recoverCorruptAppStateStorage(error);
|
|
3202
|
+
return clone2(appStateCache);
|
|
3203
|
+
}
|
|
3026
3204
|
const normalized = loaded ?? normalizeAppState(null);
|
|
3027
3205
|
appStateCache = await writeAppStateToStorage(normalized);
|
|
3028
3206
|
return clone2(appStateCache);
|
|
@@ -3046,7 +3224,11 @@ async function withWriteLock(task) {
|
|
|
3046
3224
|
}
|
|
3047
3225
|
}
|
|
3048
3226
|
async function initializeAppState(userDataDir) {
|
|
3049
|
-
configuredUserDataDir
|
|
3227
|
+
if (configuredUserDataDir !== userDataDir) {
|
|
3228
|
+
configuredUserDataDir = userDataDir;
|
|
3229
|
+
appStateCache = null;
|
|
3230
|
+
resetAppStorageInitialization(resolveStorageDbPath());
|
|
3231
|
+
}
|
|
3050
3232
|
const state = await ensureInitialized();
|
|
3051
3233
|
return clone2(state);
|
|
3052
3234
|
}
|
|
@@ -4037,8 +4219,125 @@ function logInfo(...args) {
|
|
|
4037
4219
|
|
|
4038
4220
|
// ../../packages/runtime-codex/src/codex/rpc.ts
|
|
4039
4221
|
var RPC_TIMEOUT_MS = 1e4;
|
|
4222
|
+
var ACTIVATION_TURN_TIMEOUT_MS = 9e4;
|
|
4223
|
+
var ACTIVATION_PROMPT = "Reply with exactly: ok.";
|
|
4224
|
+
var ACTIVATION_MODEL = "gpt-5.1-codex-mini";
|
|
4040
4225
|
var MAX_STDERR_CAPTURE_CHARS = 32768;
|
|
4041
4226
|
var REFRESH_TOKEN_REDEEMED_SNIPPET = "refresh token was already used";
|
|
4227
|
+
function isRecord4(value) {
|
|
4228
|
+
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
4229
|
+
}
|
|
4230
|
+
function asString3(value) {
|
|
4231
|
+
return typeof value === "string" ? value : value != null ? String(value) : "";
|
|
4232
|
+
}
|
|
4233
|
+
function createRpcMessageReader(rl) {
|
|
4234
|
+
const queue = [];
|
|
4235
|
+
const waiters = [];
|
|
4236
|
+
let closedError = null;
|
|
4237
|
+
const rejectAll = (error) => {
|
|
4238
|
+
closedError = error;
|
|
4239
|
+
while (waiters.length > 0) {
|
|
4240
|
+
const waiter = waiters.shift();
|
|
4241
|
+
clearTimeout(waiter.timer);
|
|
4242
|
+
waiter.reject(error);
|
|
4243
|
+
}
|
|
4244
|
+
};
|
|
4245
|
+
const onLine = (line) => {
|
|
4246
|
+
let parsed;
|
|
4247
|
+
try {
|
|
4248
|
+
parsed = JSON.parse(line);
|
|
4249
|
+
} catch {
|
|
4250
|
+
rejectAll(new Error("codex RPC returned malformed JSON"));
|
|
4251
|
+
return;
|
|
4252
|
+
}
|
|
4253
|
+
const waiterIndex = waiters.findIndex((waiter) => waiter.predicate(parsed));
|
|
4254
|
+
if (waiterIndex >= 0) {
|
|
4255
|
+
const [waiter] = waiters.splice(waiterIndex, 1);
|
|
4256
|
+
clearTimeout(waiter.timer);
|
|
4257
|
+
waiter.resolve(parsed);
|
|
4258
|
+
return;
|
|
4259
|
+
}
|
|
4260
|
+
queue.push(parsed);
|
|
4261
|
+
};
|
|
4262
|
+
const onClose = () => {
|
|
4263
|
+
rejectAll(new Error("codex RPC stream closed before response"));
|
|
4264
|
+
};
|
|
4265
|
+
rl.on("line", onLine);
|
|
4266
|
+
rl.on("close", onClose);
|
|
4267
|
+
return {
|
|
4268
|
+
read(predicate, timeoutMs) {
|
|
4269
|
+
const queuedIndex = queue.findIndex(predicate);
|
|
4270
|
+
if (queuedIndex >= 0) {
|
|
4271
|
+
const [message] = queue.splice(queuedIndex, 1);
|
|
4272
|
+
return Promise.resolve(message);
|
|
4273
|
+
}
|
|
4274
|
+
if (closedError) {
|
|
4275
|
+
return Promise.reject(closedError);
|
|
4276
|
+
}
|
|
4277
|
+
return new Promise((resolve, reject) => {
|
|
4278
|
+
const waiter = {
|
|
4279
|
+
predicate,
|
|
4280
|
+
resolve,
|
|
4281
|
+
reject,
|
|
4282
|
+
timer: setTimeout(
|
|
4283
|
+
() => {
|
|
4284
|
+
const index = waiters.indexOf(waiter);
|
|
4285
|
+
if (index >= 0) {
|
|
4286
|
+
waiters.splice(index, 1);
|
|
4287
|
+
}
|
|
4288
|
+
reject(new Error("codex RPC timed out"));
|
|
4289
|
+
},
|
|
4290
|
+
Math.max(1, timeoutMs)
|
|
4291
|
+
)
|
|
4292
|
+
};
|
|
4293
|
+
waiters.push(waiter);
|
|
4294
|
+
});
|
|
4295
|
+
},
|
|
4296
|
+
dispose() {
|
|
4297
|
+
rl.off("line", onLine);
|
|
4298
|
+
rl.off("close", onClose);
|
|
4299
|
+
while (waiters.length > 0) {
|
|
4300
|
+
const waiter = waiters.shift();
|
|
4301
|
+
clearTimeout(waiter.timer);
|
|
4302
|
+
}
|
|
4303
|
+
}
|
|
4304
|
+
};
|
|
4305
|
+
}
|
|
4306
|
+
function readThreadIdFromResult(result) {
|
|
4307
|
+
if (!isRecord4(result)) return null;
|
|
4308
|
+
const thread = isRecord4(result.thread) ? result.thread : {};
|
|
4309
|
+
const value = asString3(thread.id ?? result.threadId).trim();
|
|
4310
|
+
return value.length > 0 ? value : null;
|
|
4311
|
+
}
|
|
4312
|
+
function readTurnIdFromResult(result) {
|
|
4313
|
+
if (!isRecord4(result)) return null;
|
|
4314
|
+
const turn = isRecord4(result.turn) ? result.turn : {};
|
|
4315
|
+
const value = asString3(turn.id ?? result.turnId).trim();
|
|
4316
|
+
return value.length > 0 ? value : null;
|
|
4317
|
+
}
|
|
4318
|
+
function readTurnIdFromNotification(message) {
|
|
4319
|
+
if (!isRecord4(message.params)) return null;
|
|
4320
|
+
const turn = isRecord4(message.params.turn) ? message.params.turn : {};
|
|
4321
|
+
const value = asString3(turn.id ?? message.params.turnId).trim();
|
|
4322
|
+
return value.length > 0 ? value : null;
|
|
4323
|
+
}
|
|
4324
|
+
function readTurnStatusFromNotification(message) {
|
|
4325
|
+
if (!isRecord4(message.params)) {
|
|
4326
|
+
return { status: null, reason: null };
|
|
4327
|
+
}
|
|
4328
|
+
const turn = isRecord4(message.params.turn) ? message.params.turn : {};
|
|
4329
|
+
const error = isRecord4(turn.error) ? turn.error : null;
|
|
4330
|
+
return {
|
|
4331
|
+
status: asString3(turn.status).trim() || null,
|
|
4332
|
+
reason: error ? asString3(error.message).trim() || null : null
|
|
4333
|
+
};
|
|
4334
|
+
}
|
|
4335
|
+
function readLegacyEventTurnId(message) {
|
|
4336
|
+
if (!isRecord4(message.params)) return null;
|
|
4337
|
+
const msg = isRecord4(message.params.msg) ? message.params.msg : {};
|
|
4338
|
+
const value = asString3(message.params.id ?? msg.turn_id ?? msg.turnId).trim();
|
|
4339
|
+
return value.length > 0 ? value : null;
|
|
4340
|
+
}
|
|
4042
4341
|
function parseTimestamp2(value) {
|
|
4043
4342
|
if (typeof value !== "string" || value.trim().length === 0) {
|
|
4044
4343
|
return null;
|
|
@@ -4089,8 +4388,17 @@ function extractAuthRecencyMs(content) {
|
|
|
4089
4388
|
const rootLastRefresh = parseTimestamp2(parsed.last_refresh);
|
|
4090
4389
|
const nestedLastRefresh = parseTimestamp2(parsed.tokens?.last_refresh);
|
|
4091
4390
|
const rootAccessIssuedAt = extractJwtIssuedAtMs(parsed.access_token);
|
|
4092
|
-
const nestedAccessIssuedAt = extractJwtIssuedAtMs(
|
|
4093
|
-
|
|
4391
|
+
const nestedAccessIssuedAt = extractJwtIssuedAtMs(
|
|
4392
|
+
parsed.tokens?.access_token
|
|
4393
|
+
);
|
|
4394
|
+
const candidates = [
|
|
4395
|
+
rootLastRefresh,
|
|
4396
|
+
nestedLastRefresh,
|
|
4397
|
+
rootAccessIssuedAt,
|
|
4398
|
+
nestedAccessIssuedAt
|
|
4399
|
+
].filter(
|
|
4400
|
+
(value) => typeof value === "number" && Number.isFinite(value)
|
|
4401
|
+
);
|
|
4094
4402
|
if (candidates.length === 0) {
|
|
4095
4403
|
return null;
|
|
4096
4404
|
}
|
|
@@ -4141,10 +4449,13 @@ function isRpcResponseForRequest(message, requestId) {
|
|
|
4141
4449
|
}
|
|
4142
4450
|
async function readRpcResponseById(rl, requestId, timeoutMs) {
|
|
4143
4451
|
return new Promise((resolve, reject) => {
|
|
4144
|
-
const timer = setTimeout(
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
|
|
4452
|
+
const timer = setTimeout(
|
|
4453
|
+
() => {
|
|
4454
|
+
cleanup();
|
|
4455
|
+
reject(new Error("codex RPC timed out"));
|
|
4456
|
+
},
|
|
4457
|
+
Math.max(1, timeoutMs)
|
|
4458
|
+
);
|
|
4148
4459
|
const cleanup = () => {
|
|
4149
4460
|
clearTimeout(timer);
|
|
4150
4461
|
rl.off("line", onLine);
|
|
@@ -4294,7 +4605,11 @@ async function fetchRateLimitsViaRpc(envOverride, options = {}) {
|
|
|
4294
4605
|
throw new Error(formatRpcError("initialize", initializeResponse.error));
|
|
4295
4606
|
}
|
|
4296
4607
|
await sendPayload(child, { method: "initialized", params: {} });
|
|
4297
|
-
await sendPayload(child, {
|
|
4608
|
+
await sendPayload(child, {
|
|
4609
|
+
id: 2,
|
|
4610
|
+
method: "account/rateLimits/read",
|
|
4611
|
+
params: {}
|
|
4612
|
+
});
|
|
4298
4613
|
const message = await readRpcResponseById(rl, 2, RPC_TIMEOUT_MS);
|
|
4299
4614
|
if (message.error) {
|
|
4300
4615
|
const base = formatRpcError("account/rateLimits/read", message.error);
|
|
@@ -4315,11 +4630,181 @@ async function fetchRateLimitsViaRpc(envOverride, options = {}) {
|
|
|
4315
4630
|
if (shouldWriteBackAuth(initialSourceAuth, currentSourceAuth, updatedAuth)) {
|
|
4316
4631
|
await import_node_fs5.promises.writeFile(sourceAuthPath, updatedAuth, "utf8");
|
|
4317
4632
|
} else if (currentSourceAuth && currentSourceAuth !== updatedAuth && currentSourceAuth !== initialSourceAuth) {
|
|
4318
|
-
logWarn(
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
|
|
4633
|
+
logWarn(
|
|
4634
|
+
"Skipped stale auth sync-back after rate-limit probe; source auth changed in flight.",
|
|
4635
|
+
{
|
|
4636
|
+
sourceAuthPath,
|
|
4637
|
+
currentRecencyMs: extractAuthRecencyMs(currentSourceAuth),
|
|
4638
|
+
updatedRecencyMs: extractAuthRecencyMs(updatedAuth)
|
|
4639
|
+
}
|
|
4640
|
+
);
|
|
4641
|
+
}
|
|
4642
|
+
}
|
|
4643
|
+
} catch {
|
|
4644
|
+
}
|
|
4645
|
+
await import_node_fs5.promises.rm(tempHome, { recursive: true, force: true }).catch(() => {
|
|
4646
|
+
});
|
|
4647
|
+
}
|
|
4648
|
+
}
|
|
4649
|
+
async function activateResetWindowViaRpc(envOverride, options = {}) {
|
|
4650
|
+
const binaryPath = options.codexPath ?? await requireCodexCli();
|
|
4651
|
+
const tempHome = await import_node_fs5.promises.mkdtemp(
|
|
4652
|
+
import_node_path6.default.join(import_node_os2.default.tmpdir(), "codex-activation-")
|
|
4653
|
+
);
|
|
4654
|
+
const tempAuthPath = import_node_path6.default.join(tempHome, "auth.json");
|
|
4655
|
+
let initialSourceAuth = null;
|
|
4656
|
+
const sourceAuthPath = options.authPath ?? (envOverride?.CODEX_HOME ? import_node_path6.default.join(envOverride.CODEX_HOME, "auth.json") : import_node_path6.default.join(
|
|
4657
|
+
envOverride?.HOME ?? process.env.HOME ?? process.env.USERPROFILE ?? import_node_os2.default.homedir(),
|
|
4658
|
+
".codex",
|
|
4659
|
+
"auth.json"
|
|
4660
|
+
));
|
|
4661
|
+
try {
|
|
4662
|
+
initialSourceAuth = await import_node_fs5.promises.readFile(sourceAuthPath, "utf8").catch(() => null);
|
|
4663
|
+
if (!initialSourceAuth) {
|
|
4664
|
+
await import_node_fs5.promises.rm(tempHome, { recursive: true, force: true }).catch(() => {
|
|
4665
|
+
});
|
|
4666
|
+
return { status: "skipped", reason: "auth-missing" };
|
|
4667
|
+
}
|
|
4668
|
+
await import_node_fs5.promises.writeFile(tempAuthPath, initialSourceAuth, "utf8");
|
|
4669
|
+
} catch {
|
|
4670
|
+
await import_node_fs5.promises.rm(tempHome, { recursive: true, force: true }).catch(() => {
|
|
4671
|
+
});
|
|
4672
|
+
return { status: "skipped", reason: "auth-missing" };
|
|
4673
|
+
}
|
|
4674
|
+
const childEnv = {
|
|
4675
|
+
...process.env,
|
|
4676
|
+
...envOverride ?? {},
|
|
4677
|
+
HOME: tempHome,
|
|
4678
|
+
USERPROFILE: tempHome,
|
|
4679
|
+
CODEX_HOME: tempHome,
|
|
4680
|
+
CODEX_TELEMETRY_LABEL: "codex-reset-activation",
|
|
4681
|
+
ELECTRON_RUN_AS_NODE: "1"
|
|
4682
|
+
};
|
|
4683
|
+
const command = buildCodexCommand(
|
|
4684
|
+
binaryPath,
|
|
4685
|
+
["-s", "read-only", "-a", "untrusted", "app-server"],
|
|
4686
|
+
childEnv
|
|
4687
|
+
);
|
|
4688
|
+
const child = (0, import_node_child_process2.spawn)(command.command, command.args, {
|
|
4689
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
4690
|
+
env: childEnv,
|
|
4691
|
+
shell: command.shell
|
|
4692
|
+
});
|
|
4693
|
+
const rl = import_node_readline.default.createInterface({
|
|
4694
|
+
input: child.stdout,
|
|
4695
|
+
crlfDelay: Infinity
|
|
4696
|
+
});
|
|
4697
|
+
const reader = createRpcMessageReader(rl);
|
|
4698
|
+
let stderrOutput = "";
|
|
4699
|
+
child.stderr?.on("data", (chunk) => {
|
|
4700
|
+
if (stderrOutput.length >= MAX_STDERR_CAPTURE_CHARS) {
|
|
4701
|
+
return;
|
|
4702
|
+
}
|
|
4703
|
+
const text = chunk.toString("utf8");
|
|
4704
|
+
const remaining = MAX_STDERR_CAPTURE_CHARS - stderrOutput.length;
|
|
4705
|
+
stderrOutput += text.slice(0, Math.max(0, remaining));
|
|
4706
|
+
});
|
|
4707
|
+
try {
|
|
4708
|
+
await sendPayload(child, {
|
|
4709
|
+
id: 1,
|
|
4710
|
+
method: "initialize",
|
|
4711
|
+
params: { clientInfo: { name: "codexuse", version: "0.0.0" } }
|
|
4712
|
+
});
|
|
4713
|
+
const initializeResponse = await reader.read(
|
|
4714
|
+
(message) => isRpcResponseForRequest(message, 1),
|
|
4715
|
+
RPC_TIMEOUT_MS
|
|
4716
|
+
);
|
|
4717
|
+
if (initializeResponse.error) {
|
|
4718
|
+
throw new Error(formatRpcError("initialize", initializeResponse.error));
|
|
4719
|
+
}
|
|
4720
|
+
await sendPayload(child, { method: "initialized", params: {} });
|
|
4721
|
+
await sendPayload(child, {
|
|
4722
|
+
id: 2,
|
|
4723
|
+
method: "thread/start",
|
|
4724
|
+
params: {
|
|
4725
|
+
cwd: tempHome,
|
|
4726
|
+
model: ACTIVATION_MODEL,
|
|
4727
|
+
approvalPolicy: "untrusted",
|
|
4728
|
+
sandbox: "read-only",
|
|
4729
|
+
experimentalRawEvents: false
|
|
4730
|
+
}
|
|
4731
|
+
});
|
|
4732
|
+
const threadResponse = await reader.read(
|
|
4733
|
+
(message) => isRpcResponseForRequest(message, 2),
|
|
4734
|
+
RPC_TIMEOUT_MS
|
|
4735
|
+
);
|
|
4736
|
+
if (threadResponse.error) {
|
|
4737
|
+
throw new Error(formatRpcError("thread/start", threadResponse.error));
|
|
4738
|
+
}
|
|
4739
|
+
const threadId = readThreadIdFromResult(threadResponse.result);
|
|
4740
|
+
if (!threadId) {
|
|
4741
|
+
throw new Error("thread/start response did not include a thread id.");
|
|
4742
|
+
}
|
|
4743
|
+
await sendPayload(child, {
|
|
4744
|
+
id: 3,
|
|
4745
|
+
method: "turn/start",
|
|
4746
|
+
params: {
|
|
4747
|
+
threadId,
|
|
4748
|
+
model: ACTIVATION_MODEL,
|
|
4749
|
+
effort: "low",
|
|
4750
|
+
input: [
|
|
4751
|
+
{
|
|
4752
|
+
type: "text",
|
|
4753
|
+
text: ACTIVATION_PROMPT,
|
|
4754
|
+
text_elements: []
|
|
4755
|
+
}
|
|
4756
|
+
]
|
|
4757
|
+
}
|
|
4758
|
+
});
|
|
4759
|
+
const turnResponse = await reader.read(
|
|
4760
|
+
(message) => isRpcResponseForRequest(message, 3),
|
|
4761
|
+
RPC_TIMEOUT_MS
|
|
4762
|
+
);
|
|
4763
|
+
if (turnResponse.error) {
|
|
4764
|
+
const base = formatRpcError("turn/start", turnResponse.error);
|
|
4765
|
+
const hint = inferRefreshFailureHint(stderrOutput);
|
|
4766
|
+
if (hint && !base.toLowerCase().includes(hint)) {
|
|
4767
|
+
throw new Error(`${base}; ${hint}`);
|
|
4768
|
+
}
|
|
4769
|
+
throw new Error(base);
|
|
4770
|
+
}
|
|
4771
|
+
const turnId = readTurnIdFromResult(turnResponse.result);
|
|
4772
|
+
if (!turnId) {
|
|
4773
|
+
throw new Error("turn/start response did not include a turn id.");
|
|
4774
|
+
}
|
|
4775
|
+
const completed = await reader.read(
|
|
4776
|
+
(message) => message.method === "turn/completed" && readTurnIdFromNotification(message) === turnId || message.method === "codex/event/task_complete" && readLegacyEventTurnId(message) === turnId,
|
|
4777
|
+
ACTIVATION_TURN_TIMEOUT_MS
|
|
4778
|
+
);
|
|
4779
|
+
const turnStatus = readTurnStatusFromNotification(completed);
|
|
4780
|
+
if (turnStatus.status === "failed") {
|
|
4781
|
+
return {
|
|
4782
|
+
status: "failed",
|
|
4783
|
+
reason: turnStatus.reason ?? "turn-failed",
|
|
4784
|
+
threadId,
|
|
4785
|
+
turnId
|
|
4786
|
+
};
|
|
4787
|
+
}
|
|
4788
|
+
return { status: "completed", reason: null, threadId, turnId };
|
|
4789
|
+
} finally {
|
|
4790
|
+
child.kill();
|
|
4791
|
+
reader.dispose();
|
|
4792
|
+
rl.close();
|
|
4793
|
+
try {
|
|
4794
|
+
const updatedAuth = await import_node_fs5.promises.readFile(tempAuthPath, "utf8");
|
|
4795
|
+
if (updatedAuth.trim().length > 0) {
|
|
4796
|
+
const currentSourceAuth = await import_node_fs5.promises.readFile(sourceAuthPath, "utf8").catch(() => null);
|
|
4797
|
+
if (shouldWriteBackAuth(initialSourceAuth, currentSourceAuth, updatedAuth)) {
|
|
4798
|
+
await import_node_fs5.promises.writeFile(sourceAuthPath, updatedAuth, "utf8");
|
|
4799
|
+
} else if (currentSourceAuth && currentSourceAuth !== updatedAuth && currentSourceAuth !== initialSourceAuth) {
|
|
4800
|
+
logWarn(
|
|
4801
|
+
"Skipped stale auth sync-back after reset-window activation; source auth changed in flight.",
|
|
4802
|
+
{
|
|
4803
|
+
sourceAuthPath,
|
|
4804
|
+
currentRecencyMs: extractAuthRecencyMs(currentSourceAuth),
|
|
4805
|
+
updatedRecencyMs: extractAuthRecencyMs(updatedAuth)
|
|
4806
|
+
}
|
|
4807
|
+
);
|
|
4323
4808
|
}
|
|
4324
4809
|
}
|
|
4325
4810
|
} catch {
|
|
@@ -5868,6 +6353,25 @@ var ProfileManager = class {
|
|
|
5868
6353
|
});
|
|
5869
6354
|
}
|
|
5870
6355
|
}
|
|
6356
|
+
async activateResetWindow(name, options = {}) {
|
|
6357
|
+
const profileName = this.normalizeProfileName(name);
|
|
6358
|
+
try {
|
|
6359
|
+
return await this.enqueueProfileOperation(
|
|
6360
|
+
profileName,
|
|
6361
|
+
() => this.runWithPreparedProfileHome(
|
|
6362
|
+
profileName,
|
|
6363
|
+
(env) => activateResetWindowViaRpc(env, { codexPath: options.codexPath }),
|
|
6364
|
+
{ syncFromActiveAuthBeforeAction: false }
|
|
6365
|
+
)
|
|
6366
|
+
);
|
|
6367
|
+
} finally {
|
|
6368
|
+
await this.enqueueAuthSwap(async () => {
|
|
6369
|
+
await this.syncActiveAuthFromProfileIfCurrent(profileName);
|
|
6370
|
+
}).catch((error) => {
|
|
6371
|
+
logWarn(`Failed to sync active auth after reset-window activation for '${profileName}':`, error);
|
|
6372
|
+
});
|
|
6373
|
+
}
|
|
6374
|
+
}
|
|
5871
6375
|
/**
|
|
5872
6376
|
* Rename a profile
|
|
5873
6377
|
*/
|
|
@@ -6320,7 +6824,7 @@ var MODEL_SLUG_ALIASES = {
|
|
|
6320
6824
|
function asRecord2(value) {
|
|
6321
6825
|
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
6322
6826
|
}
|
|
6323
|
-
function
|
|
6827
|
+
function asString4(value) {
|
|
6324
6828
|
if (typeof value !== "string") {
|
|
6325
6829
|
return null;
|
|
6326
6830
|
}
|
|
@@ -6331,7 +6835,7 @@ function asNumber(value) {
|
|
|
6331
6835
|
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
6332
6836
|
}
|
|
6333
6837
|
function normalizeIsoString(value) {
|
|
6334
|
-
const normalized =
|
|
6838
|
+
const normalized = asString4(value);
|
|
6335
6839
|
if (!normalized) {
|
|
6336
6840
|
return null;
|
|
6337
6841
|
}
|
|
@@ -6343,7 +6847,7 @@ function normalizeStringArray(value) {
|
|
|
6343
6847
|
const result = [];
|
|
6344
6848
|
const seen = /* @__PURE__ */ new Set();
|
|
6345
6849
|
for (const entry of input) {
|
|
6346
|
-
const normalized =
|
|
6850
|
+
const normalized = asString4(entry);
|
|
6347
6851
|
if (!normalized || seen.has(normalized)) {
|
|
6348
6852
|
continue;
|
|
6349
6853
|
}
|
|
@@ -6353,7 +6857,7 @@ function normalizeStringArray(value) {
|
|
|
6353
6857
|
return result;
|
|
6354
6858
|
}
|
|
6355
6859
|
function normalizeReasoningEffort(value) {
|
|
6356
|
-
const normalized =
|
|
6860
|
+
const normalized = asString4(value)?.toLowerCase() ?? null;
|
|
6357
6861
|
return normalized && normalized.length > 0 ? normalized : null;
|
|
6358
6862
|
}
|
|
6359
6863
|
function normalizeRoutingStrategy(value) {
|
|
@@ -6387,7 +6891,7 @@ function normalizeAccountPoolExposedModels(value, fallbackToDefault) {
|
|
|
6387
6891
|
const seen = /* @__PURE__ */ new Set();
|
|
6388
6892
|
const input = Array.isArray(value) ? value : [];
|
|
6389
6893
|
for (const entry of input) {
|
|
6390
|
-
const raw =
|
|
6894
|
+
const raw = asString4(entry);
|
|
6391
6895
|
const normalized = normalizeCodexModelSlug(raw) ?? raw;
|
|
6392
6896
|
if (!normalized || seen.has(normalized)) {
|
|
6393
6897
|
continue;
|
|
@@ -6503,8 +7007,8 @@ function normalizeSessionStatus(value) {
|
|
|
6503
7007
|
}
|
|
6504
7008
|
function normalizeApiKeyRecord(id, value) {
|
|
6505
7009
|
const record = asRecord2(value);
|
|
6506
|
-
const tokenHash =
|
|
6507
|
-
const tokenPreview =
|
|
7010
|
+
const tokenHash = asString4(record.tokenHash);
|
|
7011
|
+
const tokenPreview = asString4(record.tokenPreview);
|
|
6508
7012
|
const createdAt = normalizeIsoString(record.createdAt);
|
|
6509
7013
|
if (!tokenHash || !tokenPreview || !createdAt) {
|
|
6510
7014
|
return null;
|
|
@@ -6520,7 +7024,7 @@ function normalizeApiKeyRecord(id, value) {
|
|
|
6520
7024
|
}
|
|
6521
7025
|
function normalizeLegacySessionRecord(id, value) {
|
|
6522
7026
|
const record = asRecord2(value);
|
|
6523
|
-
const profileName =
|
|
7027
|
+
const profileName = asString4(record.profileName);
|
|
6524
7028
|
const createdAt = normalizeIsoString(record.createdAt);
|
|
6525
7029
|
const lastUsedAt = normalizeIsoString(record.lastUsedAt);
|
|
6526
7030
|
if (!profileName || !createdAt || !lastUsedAt) {
|
|
@@ -6530,16 +7034,16 @@ function normalizeLegacySessionRecord(id, value) {
|
|
|
6530
7034
|
return {
|
|
6531
7035
|
id,
|
|
6532
7036
|
affinityKind,
|
|
6533
|
-
affinityKey:
|
|
7037
|
+
affinityKey: asString4(record.affinityKey),
|
|
6534
7038
|
profileName,
|
|
6535
|
-
threadId:
|
|
6536
|
-
model:
|
|
7039
|
+
threadId: asString4(record.threadId) ?? id,
|
|
7040
|
+
model: asString4(record.model),
|
|
6537
7041
|
status: normalizeSessionStatus(record.status),
|
|
6538
|
-
lastError:
|
|
7042
|
+
lastError: asString4(record.lastError),
|
|
6539
7043
|
createdAt,
|
|
6540
7044
|
lastUsedAt,
|
|
6541
7045
|
expiresAt: normalizeIsoString(record.expiresAt),
|
|
6542
|
-
lastResponseId:
|
|
7046
|
+
lastResponseId: asString4(record.lastResponseId),
|
|
6543
7047
|
responseIds: normalizeStringArray(record.responseIds).slice(0, MAX_RESPONSE_IDS_PER_SESSION)
|
|
6544
7048
|
};
|
|
6545
7049
|
}
|
|
@@ -6561,7 +7065,7 @@ function normalizeLegacyStore(value) {
|
|
|
6561
7065
|
}
|
|
6562
7066
|
const responseIndex = {};
|
|
6563
7067
|
for (const [responseId, sessionId] of Object.entries(asRecord2(record.responseIndex))) {
|
|
6564
|
-
const normalizedSessionId =
|
|
7068
|
+
const normalizedSessionId = asString4(sessionId);
|
|
6565
7069
|
if (normalizedSessionId) {
|
|
6566
7070
|
responseIndex[responseId] = normalizedSessionId;
|
|
6567
7071
|
}
|
|
@@ -6576,7 +7080,7 @@ function normalizeLegacyStore(value) {
|
|
|
6576
7080
|
}
|
|
6577
7081
|
function normalizeSessionRecord(id, value) {
|
|
6578
7082
|
const record = asRecord2(value);
|
|
6579
|
-
const activeSegmentId =
|
|
7083
|
+
const activeSegmentId = asString4(record.activeSegmentId);
|
|
6580
7084
|
const createdAt = normalizeIsoString(record.createdAt);
|
|
6581
7085
|
const lastUsedAt = normalizeIsoString(record.lastUsedAt);
|
|
6582
7086
|
if (!activeSegmentId || !createdAt || !lastUsedAt) {
|
|
@@ -6586,25 +7090,25 @@ function normalizeSessionRecord(id, value) {
|
|
|
6586
7090
|
return {
|
|
6587
7091
|
id,
|
|
6588
7092
|
affinityKind,
|
|
6589
|
-
affinityKey:
|
|
7093
|
+
affinityKey: asString4(record.affinityKey),
|
|
6590
7094
|
activeSegmentId,
|
|
6591
7095
|
segmentIds: normalizeStringArray(record.segmentIds),
|
|
6592
|
-
model:
|
|
7096
|
+
model: asString4(record.model),
|
|
6593
7097
|
status: normalizeSessionStatus(record.status),
|
|
6594
|
-
lastError:
|
|
7098
|
+
lastError: asString4(record.lastError),
|
|
6595
7099
|
createdAt,
|
|
6596
7100
|
lastUsedAt,
|
|
6597
7101
|
expiresAt: normalizeIsoString(record.expiresAt),
|
|
6598
|
-
lastResponseId:
|
|
7102
|
+
lastResponseId: asString4(record.lastResponseId),
|
|
6599
7103
|
responseIds: normalizeStringArray(record.responseIds).slice(0, MAX_RESPONSE_IDS_PER_SESSION),
|
|
6600
7104
|
rolloverCount: asNumber(record.rolloverCount) ?? 0,
|
|
6601
|
-
lastRolloverReason:
|
|
7105
|
+
lastRolloverReason: asString4(record.lastRolloverReason)
|
|
6602
7106
|
};
|
|
6603
7107
|
}
|
|
6604
7108
|
function normalizeSegmentRecord(id, value) {
|
|
6605
7109
|
const record = asRecord2(value);
|
|
6606
|
-
const sessionId =
|
|
6607
|
-
const profileName =
|
|
7110
|
+
const sessionId = asString4(record.sessionId);
|
|
7111
|
+
const profileName = asString4(record.profileName);
|
|
6608
7112
|
const createdAt = normalizeIsoString(record.createdAt);
|
|
6609
7113
|
const lastUsedAt = normalizeIsoString(record.lastUsedAt);
|
|
6610
7114
|
if (!sessionId || !profileName || !createdAt || !lastUsedAt) {
|
|
@@ -6620,8 +7124,8 @@ function normalizeSegmentRecord(id, value) {
|
|
|
6620
7124
|
}
|
|
6621
7125
|
function normalizeResponseIndexRecord(value) {
|
|
6622
7126
|
const record = asRecord2(value);
|
|
6623
|
-
const sessionId =
|
|
6624
|
-
const segmentId =
|
|
7127
|
+
const sessionId = asString4(record.sessionId);
|
|
7128
|
+
const segmentId = asString4(record.segmentId);
|
|
6625
7129
|
const createdAt = normalizeIsoString(record.createdAt) ?? (/* @__PURE__ */ new Date(0)).toISOString();
|
|
6626
7130
|
if (!sessionId || !segmentId) {
|
|
6627
7131
|
return null;
|
|
@@ -7296,7 +7800,7 @@ async function handleAccountPoolCommand(args, version) {
|
|
|
7296
7800
|
params,
|
|
7297
7801
|
key: "accountPoolExposedModels",
|
|
7298
7802
|
defaultValues: DEFAULT_ACCOUNT_POOL_EXPOSED_MODELS,
|
|
7299
|
-
normalizeValue: (value) => normalizeCodexModelSlug(value) ??
|
|
7803
|
+
normalizeValue: (value) => normalizeCodexModelSlug(value) ?? asString4(value)
|
|
7300
7804
|
});
|
|
7301
7805
|
return;
|
|
7302
7806
|
case "reasoning":
|
|
@@ -8653,228 +9157,227 @@ async function getOfficialCodexProfileInstances() {
|
|
|
8653
9157
|
};
|
|
8654
9158
|
}
|
|
8655
9159
|
function launchOfficialCodexProfileInstance(options) {
|
|
8656
|
-
return enqueueProfileAction(
|
|
8657
|
-
|
|
8658
|
-
|
|
8659
|
-
|
|
8660
|
-
|
|
8661
|
-
|
|
8662
|
-
|
|
8663
|
-
|
|
8664
|
-
|
|
8665
|
-
|
|
8666
|
-
|
|
8667
|
-
|
|
8668
|
-
|
|
8669
|
-
|
|
8670
|
-
|
|
8671
|
-
|
|
8672
|
-
|
|
8673
|
-
|
|
8674
|
-
|
|
8675
|
-
|
|
8676
|
-
|
|
8677
|
-
|
|
8678
|
-
|
|
8679
|
-
|
|
8680
|
-
|
|
8681
|
-
|
|
8682
|
-
|
|
8683
|
-
|
|
8684
|
-
|
|
8685
|
-
lastError: null
|
|
8686
|
-
};
|
|
8687
|
-
await patchManagedInstance(verified);
|
|
8688
|
-
return {
|
|
8689
|
-
status: "already-running",
|
|
8690
|
-
profileName: options.profileName,
|
|
8691
|
-
instance: managedInstanceToPayload(
|
|
8692
|
-
verified,
|
|
8693
|
-
true,
|
|
8694
|
-
runtime.appServerPid,
|
|
8695
|
-
runtime.startedAt
|
|
8696
|
-
),
|
|
8697
|
-
reason: null
|
|
8698
|
-
};
|
|
8699
|
-
}
|
|
8700
|
-
}
|
|
8701
|
-
const launch = await openCodexWithProfileHome(
|
|
8702
|
-
candidate,
|
|
8703
|
-
options.profileHome,
|
|
8704
|
-
options.profileName,
|
|
8705
|
-
new Set(mainPids)
|
|
8706
|
-
);
|
|
8707
|
-
if (!launch.opened) {
|
|
8708
|
-
const failed = {
|
|
8709
|
-
profileName: options.profileName,
|
|
8710
|
-
profileKey: options.profileKey,
|
|
8711
|
-
profileHome: options.profileHome,
|
|
8712
|
-
appPath: candidate.appPath,
|
|
8713
|
-
bundleId: candidate.bundleId,
|
|
8714
|
-
pid: null,
|
|
8715
|
-
appServerPid: null,
|
|
8716
|
-
launchedAt: null,
|
|
8717
|
-
lastVerifiedAt: null,
|
|
8718
|
-
lastStatus: "failed",
|
|
8719
|
-
lastError: "open-failed"
|
|
8720
|
-
};
|
|
8721
|
-
await patchManagedInstance(failed);
|
|
8722
|
-
return {
|
|
8723
|
-
status: "failed",
|
|
8724
|
-
profileName: options.profileName,
|
|
8725
|
-
instance: managedInstanceToPayload(failed, false),
|
|
8726
|
-
reason: "open-failed"
|
|
8727
|
-
};
|
|
8728
|
-
}
|
|
8729
|
-
const launchedPid = launch.pid;
|
|
8730
|
-
if (launchedPid === null) {
|
|
8731
|
-
const failed = {
|
|
8732
|
-
profileName: options.profileName,
|
|
8733
|
-
profileKey: options.profileKey,
|
|
8734
|
-
profileHome: options.profileHome,
|
|
8735
|
-
appPath: candidate.appPath,
|
|
8736
|
-
bundleId: candidate.bundleId,
|
|
8737
|
-
pid: null,
|
|
8738
|
-
appServerPid: null,
|
|
8739
|
-
launchedAt: null,
|
|
8740
|
-
lastVerifiedAt: null,
|
|
8741
|
-
lastStatus: "failed",
|
|
8742
|
-
lastError: "launch-timeout"
|
|
8743
|
-
};
|
|
8744
|
-
await patchManagedInstance(failed);
|
|
8745
|
-
return {
|
|
8746
|
-
status: "failed",
|
|
8747
|
-
profileName: options.profileName,
|
|
8748
|
-
instance: managedInstanceToPayload(failed, false),
|
|
8749
|
-
reason: "launch-timeout"
|
|
8750
|
-
};
|
|
8751
|
-
}
|
|
8752
|
-
const appServerPid = await waitForAppServerPid(
|
|
8753
|
-
launchedPid,
|
|
8754
|
-
options.profileHome
|
|
8755
|
-
);
|
|
8756
|
-
if (appServerPid === null) {
|
|
8757
|
-
const failed = {
|
|
8758
|
-
profileName: options.profileName,
|
|
8759
|
-
profileKey: options.profileKey,
|
|
8760
|
-
profileHome: options.profileHome,
|
|
8761
|
-
appPath: candidate.appPath,
|
|
8762
|
-
bundleId: candidate.bundleId,
|
|
8763
|
-
pid: null,
|
|
8764
|
-
appServerPid: null,
|
|
8765
|
-
launchedAt: null,
|
|
9160
|
+
return enqueueProfileAction(() => launchOfficialCodexProfileInstanceOnce(options));
|
|
9161
|
+
}
|
|
9162
|
+
async function launchOfficialCodexProfileInstanceOnce(options) {
|
|
9163
|
+
if (process.platform !== "darwin") {
|
|
9164
|
+
return {
|
|
9165
|
+
status: "skipped",
|
|
9166
|
+
profileName: options.profileName,
|
|
9167
|
+
instance: null,
|
|
9168
|
+
reason: "unsupported-platform"
|
|
9169
|
+
};
|
|
9170
|
+
}
|
|
9171
|
+
const { candidate, mainPids } = await resolveCodexAppTarget();
|
|
9172
|
+
if (!candidate) {
|
|
9173
|
+
return {
|
|
9174
|
+
status: "skipped",
|
|
9175
|
+
profileName: options.profileName,
|
|
9176
|
+
instance: null,
|
|
9177
|
+
reason: "official-codex-app-not-found"
|
|
9178
|
+
};
|
|
9179
|
+
}
|
|
9180
|
+
const existing = await readManagedInstance(options.profileName);
|
|
9181
|
+
if (existing) {
|
|
9182
|
+
const rows = await readProcessRows();
|
|
9183
|
+
const runtime = await resolveInstanceRuntimeState({ instance: existing, candidate, rows });
|
|
9184
|
+
if (runtime.running) {
|
|
9185
|
+
const verified = {
|
|
9186
|
+
...existing,
|
|
9187
|
+
profileHome: existing.profileHome ?? options.profileHome,
|
|
9188
|
+
appServerPid: runtime.appServerPid,
|
|
8766
9189
|
lastVerifiedAt: Date.now(),
|
|
8767
|
-
lastStatus: "
|
|
8768
|
-
lastError:
|
|
9190
|
+
lastStatus: "already-running",
|
|
9191
|
+
lastError: null
|
|
8769
9192
|
};
|
|
8770
|
-
await patchManagedInstance(
|
|
9193
|
+
await patchManagedInstance(verified);
|
|
8771
9194
|
return {
|
|
8772
|
-
status: "
|
|
9195
|
+
status: "already-running",
|
|
8773
9196
|
profileName: options.profileName,
|
|
8774
|
-
instance: managedInstanceToPayload(
|
|
8775
|
-
|
|
9197
|
+
instance: managedInstanceToPayload(
|
|
9198
|
+
verified,
|
|
9199
|
+
true,
|
|
9200
|
+
runtime.appServerPid,
|
|
9201
|
+
runtime.startedAt
|
|
9202
|
+
),
|
|
9203
|
+
reason: null
|
|
8776
9204
|
};
|
|
8777
9205
|
}
|
|
8778
|
-
|
|
8779
|
-
|
|
9206
|
+
}
|
|
9207
|
+
const launch = await openCodexWithProfileHome(
|
|
9208
|
+
candidate,
|
|
9209
|
+
options.profileHome,
|
|
9210
|
+
options.profileName,
|
|
9211
|
+
new Set(mainPids)
|
|
9212
|
+
);
|
|
9213
|
+
if (!launch.opened) {
|
|
9214
|
+
const failed = {
|
|
8780
9215
|
profileName: options.profileName,
|
|
8781
9216
|
profileKey: options.profileKey,
|
|
8782
9217
|
profileHome: options.profileHome,
|
|
8783
9218
|
appPath: candidate.appPath,
|
|
8784
9219
|
bundleId: candidate.bundleId,
|
|
8785
|
-
pid:
|
|
8786
|
-
appServerPid,
|
|
8787
|
-
launchedAt:
|
|
8788
|
-
lastVerifiedAt:
|
|
8789
|
-
lastStatus: "
|
|
8790
|
-
lastError:
|
|
9220
|
+
pid: null,
|
|
9221
|
+
appServerPid: null,
|
|
9222
|
+
launchedAt: null,
|
|
9223
|
+
lastVerifiedAt: null,
|
|
9224
|
+
lastStatus: "failed",
|
|
9225
|
+
lastError: "open-failed"
|
|
8791
9226
|
};
|
|
8792
|
-
await patchManagedInstance(
|
|
9227
|
+
await patchManagedInstance(failed);
|
|
8793
9228
|
return {
|
|
8794
|
-
status: "
|
|
9229
|
+
status: "failed",
|
|
8795
9230
|
profileName: options.profileName,
|
|
8796
|
-
instance: managedInstanceToPayload(
|
|
8797
|
-
reason:
|
|
9231
|
+
instance: managedInstanceToPayload(failed, false),
|
|
9232
|
+
reason: "open-failed"
|
|
8798
9233
|
};
|
|
8799
|
-
}
|
|
9234
|
+
}
|
|
9235
|
+
const launchedPid = launch.pid;
|
|
9236
|
+
if (launchedPid === null) {
|
|
9237
|
+
const failed = {
|
|
9238
|
+
profileName: options.profileName,
|
|
9239
|
+
profileKey: options.profileKey,
|
|
9240
|
+
profileHome: options.profileHome,
|
|
9241
|
+
appPath: candidate.appPath,
|
|
9242
|
+
bundleId: candidate.bundleId,
|
|
9243
|
+
pid: null,
|
|
9244
|
+
appServerPid: null,
|
|
9245
|
+
launchedAt: null,
|
|
9246
|
+
lastVerifiedAt: null,
|
|
9247
|
+
lastStatus: "failed",
|
|
9248
|
+
lastError: "launch-timeout"
|
|
9249
|
+
};
|
|
9250
|
+
await patchManagedInstance(failed);
|
|
9251
|
+
return {
|
|
9252
|
+
status: "failed",
|
|
9253
|
+
profileName: options.profileName,
|
|
9254
|
+
instance: managedInstanceToPayload(failed, false),
|
|
9255
|
+
reason: "launch-timeout"
|
|
9256
|
+
};
|
|
9257
|
+
}
|
|
9258
|
+
const appServerPid = await waitForAppServerPid(
|
|
9259
|
+
launchedPid,
|
|
9260
|
+
options.profileHome
|
|
9261
|
+
);
|
|
9262
|
+
if (appServerPid === null) {
|
|
9263
|
+
const failed = {
|
|
9264
|
+
profileName: options.profileName,
|
|
9265
|
+
profileKey: options.profileKey,
|
|
9266
|
+
profileHome: options.profileHome,
|
|
9267
|
+
appPath: candidate.appPath,
|
|
9268
|
+
bundleId: candidate.bundleId,
|
|
9269
|
+
pid: null,
|
|
9270
|
+
appServerPid: null,
|
|
9271
|
+
launchedAt: null,
|
|
9272
|
+
lastVerifiedAt: Date.now(),
|
|
9273
|
+
lastStatus: "failed",
|
|
9274
|
+
lastError: "app-server-not-verified"
|
|
9275
|
+
};
|
|
9276
|
+
await patchManagedInstance(failed);
|
|
9277
|
+
return {
|
|
9278
|
+
status: "failed",
|
|
9279
|
+
profileName: options.profileName,
|
|
9280
|
+
instance: managedInstanceToPayload(failed, false),
|
|
9281
|
+
reason: "app-server-not-verified"
|
|
9282
|
+
};
|
|
9283
|
+
}
|
|
9284
|
+
const now = Date.now();
|
|
9285
|
+
const instance = {
|
|
9286
|
+
profileName: options.profileName,
|
|
9287
|
+
profileKey: options.profileKey,
|
|
9288
|
+
profileHome: options.profileHome,
|
|
9289
|
+
appPath: candidate.appPath,
|
|
9290
|
+
bundleId: candidate.bundleId,
|
|
9291
|
+
pid: launchedPid,
|
|
9292
|
+
appServerPid,
|
|
9293
|
+
launchedAt: now,
|
|
9294
|
+
lastVerifiedAt: now,
|
|
9295
|
+
lastStatus: "started",
|
|
9296
|
+
lastError: null
|
|
9297
|
+
};
|
|
9298
|
+
await patchManagedInstance(instance);
|
|
9299
|
+
return {
|
|
9300
|
+
status: "started",
|
|
9301
|
+
profileName: options.profileName,
|
|
9302
|
+
instance: managedInstanceToPayload(instance, true, appServerPid),
|
|
9303
|
+
reason: null
|
|
9304
|
+
};
|
|
8800
9305
|
}
|
|
8801
|
-
function
|
|
8802
|
-
|
|
8803
|
-
|
|
8804
|
-
|
|
8805
|
-
|
|
8806
|
-
|
|
8807
|
-
|
|
8808
|
-
|
|
8809
|
-
|
|
8810
|
-
|
|
8811
|
-
|
|
8812
|
-
|
|
8813
|
-
|
|
8814
|
-
const stopped2 = {
|
|
8815
|
-
...existing,
|
|
8816
|
-
pid: null,
|
|
8817
|
-
appServerPid: null,
|
|
8818
|
-
lastVerifiedAt: Date.now(),
|
|
8819
|
-
lastStatus: "not-running",
|
|
8820
|
-
lastError: "official-codex-app-not-found"
|
|
8821
|
-
};
|
|
8822
|
-
await patchManagedInstance(stopped2);
|
|
8823
|
-
return {
|
|
8824
|
-
status: "not-running",
|
|
8825
|
-
profileName,
|
|
8826
|
-
instance: managedInstanceToPayload(stopped2, false),
|
|
8827
|
-
reason: "official-codex-app-not-found"
|
|
8828
|
-
};
|
|
8829
|
-
}
|
|
8830
|
-
const rows = await readProcessRows();
|
|
8831
|
-
const runtime = await resolveInstanceRuntimeState({ instance: existing, candidate, rows });
|
|
8832
|
-
if (!runtime.running || !existing.pid) {
|
|
8833
|
-
const stopped2 = {
|
|
8834
|
-
...existing,
|
|
8835
|
-
pid: null,
|
|
8836
|
-
appServerPid: null,
|
|
8837
|
-
lastVerifiedAt: Date.now(),
|
|
8838
|
-
lastStatus: "not-running",
|
|
8839
|
-
lastError: null
|
|
8840
|
-
};
|
|
8841
|
-
await patchManagedInstance(stopped2);
|
|
8842
|
-
return {
|
|
8843
|
-
status: "not-running",
|
|
8844
|
-
profileName,
|
|
8845
|
-
instance: managedInstanceToPayload(stopped2, false),
|
|
8846
|
-
reason: null
|
|
8847
|
-
};
|
|
8848
|
-
}
|
|
8849
|
-
const tree = [existing.pid, ...getDescendantPids(existing.pid, rows)].filter((pid, index, all) => all.indexOf(pid) === index).sort((a, b) => b - a);
|
|
8850
|
-
await signalPids(tree, "SIGTERM");
|
|
8851
|
-
const exited = await waitForMainPidExit(existing.pid, 5e3);
|
|
8852
|
-
if (!exited) {
|
|
8853
|
-
await signalPids(tree, "SIGKILL");
|
|
8854
|
-
await waitForMainPidExit(existing.pid, EXIT_WAIT_MS);
|
|
8855
|
-
}
|
|
8856
|
-
const stillRunning = (await readProcessRows()).some((row) => row.pid === existing.pid);
|
|
8857
|
-
const stopped = {
|
|
9306
|
+
async function stopOfficialCodexProfileInstanceOnce(profileName) {
|
|
9307
|
+
const existing = await readManagedInstance(profileName);
|
|
9308
|
+
if (!existing) {
|
|
9309
|
+
return {
|
|
9310
|
+
status: "not-running",
|
|
9311
|
+
profileName,
|
|
9312
|
+
instance: null,
|
|
9313
|
+
reason: "not-managed"
|
|
9314
|
+
};
|
|
9315
|
+
}
|
|
9316
|
+
const { candidate } = await resolveCodexAppTarget();
|
|
9317
|
+
if (!candidate) {
|
|
9318
|
+
const stopped2 = {
|
|
8858
9319
|
...existing,
|
|
8859
|
-
pid:
|
|
8860
|
-
appServerPid:
|
|
9320
|
+
pid: null,
|
|
9321
|
+
appServerPid: null,
|
|
8861
9322
|
lastVerifiedAt: Date.now(),
|
|
8862
|
-
lastStatus:
|
|
8863
|
-
lastError:
|
|
9323
|
+
lastStatus: "not-running",
|
|
9324
|
+
lastError: "official-codex-app-not-found"
|
|
8864
9325
|
};
|
|
8865
|
-
await patchManagedInstance(
|
|
9326
|
+
await patchManagedInstance(stopped2);
|
|
8866
9327
|
return {
|
|
8867
|
-
status:
|
|
9328
|
+
status: "not-running",
|
|
8868
9329
|
profileName,
|
|
8869
|
-
instance: managedInstanceToPayload(
|
|
8870
|
-
|
|
8871
|
-
stillRunning,
|
|
8872
|
-
stopped.appServerPid,
|
|
8873
|
-
runtime.startedAt
|
|
8874
|
-
),
|
|
8875
|
-
reason: stillRunning ? "stop-timeout" : null
|
|
9330
|
+
instance: managedInstanceToPayload(stopped2, false),
|
|
9331
|
+
reason: "official-codex-app-not-found"
|
|
8876
9332
|
};
|
|
8877
|
-
}
|
|
9333
|
+
}
|
|
9334
|
+
const rows = await readProcessRows();
|
|
9335
|
+
const runtime = await resolveInstanceRuntimeState({ instance: existing, candidate, rows });
|
|
9336
|
+
if (!runtime.running || !existing.pid) {
|
|
9337
|
+
const stopped2 = {
|
|
9338
|
+
...existing,
|
|
9339
|
+
pid: null,
|
|
9340
|
+
appServerPid: null,
|
|
9341
|
+
lastVerifiedAt: Date.now(),
|
|
9342
|
+
lastStatus: "not-running",
|
|
9343
|
+
lastError: null
|
|
9344
|
+
};
|
|
9345
|
+
await patchManagedInstance(stopped2);
|
|
9346
|
+
return {
|
|
9347
|
+
status: "not-running",
|
|
9348
|
+
profileName,
|
|
9349
|
+
instance: managedInstanceToPayload(stopped2, false),
|
|
9350
|
+
reason: null
|
|
9351
|
+
};
|
|
9352
|
+
}
|
|
9353
|
+
const tree = [existing.pid, ...getDescendantPids(existing.pid, rows)].filter((pid, index, all) => all.indexOf(pid) === index).sort((a, b) => b - a);
|
|
9354
|
+
await signalPids(tree, "SIGTERM");
|
|
9355
|
+
const exited = await waitForMainPidExit(existing.pid, 5e3);
|
|
9356
|
+
if (!exited) {
|
|
9357
|
+
await signalPids(tree, "SIGKILL");
|
|
9358
|
+
await waitForMainPidExit(existing.pid, EXIT_WAIT_MS);
|
|
9359
|
+
}
|
|
9360
|
+
const stillRunning = (await readProcessRows()).some((row) => row.pid === existing.pid);
|
|
9361
|
+
const stopped = {
|
|
9362
|
+
...existing,
|
|
9363
|
+
pid: stillRunning ? existing.pid : null,
|
|
9364
|
+
appServerPid: stillRunning ? runtime.appServerPid : null,
|
|
9365
|
+
lastVerifiedAt: Date.now(),
|
|
9366
|
+
lastStatus: stillRunning ? "failed" : "stopped",
|
|
9367
|
+
lastError: stillRunning ? "stop-timeout" : null
|
|
9368
|
+
};
|
|
9369
|
+
await patchManagedInstance(stopped);
|
|
9370
|
+
return {
|
|
9371
|
+
status: stillRunning ? "failed" : "stopped",
|
|
9372
|
+
profileName,
|
|
9373
|
+
instance: managedInstanceToPayload(
|
|
9374
|
+
stopped,
|
|
9375
|
+
stillRunning,
|
|
9376
|
+
stopped.appServerPid,
|
|
9377
|
+
runtime.startedAt
|
|
9378
|
+
),
|
|
9379
|
+
reason: stillRunning ? "stop-timeout" : null
|
|
9380
|
+
};
|
|
8878
9381
|
}
|
|
8879
9382
|
function stopOfficialCodexObservedProfileInstance(profileName, pid, appServerPid) {
|
|
8880
9383
|
return enqueueProfileAction(async () => {
|
|
@@ -8930,15 +9433,17 @@ function stopOfficialCodexObservedProfileInstance(profileName, pid, appServerPid
|
|
|
8930
9433
|
});
|
|
8931
9434
|
}
|
|
8932
9435
|
async function restartOfficialCodexProfileInstance(options) {
|
|
8933
|
-
|
|
8934
|
-
|
|
8935
|
-
|
|
8936
|
-
|
|
8937
|
-
|
|
8938
|
-
|
|
8939
|
-
|
|
8940
|
-
|
|
8941
|
-
|
|
9436
|
+
return enqueueProfileAction(async () => {
|
|
9437
|
+
const stopped = await stopOfficialCodexProfileInstanceOnce(options.profileName);
|
|
9438
|
+
if (stopped.status === "failed") {
|
|
9439
|
+
return stopped;
|
|
9440
|
+
}
|
|
9441
|
+
const launched = await launchOfficialCodexProfileInstanceOnce(options);
|
|
9442
|
+
return {
|
|
9443
|
+
...launched,
|
|
9444
|
+
status: launched.status === "started" ? "restarted" : launched.status
|
|
9445
|
+
};
|
|
9446
|
+
});
|
|
8942
9447
|
}
|
|
8943
9448
|
|
|
8944
9449
|
// src/commands/profile.ts
|
|
@@ -9941,7 +10446,7 @@ var import_node_path15 = __toESM(require("path"), 1);
|
|
|
9941
10446
|
var CLOUD_SYNC_SCHEMA_VERSION = 1;
|
|
9942
10447
|
|
|
9943
10448
|
// ../../packages/shared/src/core/type-guards.ts
|
|
9944
|
-
function
|
|
10449
|
+
function isRecord5(value) {
|
|
9945
10450
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
9946
10451
|
}
|
|
9947
10452
|
function toIsoOrNull(value) {
|
|
@@ -9979,10 +10484,10 @@ function buildSyncUrl(pathname) {
|
|
|
9979
10484
|
return `${baseUrl}${normalizedPath}`;
|
|
9980
10485
|
}
|
|
9981
10486
|
function normalizeSnapshot(value) {
|
|
9982
|
-
if (!
|
|
10487
|
+
if (!isRecord5(value)) {
|
|
9983
10488
|
return null;
|
|
9984
10489
|
}
|
|
9985
|
-
if (
|
|
10490
|
+
if (isRecord5(value.snapshot)) {
|
|
9986
10491
|
const nested = normalizeSnapshot(value.snapshot);
|
|
9987
10492
|
if (nested) {
|
|
9988
10493
|
return nested;
|
|
@@ -9997,9 +10502,9 @@ function normalizeSnapshot(value) {
|
|
|
9997
10502
|
return null;
|
|
9998
10503
|
}
|
|
9999
10504
|
const rawProfiles = Array.isArray(value.profiles) ? value.profiles : [];
|
|
10000
|
-
const profiles = rawProfiles.map((entry) =>
|
|
10001
|
-
const data =
|
|
10002
|
-
const metadata =
|
|
10505
|
+
const profiles = rawProfiles.map((entry) => isRecord5(entry) ? entry : null).filter((entry) => Boolean(entry)).map((entry) => {
|
|
10506
|
+
const data = isRecord5(entry.data) ? entry.data : {};
|
|
10507
|
+
const metadata = isRecord5(entry.metadata) ? entry.metadata : void 0;
|
|
10003
10508
|
return {
|
|
10004
10509
|
name: typeof entry.name === "string" ? entry.name : "",
|
|
10005
10510
|
displayName: typeof entry.displayName === "string" ? entry.displayName : null,
|
|
@@ -10015,7 +10520,7 @@ function normalizeSnapshot(value) {
|
|
|
10015
10520
|
};
|
|
10016
10521
|
}).filter((entry) => entry.name.trim().length > 0);
|
|
10017
10522
|
const rawSettings = value.settingsJson;
|
|
10018
|
-
const settingsJson =
|
|
10523
|
+
const settingsJson = isRecord5(rawSettings) ? rawSettings : null;
|
|
10019
10524
|
return {
|
|
10020
10525
|
schemaVersion: CLOUD_SYNC_SCHEMA_VERSION,
|
|
10021
10526
|
updatedAt,
|
|
@@ -10199,7 +10704,7 @@ var FALLBACK_FEATURE_KEYS = [
|
|
|
10199
10704
|
];
|
|
10200
10705
|
var metadataCache = null;
|
|
10201
10706
|
var metadataCacheAt = 0;
|
|
10202
|
-
function
|
|
10707
|
+
function isRecord6(value) {
|
|
10203
10708
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
10204
10709
|
}
|
|
10205
10710
|
function uniqueSorted(values) {
|
|
@@ -10264,16 +10769,16 @@ function parseFeatureCatalog(output) {
|
|
|
10264
10769
|
}
|
|
10265
10770
|
function parseSchemaKeys(schemaRaw) {
|
|
10266
10771
|
const parsed = JSON.parse(schemaRaw);
|
|
10267
|
-
if (!
|
|
10772
|
+
if (!isRecord6(parsed)) {
|
|
10268
10773
|
return {
|
|
10269
10774
|
topLevelKeys: FALLBACK_SCHEMA_TOP_LEVEL_KEYS,
|
|
10270
10775
|
featureKeys: FALLBACK_FEATURE_KEYS
|
|
10271
10776
|
};
|
|
10272
10777
|
}
|
|
10273
|
-
const properties =
|
|
10778
|
+
const properties = isRecord6(parsed.properties) ? parsed.properties : {};
|
|
10274
10779
|
const topLevelKeys = uniqueSorted(Object.keys(properties));
|
|
10275
|
-
const features =
|
|
10276
|
-
const featureProperties =
|
|
10780
|
+
const features = isRecord6(properties.features) ? properties.features : {};
|
|
10781
|
+
const featureProperties = isRecord6(features.properties) ? features.properties : {};
|
|
10277
10782
|
const featureKeys = uniqueSorted(Object.keys(featureProperties));
|
|
10278
10783
|
return {
|
|
10279
10784
|
topLevelKeys: topLevelKeys.length > 0 ? topLevelKeys : FALLBACK_SCHEMA_TOP_LEVEL_KEYS,
|
|
@@ -11059,15 +11564,15 @@ var SYNC_SIZE_WARN_BYTES = 1 * 1024 * 1024;
|
|
|
11059
11564
|
var SYNC_SIZE_MAX_BYTES = 5 * 1024 * 1024;
|
|
11060
11565
|
var MB_DIVISOR = 1024 * 1024;
|
|
11061
11566
|
function mapProfilesFromAppState(raw) {
|
|
11062
|
-
if (!
|
|
11567
|
+
if (!isRecord5(raw)) {
|
|
11063
11568
|
return [];
|
|
11064
11569
|
}
|
|
11065
11570
|
const profiles = [];
|
|
11066
11571
|
for (const [name, value] of Object.entries(raw)) {
|
|
11067
|
-
if (!
|
|
11572
|
+
if (!isRecord5(value)) {
|
|
11068
11573
|
continue;
|
|
11069
11574
|
}
|
|
11070
|
-
const data =
|
|
11575
|
+
const data = isRecord5(value.data) ? value.data : null;
|
|
11071
11576
|
if (!data) {
|
|
11072
11577
|
continue;
|
|
11073
11578
|
}
|
|
@@ -11079,7 +11584,7 @@ function mapProfilesFromAppState(raw) {
|
|
|
11079
11584
|
name: normalizedName,
|
|
11080
11585
|
displayName: typeof value.displayName === "string" ? value.displayName : null,
|
|
11081
11586
|
data,
|
|
11082
|
-
metadata:
|
|
11587
|
+
metadata: isRecord5(value.metadata) ? value.metadata : void 0,
|
|
11083
11588
|
accountId: typeof value.accountId === "string" ? value.accountId : null,
|
|
11084
11589
|
workspaceId: typeof value.workspaceId === "string" ? value.workspaceId : null,
|
|
11085
11590
|
workspaceName: typeof value.workspaceName === "string" ? value.workspaceName : null,
|
|
@@ -11093,7 +11598,7 @@ function mapProfilesFromAppState(raw) {
|
|
|
11093
11598
|
}
|
|
11094
11599
|
function summarizeSnapshot(snapshot) {
|
|
11095
11600
|
const configBytes = typeof snapshot.configTomlContent === "string" ? snapshot.configTomlContent.length : 0;
|
|
11096
|
-
const settingsKeys =
|
|
11601
|
+
const settingsKeys = isRecord5(snapshot.settingsJson) ? Object.keys(snapshot.settingsJson).length : 0;
|
|
11097
11602
|
return {
|
|
11098
11603
|
profiles: snapshot.profiles.length,
|
|
11099
11604
|
configBytes,
|
|
@@ -11198,7 +11703,7 @@ async function buildLocalSnapshot(profileManager, options = {}) {
|
|
|
11198
11703
|
const settingsJson = await readCodexSettingsJsonRaw();
|
|
11199
11704
|
const hasProfiles = profiles.length > 0;
|
|
11200
11705
|
const hasConfig = typeof config.content === "string" && config.content.trim().length > 0;
|
|
11201
|
-
const hasSettings =
|
|
11706
|
+
const hasSettings = isRecord5(settingsJson) && Object.keys(settingsJson).length > 0;
|
|
11202
11707
|
if (enforcePushGuards && !hasProfiles && !hasConfig && !hasSettings) {
|
|
11203
11708
|
throw new Error("Refusing to push an empty cloud sync snapshot.");
|
|
11204
11709
|
}
|
|
@@ -11222,7 +11727,7 @@ async function applyRemoteSnapshot(profileManager, snapshot) {
|
|
|
11222
11727
|
codexHomePath: runtimeContext.codexHomePath
|
|
11223
11728
|
});
|
|
11224
11729
|
}
|
|
11225
|
-
if (snapshot.settingsJson &&
|
|
11730
|
+
if (snapshot.settingsJson && isRecord5(snapshot.settingsJson)) {
|
|
11226
11731
|
await writeCodexSettingsJsonRaw(snapshot.settingsJson);
|
|
11227
11732
|
} else {
|
|
11228
11733
|
await writeCodexSettingsJsonRaw({});
|
|
@@ -11475,10 +11980,10 @@ var LEGACY_SKILL_CACHE_DIR = "skill-cache";
|
|
|
11475
11980
|
var LEGACY_SKILLS_REPOS_FILE = "repos.json";
|
|
11476
11981
|
var LEGACY_SKILL_MANIFEST = ".codexuse-skill.json";
|
|
11477
11982
|
var LEGACY_LICENSE_SECRET_FILE2 = "license.secret";
|
|
11478
|
-
function
|
|
11983
|
+
function isRecord7(value) {
|
|
11479
11984
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
11480
11985
|
}
|
|
11481
|
-
function
|
|
11986
|
+
function asString5(value) {
|
|
11482
11987
|
if (typeof value !== "string") {
|
|
11483
11988
|
return null;
|
|
11484
11989
|
}
|
|
@@ -11647,7 +12152,7 @@ function pickAutoRoll(raw) {
|
|
|
11647
12152
|
}
|
|
11648
12153
|
}
|
|
11649
12154
|
function parseLegacyLicense(raw) {
|
|
11650
|
-
if (!
|
|
12155
|
+
if (!isRecord7(raw)) {
|
|
11651
12156
|
return {
|
|
11652
12157
|
licenseKey: null,
|
|
11653
12158
|
purchaseEmail: null,
|
|
@@ -11658,25 +12163,25 @@ function parseLegacyLicense(raw) {
|
|
|
11658
12163
|
signature: null
|
|
11659
12164
|
};
|
|
11660
12165
|
}
|
|
11661
|
-
const statusCandidate =
|
|
12166
|
+
const statusCandidate = asString5(raw.status);
|
|
11662
12167
|
const status = ["inactive", "active", "grace", "error"].includes(statusCandidate ?? "") ? statusCandidate : "inactive";
|
|
11663
12168
|
return {
|
|
11664
|
-
licenseKey:
|
|
11665
|
-
purchaseEmail:
|
|
11666
|
-
lastVerifiedAt:
|
|
11667
|
-
nextCheckAt:
|
|
11668
|
-
lastVerificationError:
|
|
12169
|
+
licenseKey: asString5(raw.licenseKey ?? raw.license_key),
|
|
12170
|
+
purchaseEmail: asString5(raw.purchaseEmail ?? raw.purchase_email),
|
|
12171
|
+
lastVerifiedAt: asString5(raw.lastVerifiedAt ?? raw.last_verified_at),
|
|
12172
|
+
nextCheckAt: asString5(raw.nextCheckAt ?? raw.next_check_at),
|
|
12173
|
+
lastVerificationError: asString5(raw.lastVerificationError ?? raw.last_verification_error),
|
|
11669
12174
|
status,
|
|
11670
|
-
signature:
|
|
12175
|
+
signature: asString5(raw.signature)
|
|
11671
12176
|
};
|
|
11672
12177
|
}
|
|
11673
12178
|
function parseLegacyProfileRecord(name, raw) {
|
|
11674
|
-
if (!
|
|
12179
|
+
if (!isRecord7(raw)) {
|
|
11675
12180
|
return null;
|
|
11676
12181
|
}
|
|
11677
12182
|
const dataRaw = raw.data;
|
|
11678
12183
|
let data = null;
|
|
11679
|
-
if (
|
|
12184
|
+
if (isRecord7(dataRaw)) {
|
|
11680
12185
|
data = dataRaw;
|
|
11681
12186
|
} else if (typeof dataRaw === "string") {
|
|
11682
12187
|
try {
|
|
@@ -11690,31 +12195,31 @@ function parseLegacyProfileRecord(name, raw) {
|
|
|
11690
12195
|
}
|
|
11691
12196
|
return {
|
|
11692
12197
|
name,
|
|
11693
|
-
displayName:
|
|
12198
|
+
displayName: asString5(raw.displayName ?? raw.display_name) ?? name,
|
|
11694
12199
|
data,
|
|
11695
|
-
metadata:
|
|
11696
|
-
accountId:
|
|
11697
|
-
workspaceId:
|
|
11698
|
-
workspaceName:
|
|
11699
|
-
email:
|
|
11700
|
-
authMethod:
|
|
11701
|
-
createdAt:
|
|
11702
|
-
updatedAt:
|
|
12200
|
+
metadata: isRecord7(raw.metadata) ? raw.metadata : void 0,
|
|
12201
|
+
accountId: asString5(raw.accountId ?? raw.account_id),
|
|
12202
|
+
workspaceId: asString5(raw.workspaceId ?? raw.workspace_id),
|
|
12203
|
+
workspaceName: asString5(raw.workspaceName ?? raw.workspace_name),
|
|
12204
|
+
email: asString5(raw.email),
|
|
12205
|
+
authMethod: asString5(raw.authMethod ?? raw.auth_method),
|
|
12206
|
+
createdAt: asString5(raw.createdAt ?? raw.created_at),
|
|
12207
|
+
updatedAt: asString5(raw.updatedAt ?? raw.updated_at)
|
|
11703
12208
|
};
|
|
11704
12209
|
}
|
|
11705
12210
|
async function loadLegacySettingsPatch() {
|
|
11706
12211
|
const filePath = resolveLegacyPath(LEGACY_SETTINGS_FILE);
|
|
11707
12212
|
const raw = await readJsonFileIfExists(filePath);
|
|
11708
|
-
if (!
|
|
12213
|
+
if (!isRecord7(raw)) {
|
|
11709
12214
|
return {};
|
|
11710
12215
|
}
|
|
11711
12216
|
const autoRoll = pickAutoRoll(raw.autoRoll ?? raw.auto_roll);
|
|
11712
12217
|
const license = parseLegacyLicense(raw.license ?? raw.license_data ?? raw.license_state);
|
|
11713
12218
|
return {
|
|
11714
12219
|
app: {
|
|
11715
|
-
lastAppVersion:
|
|
11716
|
-
pendingUpdateVersion:
|
|
11717
|
-
lastProfileName:
|
|
12220
|
+
lastAppVersion: asString5(raw.lastAppVersion ?? raw.last_app_version),
|
|
12221
|
+
pendingUpdateVersion: asString5(raw.pendingUpdateVersion ?? raw.pending_update_version),
|
|
12222
|
+
lastProfileName: asString5(raw.lastProfileName ?? raw.last_profile_name)
|
|
11718
12223
|
},
|
|
11719
12224
|
license,
|
|
11720
12225
|
autoRoll: autoRoll ? {
|
|
@@ -11732,22 +12237,22 @@ async function loadLegacySettingsPatch() {
|
|
|
11732
12237
|
async function loadLegacySyncPatch() {
|
|
11733
12238
|
const filePath = resolveLegacyPath(LEGACY_SYNC_STATE_FILE);
|
|
11734
12239
|
const raw = await readJsonFileIfExists(filePath);
|
|
11735
|
-
if (!
|
|
12240
|
+
if (!isRecord7(raw)) {
|
|
11736
12241
|
return {};
|
|
11737
12242
|
}
|
|
11738
12243
|
return {
|
|
11739
12244
|
sync: {
|
|
11740
|
-
lastPushAt:
|
|
11741
|
-
lastPullAt:
|
|
11742
|
-
lastError:
|
|
11743
|
-
remoteUpdatedAt:
|
|
12245
|
+
lastPushAt: asString5(raw.lastPushAt),
|
|
12246
|
+
lastPullAt: asString5(raw.lastPullAt),
|
|
12247
|
+
lastError: asString5(raw.lastError),
|
|
12248
|
+
remoteUpdatedAt: asString5(raw.remoteUpdatedAt)
|
|
11744
12249
|
}
|
|
11745
12250
|
};
|
|
11746
12251
|
}
|
|
11747
12252
|
async function loadLegacyAppSettingsParityPatch() {
|
|
11748
12253
|
const filePath = import_node_path16.default.join(getUserDataDir(), LEGACY_APP_SETTINGS_PARITY_FILE);
|
|
11749
12254
|
const raw = await readJsonFileIfExists(filePath);
|
|
11750
|
-
if (!
|
|
12255
|
+
if (!isRecord7(raw)) {
|
|
11751
12256
|
return {};
|
|
11752
12257
|
}
|
|
11753
12258
|
return {
|
|
@@ -11787,21 +12292,21 @@ async function loadLegacyProfilesPatch() {
|
|
|
11787
12292
|
return { profilesByName };
|
|
11788
12293
|
}
|
|
11789
12294
|
function parseSkillInstallMetadata(raw) {
|
|
11790
|
-
if (!
|
|
12295
|
+
if (!isRecord7(raw)) {
|
|
11791
12296
|
return null;
|
|
11792
12297
|
}
|
|
11793
|
-
const id =
|
|
12298
|
+
const id = asString5(raw.id);
|
|
11794
12299
|
if (!id) {
|
|
11795
12300
|
return null;
|
|
11796
12301
|
}
|
|
11797
12302
|
return {
|
|
11798
12303
|
id,
|
|
11799
|
-
repo:
|
|
11800
|
-
repoPath:
|
|
11801
|
-
sourceLabel:
|
|
12304
|
+
repo: asString5(raw.repo),
|
|
12305
|
+
repoPath: asString5(raw.repoPath),
|
|
12306
|
+
sourceLabel: asString5(raw.sourceLabel),
|
|
11802
12307
|
sourceType: raw.sourceType === "official" || raw.sourceType === "community" || raw.sourceType === "local" ? raw.sourceType : void 0,
|
|
11803
|
-
viewUrl:
|
|
11804
|
-
createdAt:
|
|
12308
|
+
viewUrl: asString5(raw.viewUrl),
|
|
12309
|
+
createdAt: asString5(raw.createdAt)
|
|
11805
12310
|
};
|
|
11806
12311
|
}
|
|
11807
12312
|
async function loadLegacySkillsPatch() {
|
|
@@ -11832,7 +12337,7 @@ async function loadLegacySkillsPatch() {
|
|
|
11832
12337
|
}
|
|
11833
12338
|
installsBySlug[entry.name] = parsed;
|
|
11834
12339
|
}
|
|
11835
|
-
const sources =
|
|
12340
|
+
const sources = isRecord7(reposRaw) && Array.isArray(reposRaw.sources) ? reposRaw.sources : [];
|
|
11836
12341
|
if (sources.length === 0 && Object.keys(installsBySlug).length === 0) {
|
|
11837
12342
|
return {};
|
|
11838
12343
|
}
|
|
@@ -11864,7 +12369,7 @@ function mergeLegacyLocalStoragePatch(payload) {
|
|
|
11864
12369
|
}
|
|
11865
12370
|
};
|
|
11866
12371
|
const settingsStorage = payload["settings-storage"];
|
|
11867
|
-
if (
|
|
12372
|
+
if (isRecord7(settingsStorage)) {
|
|
11868
12373
|
const nextExcludeFolders = Array.isArray(settingsStorage.excludeFolders) ? settingsStorage.excludeFolders.filter((item) => typeof item === "string") : void 0;
|
|
11869
12374
|
const nextBeep = typeof settingsStorage.enableTaskCompleteBeep === "boolean" ? settingsStorage.enableTaskCompleteBeep : void 0;
|
|
11870
12375
|
const nextSleep = typeof settingsStorage.preventSleepDuringTasks === "boolean" ? settingsStorage.preventSleepDuringTasks : void 0;
|
|
@@ -11883,15 +12388,15 @@ function mergeLegacyLocalStoragePatch(payload) {
|
|
|
11883
12388
|
markSkippedIfPresent("provider", hasKey2("provider"));
|
|
11884
12389
|
markSkippedIfPresent("sandbox-storage", hasKey2("sandbox-storage"));
|
|
11885
12390
|
const projectSettings = payload["project-settings-storage"];
|
|
11886
|
-
if (
|
|
12391
|
+
if (isRecord7(projectSettings) && isRecord7(projectSettings.settingsByPath)) {
|
|
11887
12392
|
patch.workspaceSettingsByPath = projectSettings.settingsByPath;
|
|
11888
12393
|
markSkippedIfPresent("project-settings-storage", true);
|
|
11889
12394
|
} else {
|
|
11890
12395
|
markSkippedIfPresent("project-settings-storage", false);
|
|
11891
12396
|
}
|
|
11892
12397
|
const folder = payload["folder-storage"];
|
|
11893
|
-
if (
|
|
11894
|
-
const folderHistory = Array.isArray(folder.folderHistory) ? folder.folderHistory.filter(
|
|
12398
|
+
if (isRecord7(folder)) {
|
|
12399
|
+
const folderHistory = Array.isArray(folder.folderHistory) ? folder.folderHistory.filter(isRecord7) : void 0;
|
|
11895
12400
|
const pinnedPaths = Array.isArray(folder.pinnedPaths) ? folder.pinnedPaths.filter((item) => typeof item === "string") : void 0;
|
|
11896
12401
|
patch.preferences = {
|
|
11897
12402
|
...patch.preferences ?? {},
|
|
@@ -11904,12 +12409,12 @@ function mergeLegacyLocalStoragePatch(payload) {
|
|
|
11904
12409
|
}
|
|
11905
12410
|
const categories = payload["conversation-categories-storage"];
|
|
11906
12411
|
let consumedCategories = false;
|
|
11907
|
-
if (
|
|
11908
|
-
if (
|
|
12412
|
+
if (isRecord7(categories)) {
|
|
12413
|
+
if (isRecord7(categories.categoriesByCwd)) {
|
|
11909
12414
|
patch.conversationCategoriesByCwd = categories.categoriesByCwd;
|
|
11910
12415
|
consumedCategories = true;
|
|
11911
12416
|
}
|
|
11912
|
-
if (
|
|
12417
|
+
if (isRecord7(categories.conversationCategoryByCwd)) {
|
|
11913
12418
|
patch.conversationCategoryAssignmentsByCwd = categories.conversationCategoryByCwd;
|
|
11914
12419
|
consumedCategories = true;
|
|
11915
12420
|
}
|
|
@@ -12132,7 +12637,7 @@ async function importLegacyLocalStorageOnce(payload) {
|
|
|
12132
12637
|
if (current.migration.status === "pending") {
|
|
12133
12638
|
return { completed: false, importedKeys: [], skippedKeys: [] };
|
|
12134
12639
|
}
|
|
12135
|
-
if (!payload || !
|
|
12640
|
+
if (!payload || !isRecord7(payload)) {
|
|
12136
12641
|
return { completed: true, importedKeys: [], skippedKeys: [] };
|
|
12137
12642
|
}
|
|
12138
12643
|
const { patch, consumedKeys, skippedKeys } = mergeLegacyLocalStoragePatch(payload);
|
|
@@ -12200,7 +12705,7 @@ async function ensureCliStorageReady() {
|
|
|
12200
12705
|
}
|
|
12201
12706
|
|
|
12202
12707
|
// src/app/main.ts
|
|
12203
|
-
var VERSION = true ? "
|
|
12708
|
+
var VERSION = true ? "4.0.0" : "0.0.0";
|
|
12204
12709
|
async function runCli() {
|
|
12205
12710
|
const args = process.argv.slice(2);
|
|
12206
12711
|
if (args.length === 0) {
|