codexuse-cli 2.4.2 → 2.4.4
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/README.md +1 -0
- package/dist/index.js +825 -6
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -34,15 +34,45 @@ var DEFAULT_AUTO_ROLL_ENABLED = false;
|
|
|
34
34
|
var DEFAULT_AUTO_ROLL_WARNING_THRESHOLD = 85;
|
|
35
35
|
var DEFAULT_AUTO_ROLL_SWITCH_THRESHOLD = 95;
|
|
36
36
|
var AUTO_ROLL_WARNING_MIN = 50;
|
|
37
|
+
var AUTO_ROLL_WARNING_MAX = 99;
|
|
38
|
+
var AUTO_ROLL_SWITCH_MAX = 100;
|
|
37
39
|
function clampNumber(value, min, max) {
|
|
38
40
|
return Math.min(max, Math.max(min, value));
|
|
39
41
|
}
|
|
42
|
+
function resolveFiniteNumber(value, fallback) {
|
|
43
|
+
return Number.isFinite(value) ? value : fallback;
|
|
44
|
+
}
|
|
45
|
+
function sanitizeAutoRollWarningThreshold(value) {
|
|
46
|
+
const numeric = resolveFiniteNumber(value, DEFAULT_AUTO_ROLL_WARNING_THRESHOLD);
|
|
47
|
+
return clampNumber(numeric, AUTO_ROLL_WARNING_MIN, AUTO_ROLL_WARNING_MAX);
|
|
48
|
+
}
|
|
49
|
+
function sanitizeAutoRollSwitchThreshold(value, warningThreshold) {
|
|
50
|
+
const sanitizedWarning = sanitizeAutoRollWarningThreshold(warningThreshold);
|
|
51
|
+
const numeric = resolveFiniteNumber(value, DEFAULT_AUTO_ROLL_SWITCH_THRESHOLD);
|
|
52
|
+
return clampNumber(numeric, sanitizedWarning + 1, AUTO_ROLL_SWITCH_MAX);
|
|
53
|
+
}
|
|
54
|
+
function sanitizeAutoRollThresholds(warningThreshold, switchThreshold) {
|
|
55
|
+
const sanitizedWarning = sanitizeAutoRollWarningThreshold(warningThreshold);
|
|
56
|
+
const sanitizedSwitch = sanitizeAutoRollSwitchThreshold(switchThreshold, sanitizedWarning);
|
|
57
|
+
return {
|
|
58
|
+
warningThreshold: sanitizedWarning,
|
|
59
|
+
switchThreshold: sanitizedSwitch
|
|
60
|
+
};
|
|
61
|
+
}
|
|
40
62
|
function normalizeAutoRollSettings(raw) {
|
|
41
63
|
const enabled = typeof raw?.enabled === "boolean" ? raw.enabled : DEFAULT_AUTO_ROLL_ENABLED;
|
|
42
|
-
const rawWarning =
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
64
|
+
const rawWarning = resolveFiniteNumber(
|
|
65
|
+
typeof raw?.warningThreshold === "number" ? raw.warningThreshold : NaN,
|
|
66
|
+
DEFAULT_AUTO_ROLL_WARNING_THRESHOLD
|
|
67
|
+
);
|
|
68
|
+
const rawSwitch = resolveFiniteNumber(
|
|
69
|
+
typeof raw?.switchThreshold === "number" ? raw.switchThreshold : NaN,
|
|
70
|
+
DEFAULT_AUTO_ROLL_SWITCH_THRESHOLD
|
|
71
|
+
);
|
|
72
|
+
const { warningThreshold: normalizedWarning, switchThreshold: normalizedSwitch } = sanitizeAutoRollThresholds(
|
|
73
|
+
rawWarning,
|
|
74
|
+
rawSwitch
|
|
75
|
+
);
|
|
46
76
|
return {
|
|
47
77
|
enabled,
|
|
48
78
|
warningThreshold: normalizedWarning,
|
|
@@ -375,6 +405,11 @@ async function withWriteLock(task) {
|
|
|
375
405
|
release?.();
|
|
376
406
|
}
|
|
377
407
|
}
|
|
408
|
+
async function initializeAppState(userDataDir) {
|
|
409
|
+
configuredUserDataDir = userDataDir;
|
|
410
|
+
const state = await ensureInitialized();
|
|
411
|
+
return clone(state);
|
|
412
|
+
}
|
|
378
413
|
async function getAppState() {
|
|
379
414
|
const state = await ensureInitialized();
|
|
380
415
|
return clone(state);
|
|
@@ -3659,7 +3694,6 @@ async function getCloudSyncStatus() {
|
|
|
3659
3694
|
}
|
|
3660
3695
|
}
|
|
3661
3696
|
return {
|
|
3662
|
-
endpoint: getCloudSyncApiBaseUrl(),
|
|
3663
3697
|
canSync: eligibility.canSync,
|
|
3664
3698
|
reason: eligibility.reason,
|
|
3665
3699
|
licenseState: eligibility.licenseState,
|
|
@@ -4071,8 +4105,790 @@ function maxUsedPercent(snapshot) {
|
|
|
4071
4105
|
return Math.max(...candidates);
|
|
4072
4106
|
}
|
|
4073
4107
|
|
|
4108
|
+
// ../../lib/storage-migration-v1.ts
|
|
4109
|
+
var import_node_fs7 = require("fs");
|
|
4110
|
+
var import_node_path9 = __toESM(require("path"));
|
|
4111
|
+
var import_node_os3 = __toESM(require("os"));
|
|
4112
|
+
|
|
4113
|
+
// ../../lib/legacy-localstorage-keys.ts
|
|
4114
|
+
var LEGACY_LOCALSTORAGE_KEYS = [
|
|
4115
|
+
"settings-storage",
|
|
4116
|
+
"provider",
|
|
4117
|
+
"sandbox-storage",
|
|
4118
|
+
"project-settings-storage",
|
|
4119
|
+
"folder-storage",
|
|
4120
|
+
"conversation-categories-storage",
|
|
4121
|
+
"codex:auto-roll-settings"
|
|
4122
|
+
];
|
|
4123
|
+
|
|
4124
|
+
// ../../lib/storage-migration-v1.ts
|
|
4125
|
+
var SQLITE_STORAGE_DIR = ".f86eb5e712267207";
|
|
4126
|
+
var LEGACY_SETTINGS_FILE = "settings.json";
|
|
4127
|
+
var LEGACY_SETTINGS_BACKUP_FILE = "settings.json.bak";
|
|
4128
|
+
var LEGACY_SYNC_STATE_FILE = "sync-state.json";
|
|
4129
|
+
var LEGACY_PROFILE_HOMES_DIR = "profile-homes";
|
|
4130
|
+
var LEGACY_SKILLS_DIR = "skills";
|
|
4131
|
+
var LEGACY_SKILL_CACHE_DIR = "skill-cache";
|
|
4132
|
+
var LEGACY_SKILLS_REPOS_FILE = "repos.json";
|
|
4133
|
+
var LEGACY_SKILL_MANIFEST = ".codexuse-skill.json";
|
|
4134
|
+
var LEGACY_LICENSE_SECRET_FILE = "license.secret";
|
|
4135
|
+
function isRecord5(value) {
|
|
4136
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
4137
|
+
}
|
|
4138
|
+
function asString3(value) {
|
|
4139
|
+
if (typeof value !== "string") {
|
|
4140
|
+
return null;
|
|
4141
|
+
}
|
|
4142
|
+
const trimmed = value.trim();
|
|
4143
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
4144
|
+
}
|
|
4145
|
+
function resolveHomeDir2() {
|
|
4146
|
+
const home = process.env.HOME || process.env.USERPROFILE || import_node_os3.default.homedir();
|
|
4147
|
+
if (!home) {
|
|
4148
|
+
throw new Error("HOME is not set.");
|
|
4149
|
+
}
|
|
4150
|
+
return home;
|
|
4151
|
+
}
|
|
4152
|
+
function resolveCodexDir() {
|
|
4153
|
+
return import_node_path9.default.join(resolveHomeDir2(), ".codex");
|
|
4154
|
+
}
|
|
4155
|
+
function resolveLegacyPath(...segments) {
|
|
4156
|
+
return import_node_path9.default.join(resolveCodexDir(), ...segments);
|
|
4157
|
+
}
|
|
4158
|
+
async function readJsonFile(filePath) {
|
|
4159
|
+
const raw = await import_node_fs7.promises.readFile(filePath, "utf8");
|
|
4160
|
+
return JSON.parse(raw);
|
|
4161
|
+
}
|
|
4162
|
+
async function readJsonFileIfExists(filePath) {
|
|
4163
|
+
try {
|
|
4164
|
+
return await readJsonFile(filePath);
|
|
4165
|
+
} catch (error) {
|
|
4166
|
+
const code = error.code;
|
|
4167
|
+
if (code === "ENOENT") {
|
|
4168
|
+
return null;
|
|
4169
|
+
}
|
|
4170
|
+
throw error;
|
|
4171
|
+
}
|
|
4172
|
+
}
|
|
4173
|
+
async function copyDirectoryManual(source, destination) {
|
|
4174
|
+
await import_node_fs7.promises.mkdir(destination, { recursive: true });
|
|
4175
|
+
const entries = await import_node_fs7.promises.readdir(source, { withFileTypes: true });
|
|
4176
|
+
for (const entry of entries) {
|
|
4177
|
+
const srcPath = import_node_path9.default.join(source, entry.name);
|
|
4178
|
+
const destPath = import_node_path9.default.join(destination, entry.name);
|
|
4179
|
+
if (entry.isSymbolicLink()) {
|
|
4180
|
+
const linkTarget = await import_node_fs7.promises.readlink(srcPath);
|
|
4181
|
+
await import_node_fs7.promises.symlink(linkTarget, destPath).catch((error) => {
|
|
4182
|
+
if (error.code !== "EEXIST") {
|
|
4183
|
+
throw error;
|
|
4184
|
+
}
|
|
4185
|
+
});
|
|
4186
|
+
continue;
|
|
4187
|
+
}
|
|
4188
|
+
if (entry.isDirectory()) {
|
|
4189
|
+
await copyDirectoryManual(srcPath, destPath);
|
|
4190
|
+
continue;
|
|
4191
|
+
}
|
|
4192
|
+
if (entry.isFile()) {
|
|
4193
|
+
await import_node_fs7.promises.copyFile(srcPath, destPath);
|
|
4194
|
+
}
|
|
4195
|
+
}
|
|
4196
|
+
}
|
|
4197
|
+
async function copyDirIfExists(source, destination) {
|
|
4198
|
+
let stats = null;
|
|
4199
|
+
try {
|
|
4200
|
+
stats = await import_node_fs7.promises.stat(source);
|
|
4201
|
+
} catch (error) {
|
|
4202
|
+
if (error.code === "ENOENT") {
|
|
4203
|
+
return;
|
|
4204
|
+
}
|
|
4205
|
+
throw error;
|
|
4206
|
+
}
|
|
4207
|
+
if (!stats.isDirectory()) {
|
|
4208
|
+
return;
|
|
4209
|
+
}
|
|
4210
|
+
await import_node_fs7.promises.rm(destination, { recursive: true, force: true });
|
|
4211
|
+
await import_node_fs7.promises.mkdir(import_node_path9.default.dirname(destination), { recursive: true });
|
|
4212
|
+
try {
|
|
4213
|
+
await import_node_fs7.promises.cp(source, destination, {
|
|
4214
|
+
recursive: true,
|
|
4215
|
+
errorOnExist: false,
|
|
4216
|
+
force: true,
|
|
4217
|
+
dereference: false,
|
|
4218
|
+
verbatimSymlinks: true
|
|
4219
|
+
});
|
|
4220
|
+
} catch (error) {
|
|
4221
|
+
if (error.code === "ERR_FS_CP_EINVAL") {
|
|
4222
|
+
await copyDirectoryManual(source, destination);
|
|
4223
|
+
return;
|
|
4224
|
+
}
|
|
4225
|
+
throw error;
|
|
4226
|
+
}
|
|
4227
|
+
}
|
|
4228
|
+
async function copyFileIfExists(source, destination, options) {
|
|
4229
|
+
try {
|
|
4230
|
+
const sourceStat = await import_node_fs7.promises.stat(source);
|
|
4231
|
+
if (!sourceStat.isFile()) {
|
|
4232
|
+
return;
|
|
4233
|
+
}
|
|
4234
|
+
} catch (error) {
|
|
4235
|
+
if (error.code === "ENOENT") {
|
|
4236
|
+
return;
|
|
4237
|
+
}
|
|
4238
|
+
throw error;
|
|
4239
|
+
}
|
|
4240
|
+
try {
|
|
4241
|
+
const destinationStat = await import_node_fs7.promises.stat(destination);
|
|
4242
|
+
if (destinationStat.isFile()) {
|
|
4243
|
+
return;
|
|
4244
|
+
}
|
|
4245
|
+
} catch (error) {
|
|
4246
|
+
if (error.code !== "ENOENT") {
|
|
4247
|
+
throw error;
|
|
4248
|
+
}
|
|
4249
|
+
}
|
|
4250
|
+
await import_node_fs7.promises.mkdir(import_node_path9.default.dirname(destination), { recursive: true });
|
|
4251
|
+
await import_node_fs7.promises.copyFile(source, destination);
|
|
4252
|
+
if (typeof options?.mode === "number") {
|
|
4253
|
+
await import_node_fs7.promises.chmod(destination, options.mode).catch(() => void 0);
|
|
4254
|
+
}
|
|
4255
|
+
}
|
|
4256
|
+
async function cleanupCopiedSkillsMetadata(skillsDir) {
|
|
4257
|
+
await removeIfExists(import_node_path9.default.join(skillsDir, LEGACY_SKILLS_REPOS_FILE));
|
|
4258
|
+
let entries = [];
|
|
4259
|
+
try {
|
|
4260
|
+
entries = await import_node_fs7.promises.readdir(skillsDir, { withFileTypes: true });
|
|
4261
|
+
} catch {
|
|
4262
|
+
return;
|
|
4263
|
+
}
|
|
4264
|
+
for (const entry of entries) {
|
|
4265
|
+
if (!entry.isDirectory() || entry.name.startsWith(".")) {
|
|
4266
|
+
continue;
|
|
4267
|
+
}
|
|
4268
|
+
await removeIfExists(import_node_path9.default.join(skillsDir, entry.name, LEGACY_SKILL_MANIFEST));
|
|
4269
|
+
}
|
|
4270
|
+
}
|
|
4271
|
+
async function migrateLegacyDirectoriesToUserData() {
|
|
4272
|
+
const userDataDir = getUserDataDir();
|
|
4273
|
+
const legacyCodexDir = resolveCodexDir();
|
|
4274
|
+
await copyDirIfExists(
|
|
4275
|
+
import_node_path9.default.join(legacyCodexDir, LEGACY_PROFILE_HOMES_DIR),
|
|
4276
|
+
import_node_path9.default.join(userDataDir, LEGACY_PROFILE_HOMES_DIR)
|
|
4277
|
+
);
|
|
4278
|
+
await copyDirIfExists(
|
|
4279
|
+
import_node_path9.default.join(legacyCodexDir, LEGACY_SKILLS_DIR),
|
|
4280
|
+
import_node_path9.default.join(userDataDir, LEGACY_SKILLS_DIR)
|
|
4281
|
+
);
|
|
4282
|
+
await copyDirIfExists(
|
|
4283
|
+
import_node_path9.default.join(legacyCodexDir, LEGACY_SKILL_CACHE_DIR),
|
|
4284
|
+
import_node_path9.default.join(userDataDir, LEGACY_SKILL_CACHE_DIR)
|
|
4285
|
+
);
|
|
4286
|
+
await copyFileIfExists(
|
|
4287
|
+
import_node_path9.default.join(legacyCodexDir, LEGACY_LICENSE_SECRET_FILE),
|
|
4288
|
+
import_node_path9.default.join(userDataDir, LEGACY_LICENSE_SECRET_FILE),
|
|
4289
|
+
{ mode: 384 }
|
|
4290
|
+
);
|
|
4291
|
+
await cleanupCopiedSkillsMetadata(import_node_path9.default.join(userDataDir, LEGACY_SKILLS_DIR));
|
|
4292
|
+
}
|
|
4293
|
+
function pickAutoRoll(raw) {
|
|
4294
|
+
if (!raw) {
|
|
4295
|
+
return null;
|
|
4296
|
+
}
|
|
4297
|
+
try {
|
|
4298
|
+
return normalizeAutoRollSettings(raw);
|
|
4299
|
+
} catch {
|
|
4300
|
+
return null;
|
|
4301
|
+
}
|
|
4302
|
+
}
|
|
4303
|
+
function parseLegacyLicense(raw) {
|
|
4304
|
+
if (!isRecord5(raw)) {
|
|
4305
|
+
return {
|
|
4306
|
+
licenseKey: null,
|
|
4307
|
+
purchaseEmail: null,
|
|
4308
|
+
lastVerifiedAt: null,
|
|
4309
|
+
nextCheckAt: null,
|
|
4310
|
+
lastVerificationError: null,
|
|
4311
|
+
status: "inactive",
|
|
4312
|
+
signature: null
|
|
4313
|
+
};
|
|
4314
|
+
}
|
|
4315
|
+
const statusCandidate = asString3(raw.status);
|
|
4316
|
+
const status = ["inactive", "active", "grace", "error"].includes(statusCandidate ?? "") ? statusCandidate : "inactive";
|
|
4317
|
+
return {
|
|
4318
|
+
licenseKey: asString3(raw.licenseKey ?? raw.license_key),
|
|
4319
|
+
purchaseEmail: asString3(raw.purchaseEmail ?? raw.purchase_email),
|
|
4320
|
+
lastVerifiedAt: asString3(raw.lastVerifiedAt ?? raw.last_verified_at),
|
|
4321
|
+
nextCheckAt: asString3(raw.nextCheckAt ?? raw.next_check_at),
|
|
4322
|
+
lastVerificationError: asString3(raw.lastVerificationError ?? raw.last_verification_error),
|
|
4323
|
+
status,
|
|
4324
|
+
signature: asString3(raw.signature)
|
|
4325
|
+
};
|
|
4326
|
+
}
|
|
4327
|
+
function parseLegacyProfileRecord(name, raw) {
|
|
4328
|
+
if (!isRecord5(raw)) {
|
|
4329
|
+
return null;
|
|
4330
|
+
}
|
|
4331
|
+
const dataRaw = raw.data;
|
|
4332
|
+
let data = null;
|
|
4333
|
+
if (isRecord5(dataRaw)) {
|
|
4334
|
+
data = dataRaw;
|
|
4335
|
+
} else if (typeof dataRaw === "string") {
|
|
4336
|
+
try {
|
|
4337
|
+
data = JSON.parse(dataRaw);
|
|
4338
|
+
} catch {
|
|
4339
|
+
data = null;
|
|
4340
|
+
}
|
|
4341
|
+
}
|
|
4342
|
+
if (!data) {
|
|
4343
|
+
return null;
|
|
4344
|
+
}
|
|
4345
|
+
return {
|
|
4346
|
+
name,
|
|
4347
|
+
displayName: asString3(raw.displayName ?? raw.display_name) ?? name,
|
|
4348
|
+
data,
|
|
4349
|
+
metadata: isRecord5(raw.metadata) ? raw.metadata : void 0,
|
|
4350
|
+
accountId: asString3(raw.accountId ?? raw.account_id),
|
|
4351
|
+
workspaceId: asString3(raw.workspaceId ?? raw.workspace_id),
|
|
4352
|
+
workspaceName: asString3(raw.workspaceName ?? raw.workspace_name),
|
|
4353
|
+
email: asString3(raw.email),
|
|
4354
|
+
authMethod: asString3(raw.authMethod ?? raw.auth_method),
|
|
4355
|
+
createdAt: asString3(raw.createdAt ?? raw.created_at),
|
|
4356
|
+
updatedAt: asString3(raw.updatedAt ?? raw.updated_at)
|
|
4357
|
+
};
|
|
4358
|
+
}
|
|
4359
|
+
async function loadLegacySettingsPatch() {
|
|
4360
|
+
const filePath = resolveLegacyPath(LEGACY_SETTINGS_FILE);
|
|
4361
|
+
const raw = await readJsonFileIfExists(filePath);
|
|
4362
|
+
if (!isRecord5(raw)) {
|
|
4363
|
+
return {};
|
|
4364
|
+
}
|
|
4365
|
+
const cliChannel = parseCodexCliChannel(raw.cliChannel ?? raw.cli_channel);
|
|
4366
|
+
const autoRoll = pickAutoRoll(raw.autoRoll ?? raw.auto_roll);
|
|
4367
|
+
const license = parseLegacyLicense(raw.license ?? raw.license_data ?? raw.license_state);
|
|
4368
|
+
return {
|
|
4369
|
+
app: {
|
|
4370
|
+
lastAppVersion: asString3(raw.lastAppVersion ?? raw.last_app_version),
|
|
4371
|
+
pendingUpdateVersion: asString3(raw.pendingUpdateVersion ?? raw.pending_update_version),
|
|
4372
|
+
cliChannel: cliChannel ?? void 0,
|
|
4373
|
+
lastProfileName: asString3(raw.lastProfileName ?? raw.last_profile_name)
|
|
4374
|
+
},
|
|
4375
|
+
license,
|
|
4376
|
+
autoRoll: autoRoll ? {
|
|
4377
|
+
enabled: autoRoll.enabled,
|
|
4378
|
+
warningThreshold: autoRoll.warningThreshold,
|
|
4379
|
+
switchThreshold: autoRoll.switchThreshold
|
|
4380
|
+
} : void 0
|
|
4381
|
+
};
|
|
4382
|
+
}
|
|
4383
|
+
async function loadLegacySyncPatch() {
|
|
4384
|
+
const filePath = resolveLegacyPath(LEGACY_SYNC_STATE_FILE);
|
|
4385
|
+
const raw = await readJsonFileIfExists(filePath);
|
|
4386
|
+
if (!isRecord5(raw)) {
|
|
4387
|
+
return {};
|
|
4388
|
+
}
|
|
4389
|
+
return {
|
|
4390
|
+
sync: {
|
|
4391
|
+
lastPushAt: asString3(raw.lastPushAt),
|
|
4392
|
+
lastPullAt: asString3(raw.lastPullAt),
|
|
4393
|
+
lastError: asString3(raw.lastError),
|
|
4394
|
+
remoteUpdatedAt: asString3(raw.remoteUpdatedAt)
|
|
4395
|
+
}
|
|
4396
|
+
};
|
|
4397
|
+
}
|
|
4398
|
+
async function loadLegacyProfilesPatch() {
|
|
4399
|
+
const root = resolveLegacyPath(LEGACY_PROFILE_HOMES_DIR);
|
|
4400
|
+
let entries = [];
|
|
4401
|
+
try {
|
|
4402
|
+
entries = await import_node_fs7.promises.readdir(root, { withFileTypes: true });
|
|
4403
|
+
} catch (error) {
|
|
4404
|
+
if (error.code === "ENOENT") {
|
|
4405
|
+
return {};
|
|
4406
|
+
}
|
|
4407
|
+
throw error;
|
|
4408
|
+
}
|
|
4409
|
+
const profilesByName = {};
|
|
4410
|
+
for (const entry of entries) {
|
|
4411
|
+
if (!entry.isDirectory() || entry.name.startsWith(".")) {
|
|
4412
|
+
continue;
|
|
4413
|
+
}
|
|
4414
|
+
const profileFile = import_node_path9.default.join(root, entry.name, "profile.json");
|
|
4415
|
+
const raw = await readJsonFileIfExists(profileFile);
|
|
4416
|
+
if (!raw) {
|
|
4417
|
+
continue;
|
|
4418
|
+
}
|
|
4419
|
+
const parsed = parseLegacyProfileRecord(entry.name, raw);
|
|
4420
|
+
if (!parsed) {
|
|
4421
|
+
continue;
|
|
4422
|
+
}
|
|
4423
|
+
profilesByName[entry.name] = parsed;
|
|
4424
|
+
}
|
|
4425
|
+
if (Object.keys(profilesByName).length === 0) {
|
|
4426
|
+
return {};
|
|
4427
|
+
}
|
|
4428
|
+
return { profilesByName };
|
|
4429
|
+
}
|
|
4430
|
+
function parseSkillInstallMetadata(raw) {
|
|
4431
|
+
if (!isRecord5(raw)) {
|
|
4432
|
+
return null;
|
|
4433
|
+
}
|
|
4434
|
+
const id = asString3(raw.id);
|
|
4435
|
+
if (!id) {
|
|
4436
|
+
return null;
|
|
4437
|
+
}
|
|
4438
|
+
return {
|
|
4439
|
+
id,
|
|
4440
|
+
repo: asString3(raw.repo),
|
|
4441
|
+
repoPath: asString3(raw.repoPath),
|
|
4442
|
+
sourceLabel: asString3(raw.sourceLabel),
|
|
4443
|
+
sourceType: raw.sourceType === "official" || raw.sourceType === "community" || raw.sourceType === "local" ? raw.sourceType : void 0,
|
|
4444
|
+
viewUrl: asString3(raw.viewUrl),
|
|
4445
|
+
createdAt: asString3(raw.createdAt)
|
|
4446
|
+
};
|
|
4447
|
+
}
|
|
4448
|
+
async function loadLegacySkillsPatch() {
|
|
4449
|
+
const skillsRoot = resolveLegacyPath(LEGACY_SKILLS_DIR);
|
|
4450
|
+
const reposPath = import_node_path9.default.join(skillsRoot, LEGACY_SKILLS_REPOS_FILE);
|
|
4451
|
+
const reposRaw = await readJsonFileIfExists(reposPath);
|
|
4452
|
+
const installsBySlug = {};
|
|
4453
|
+
let dirEntries = [];
|
|
4454
|
+
try {
|
|
4455
|
+
dirEntries = await import_node_fs7.promises.readdir(skillsRoot, { withFileTypes: true });
|
|
4456
|
+
} catch (error) {
|
|
4457
|
+
if (error.code !== "ENOENT") {
|
|
4458
|
+
throw error;
|
|
4459
|
+
}
|
|
4460
|
+
}
|
|
4461
|
+
for (const entry of dirEntries) {
|
|
4462
|
+
if (!entry.isDirectory()) {
|
|
4463
|
+
continue;
|
|
4464
|
+
}
|
|
4465
|
+
if (entry.name.startsWith(".")) {
|
|
4466
|
+
continue;
|
|
4467
|
+
}
|
|
4468
|
+
const manifestPath = import_node_path9.default.join(skillsRoot, entry.name, LEGACY_SKILL_MANIFEST);
|
|
4469
|
+
const manifestRaw = await readJsonFileIfExists(manifestPath);
|
|
4470
|
+
const parsed = parseSkillInstallMetadata(manifestRaw);
|
|
4471
|
+
if (!parsed) {
|
|
4472
|
+
continue;
|
|
4473
|
+
}
|
|
4474
|
+
installsBySlug[entry.name] = parsed;
|
|
4475
|
+
}
|
|
4476
|
+
const sources = isRecord5(reposRaw) && Array.isArray(reposRaw.sources) ? reposRaw.sources : [];
|
|
4477
|
+
if (sources.length === 0 && Object.keys(installsBySlug).length === 0) {
|
|
4478
|
+
return {};
|
|
4479
|
+
}
|
|
4480
|
+
return {
|
|
4481
|
+
skills: {
|
|
4482
|
+
sources,
|
|
4483
|
+
installsBySlug
|
|
4484
|
+
}
|
|
4485
|
+
};
|
|
4486
|
+
}
|
|
4487
|
+
function mergeLegacyLocalStoragePatch(payload) {
|
|
4488
|
+
const patch = {};
|
|
4489
|
+
const consumedKeys = /* @__PURE__ */ new Set();
|
|
4490
|
+
const skippedKeys = /* @__PURE__ */ new Set();
|
|
4491
|
+
const legacyPayloadKeys = new Set(
|
|
4492
|
+
Object.keys(payload).filter(
|
|
4493
|
+
(key) => LEGACY_LOCALSTORAGE_KEYS.includes(key)
|
|
4494
|
+
)
|
|
4495
|
+
);
|
|
4496
|
+
const hasKey = (key) => legacyPayloadKeys.has(key);
|
|
4497
|
+
const markSkippedIfPresent = (key, consumed) => {
|
|
4498
|
+
if (!hasKey(key)) {
|
|
4499
|
+
return;
|
|
4500
|
+
}
|
|
4501
|
+
if (consumed) {
|
|
4502
|
+
consumedKeys.add(key);
|
|
4503
|
+
} else {
|
|
4504
|
+
skippedKeys.add(key);
|
|
4505
|
+
}
|
|
4506
|
+
};
|
|
4507
|
+
const settingsStorage = payload["settings-storage"];
|
|
4508
|
+
if (isRecord5(settingsStorage)) {
|
|
4509
|
+
const nextExcludeFolders = Array.isArray(settingsStorage.excludeFolders) ? settingsStorage.excludeFolders.filter((item) => typeof item === "string") : void 0;
|
|
4510
|
+
const nextBeep = typeof settingsStorage.enableTaskCompleteBeep === "boolean" ? settingsStorage.enableTaskCompleteBeep : void 0;
|
|
4511
|
+
const nextSleep = typeof settingsStorage.preventSleepDuringTasks === "boolean" ? settingsStorage.preventSleepDuringTasks : void 0;
|
|
4512
|
+
patch.preferences = {
|
|
4513
|
+
excludeFolders: nextExcludeFolders,
|
|
4514
|
+
enableTaskCompleteBeep: nextBeep,
|
|
4515
|
+
preventSleepDuringTasks: nextSleep
|
|
4516
|
+
};
|
|
4517
|
+
markSkippedIfPresent(
|
|
4518
|
+
"settings-storage",
|
|
4519
|
+
nextExcludeFolders !== void 0 || nextBeep !== void 0 || nextSleep !== void 0
|
|
4520
|
+
);
|
|
4521
|
+
} else {
|
|
4522
|
+
markSkippedIfPresent("settings-storage", false);
|
|
4523
|
+
}
|
|
4524
|
+
const provider = payload.provider;
|
|
4525
|
+
if (isRecord5(provider)) {
|
|
4526
|
+
const list = Array.isArray(provider.providers) ? provider.providers.filter(isRecord5).map((item) => ({
|
|
4527
|
+
id: asString3(item.id) ?? "",
|
|
4528
|
+
name: asString3(item.name) ?? "",
|
|
4529
|
+
models: Array.isArray(item.models) ? item.models.filter((model) => typeof model === "string") : [],
|
|
4530
|
+
apiKey: asString3(item.apiKey) ?? void 0,
|
|
4531
|
+
baseUrl: asString3(item.baseUrl) ?? void 0
|
|
4532
|
+
})).filter((item) => item.id && item.name) : void 0;
|
|
4533
|
+
const overridesByPath = isRecord5(provider.selectionsByCwd) ? provider.selectionsByCwd : void 0;
|
|
4534
|
+
patch.providers = {
|
|
4535
|
+
list,
|
|
4536
|
+
selectedProviderId: asString3(provider.selectedProviderId) ?? void 0,
|
|
4537
|
+
defaultModel: asString3(provider.defaultModel ?? provider.selectedModel),
|
|
4538
|
+
defaultReasoningEffort: typeof provider.defaultReasoningEffort === "string" ? provider.defaultReasoningEffort : typeof provider.reasoningEffort === "string" ? provider.reasoningEffort : void 0,
|
|
4539
|
+
overridesByPath
|
|
4540
|
+
};
|
|
4541
|
+
markSkippedIfPresent(
|
|
4542
|
+
"provider",
|
|
4543
|
+
list !== void 0 || asString3(provider.selectedProviderId) !== null || asString3(provider.defaultModel ?? provider.selectedModel) !== null || typeof provider.defaultReasoningEffort === "string" || typeof provider.reasoningEffort === "string" || overridesByPath !== void 0
|
|
4544
|
+
);
|
|
4545
|
+
} else {
|
|
4546
|
+
markSkippedIfPresent("provider", false);
|
|
4547
|
+
}
|
|
4548
|
+
const sandbox = payload["sandbox-storage"];
|
|
4549
|
+
if (isRecord5(sandbox)) {
|
|
4550
|
+
const defaultMode = asString3(sandbox.defaultMode ?? sandbox.mode) ?? void 0;
|
|
4551
|
+
const defaultApprovalPolicy = asString3(sandbox.defaultApprovalPolicy ?? sandbox.approvalPolicy) ?? void 0;
|
|
4552
|
+
const overridesByPath = isRecord5(sandbox.selectionsByCwd) ? sandbox.selectionsByCwd : void 0;
|
|
4553
|
+
patch.sandbox = {
|
|
4554
|
+
defaultMode,
|
|
4555
|
+
defaultApprovalPolicy,
|
|
4556
|
+
overridesByPath
|
|
4557
|
+
};
|
|
4558
|
+
markSkippedIfPresent(
|
|
4559
|
+
"sandbox-storage",
|
|
4560
|
+
defaultMode !== void 0 || defaultApprovalPolicy !== void 0 || overridesByPath !== void 0
|
|
4561
|
+
);
|
|
4562
|
+
} else {
|
|
4563
|
+
markSkippedIfPresent("sandbox-storage", false);
|
|
4564
|
+
}
|
|
4565
|
+
const projectSettings = payload["project-settings-storage"];
|
|
4566
|
+
if (isRecord5(projectSettings) && isRecord5(projectSettings.settingsByPath)) {
|
|
4567
|
+
patch.projectSettingsByPath = projectSettings.settingsByPath;
|
|
4568
|
+
markSkippedIfPresent("project-settings-storage", true);
|
|
4569
|
+
} else {
|
|
4570
|
+
markSkippedIfPresent("project-settings-storage", false);
|
|
4571
|
+
}
|
|
4572
|
+
const folder = payload["folder-storage"];
|
|
4573
|
+
if (isRecord5(folder)) {
|
|
4574
|
+
const folderHistory = Array.isArray(folder.folderHistory) ? folder.folderHistory.filter(isRecord5) : void 0;
|
|
4575
|
+
const pinnedPaths = Array.isArray(folder.pinnedPaths) ? folder.pinnedPaths.filter((item) => typeof item === "string") : void 0;
|
|
4576
|
+
patch.preferences = {
|
|
4577
|
+
...patch.preferences ?? {},
|
|
4578
|
+
folderHistory,
|
|
4579
|
+
pinnedPaths
|
|
4580
|
+
};
|
|
4581
|
+
markSkippedIfPresent("folder-storage", folderHistory !== void 0 || pinnedPaths !== void 0);
|
|
4582
|
+
} else {
|
|
4583
|
+
markSkippedIfPresent("folder-storage", false);
|
|
4584
|
+
}
|
|
4585
|
+
const categories = payload["conversation-categories-storage"];
|
|
4586
|
+
let consumedCategories = false;
|
|
4587
|
+
if (isRecord5(categories)) {
|
|
4588
|
+
if (isRecord5(categories.categoriesByCwd)) {
|
|
4589
|
+
patch.conversationCategoriesByCwd = categories.categoriesByCwd;
|
|
4590
|
+
consumedCategories = true;
|
|
4591
|
+
}
|
|
4592
|
+
if (isRecord5(categories.conversationCategoryByCwd)) {
|
|
4593
|
+
patch.conversationCategoryAssignmentsByCwd = categories.conversationCategoryByCwd;
|
|
4594
|
+
consumedCategories = true;
|
|
4595
|
+
}
|
|
4596
|
+
}
|
|
4597
|
+
markSkippedIfPresent("conversation-categories-storage", consumedCategories);
|
|
4598
|
+
const legacyAutoRoll = payload["codex:auto-roll-settings"];
|
|
4599
|
+
const autoRoll = pickAutoRoll(legacyAutoRoll);
|
|
4600
|
+
if (autoRoll) {
|
|
4601
|
+
patch.autoRoll = {
|
|
4602
|
+
enabled: autoRoll.enabled,
|
|
4603
|
+
warningThreshold: autoRoll.warningThreshold,
|
|
4604
|
+
switchThreshold: autoRoll.switchThreshold
|
|
4605
|
+
};
|
|
4606
|
+
markSkippedIfPresent("codex:auto-roll-settings", true);
|
|
4607
|
+
} else {
|
|
4608
|
+
markSkippedIfPresent("codex:auto-roll-settings", false);
|
|
4609
|
+
}
|
|
4610
|
+
return {
|
|
4611
|
+
patch,
|
|
4612
|
+
consumedKeys: Array.from(consumedKeys),
|
|
4613
|
+
skippedKeys: Array.from(skippedKeys)
|
|
4614
|
+
};
|
|
4615
|
+
}
|
|
4616
|
+
async function removeIfExists(target) {
|
|
4617
|
+
await import_node_fs7.promises.rm(target, { recursive: true, force: true });
|
|
4618
|
+
}
|
|
4619
|
+
async function cleanupLegacyCanonicalSources() {
|
|
4620
|
+
const homeDir = resolveHomeDir2();
|
|
4621
|
+
await removeIfExists(import_node_path9.default.join(homeDir, SQLITE_STORAGE_DIR));
|
|
4622
|
+
await removeIfExists(resolveLegacyPath(LEGACY_SETTINGS_FILE));
|
|
4623
|
+
await removeIfExists(resolveLegacyPath(LEGACY_SETTINGS_BACKUP_FILE));
|
|
4624
|
+
await removeIfExists(resolveLegacyPath(LEGACY_SYNC_STATE_FILE));
|
|
4625
|
+
await removeIfExists(resolveLegacyPath(LEGACY_LICENSE_SECRET_FILE));
|
|
4626
|
+
await removeIfExists(resolveLegacyPath(LEGACY_SKILLS_DIR, LEGACY_SKILLS_REPOS_FILE));
|
|
4627
|
+
const profileHomesRoot = resolveLegacyPath(LEGACY_PROFILE_HOMES_DIR);
|
|
4628
|
+
try {
|
|
4629
|
+
const profileHomes = await import_node_fs7.promises.readdir(profileHomesRoot, { withFileTypes: true });
|
|
4630
|
+
for (const profileHome of profileHomes) {
|
|
4631
|
+
if (!profileHome.isDirectory()) {
|
|
4632
|
+
continue;
|
|
4633
|
+
}
|
|
4634
|
+
const profileDir = import_node_path9.default.join(profileHomesRoot, profileHome.name);
|
|
4635
|
+
let files = [];
|
|
4636
|
+
try {
|
|
4637
|
+
files = await import_node_fs7.promises.readdir(profileDir);
|
|
4638
|
+
} catch {
|
|
4639
|
+
continue;
|
|
4640
|
+
}
|
|
4641
|
+
for (const file of files) {
|
|
4642
|
+
if (!file.startsWith("profile.json")) {
|
|
4643
|
+
continue;
|
|
4644
|
+
}
|
|
4645
|
+
await removeIfExists(import_node_path9.default.join(profileDir, file));
|
|
4646
|
+
}
|
|
4647
|
+
}
|
|
4648
|
+
} catch (error) {
|
|
4649
|
+
logWarn("Failed cleaning legacy profile metadata:", {
|
|
4650
|
+
profileHomesRoot,
|
|
4651
|
+
error: error instanceof Error ? error.message : String(error)
|
|
4652
|
+
});
|
|
4653
|
+
}
|
|
4654
|
+
const skillsRoot = resolveLegacyPath(LEGACY_SKILLS_DIR);
|
|
4655
|
+
try {
|
|
4656
|
+
const skillDirs = await import_node_fs7.promises.readdir(skillsRoot, { withFileTypes: true });
|
|
4657
|
+
for (const entry of skillDirs) {
|
|
4658
|
+
if (!entry.isDirectory() || entry.name.startsWith(".")) {
|
|
4659
|
+
continue;
|
|
4660
|
+
}
|
|
4661
|
+
await removeIfExists(import_node_path9.default.join(skillsRoot, entry.name, LEGACY_SKILL_MANIFEST));
|
|
4662
|
+
}
|
|
4663
|
+
} catch (error) {
|
|
4664
|
+
logWarn("Failed cleaning legacy skills metadata:", {
|
|
4665
|
+
skillsRoot,
|
|
4666
|
+
error: error instanceof Error ? error.message : String(error)
|
|
4667
|
+
});
|
|
4668
|
+
}
|
|
4669
|
+
}
|
|
4670
|
+
async function runStorageMigrationV1() {
|
|
4671
|
+
const current = await getAppState();
|
|
4672
|
+
if (current.migration.status === "complete" || current.migration.status === "pending_local_storage") {
|
|
4673
|
+
return current;
|
|
4674
|
+
}
|
|
4675
|
+
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
4676
|
+
try {
|
|
4677
|
+
await migrateLegacyDirectoriesToUserData();
|
|
4678
|
+
const patches = await Promise.all([
|
|
4679
|
+
loadLegacySettingsPatch(),
|
|
4680
|
+
loadLegacySyncPatch(),
|
|
4681
|
+
loadLegacyProfilesPatch(),
|
|
4682
|
+
loadLegacySkillsPatch()
|
|
4683
|
+
]);
|
|
4684
|
+
const mergedPatch = patches.reduce((acc, patch) => {
|
|
4685
|
+
return {
|
|
4686
|
+
...acc,
|
|
4687
|
+
...patch,
|
|
4688
|
+
app: { ...acc.app ?? {}, ...patch.app ?? {} },
|
|
4689
|
+
license: { ...acc.license ?? {}, ...patch.license ?? {} },
|
|
4690
|
+
autoRoll: { ...acc.autoRoll ?? {}, ...patch.autoRoll ?? {} },
|
|
4691
|
+
providers: { ...acc.providers ?? {}, ...patch.providers ?? {} },
|
|
4692
|
+
sandbox: { ...acc.sandbox ?? {}, ...patch.sandbox ?? {} },
|
|
4693
|
+
preferences: { ...acc.preferences ?? {}, ...patch.preferences ?? {} },
|
|
4694
|
+
sync: { ...acc.sync ?? {}, ...patch.sync ?? {} },
|
|
4695
|
+
profilesByName: { ...acc.profilesByName ?? {}, ...patch.profilesByName ?? {} },
|
|
4696
|
+
projectSettingsByPath: {
|
|
4697
|
+
...acc.projectSettingsByPath ?? {},
|
|
4698
|
+
...patch.projectSettingsByPath ?? {}
|
|
4699
|
+
},
|
|
4700
|
+
conversationCategoriesByCwd: {
|
|
4701
|
+
...acc.conversationCategoriesByCwd ?? {},
|
|
4702
|
+
...patch.conversationCategoriesByCwd ?? {}
|
|
4703
|
+
},
|
|
4704
|
+
conversationCategoryAssignmentsByCwd: {
|
|
4705
|
+
...acc.conversationCategoryAssignmentsByCwd ?? {},
|
|
4706
|
+
...patch.conversationCategoryAssignmentsByCwd ?? {}
|
|
4707
|
+
},
|
|
4708
|
+
skills: {
|
|
4709
|
+
...acc.skills ?? {},
|
|
4710
|
+
...patch.skills ?? {},
|
|
4711
|
+
sources: patch.skills?.sources ?? acc.skills?.sources,
|
|
4712
|
+
installsBySlug: {
|
|
4713
|
+
...acc.skills?.installsBySlug ?? {},
|
|
4714
|
+
...patch.skills?.installsBySlug ?? {}
|
|
4715
|
+
}
|
|
4716
|
+
}
|
|
4717
|
+
};
|
|
4718
|
+
}, {});
|
|
4719
|
+
return await updateAppState((state) => ({
|
|
4720
|
+
...state,
|
|
4721
|
+
...mergedPatch,
|
|
4722
|
+
app: { ...state.app, ...mergedPatch.app ?? {} },
|
|
4723
|
+
license: { ...state.license, ...mergedPatch.license ?? {} },
|
|
4724
|
+
autoRoll: { ...state.autoRoll, ...mergedPatch.autoRoll ?? {} },
|
|
4725
|
+
providers: {
|
|
4726
|
+
...state.providers,
|
|
4727
|
+
...mergedPatch.providers ?? {},
|
|
4728
|
+
overridesByPath: {
|
|
4729
|
+
...state.providers.overridesByPath,
|
|
4730
|
+
...mergedPatch.providers?.overridesByPath ?? {}
|
|
4731
|
+
}
|
|
4732
|
+
},
|
|
4733
|
+
sandbox: {
|
|
4734
|
+
...state.sandbox,
|
|
4735
|
+
...mergedPatch.sandbox ?? {},
|
|
4736
|
+
overridesByPath: {
|
|
4737
|
+
...state.sandbox.overridesByPath,
|
|
4738
|
+
...mergedPatch.sandbox?.overridesByPath ?? {}
|
|
4739
|
+
}
|
|
4740
|
+
},
|
|
4741
|
+
preferences: { ...state.preferences, ...mergedPatch.preferences ?? {} },
|
|
4742
|
+
sync: { ...state.sync, ...mergedPatch.sync ?? {} },
|
|
4743
|
+
profilesByName: {
|
|
4744
|
+
...state.profilesByName,
|
|
4745
|
+
...mergedPatch.profilesByName ?? {}
|
|
4746
|
+
},
|
|
4747
|
+
projectSettingsByPath: {
|
|
4748
|
+
...state.projectSettingsByPath,
|
|
4749
|
+
...mergedPatch.projectSettingsByPath ?? {}
|
|
4750
|
+
},
|
|
4751
|
+
conversationCategoriesByCwd: {
|
|
4752
|
+
...state.conversationCategoriesByCwd,
|
|
4753
|
+
...mergedPatch.conversationCategoriesByCwd ?? {}
|
|
4754
|
+
},
|
|
4755
|
+
conversationCategoryAssignmentsByCwd: {
|
|
4756
|
+
...state.conversationCategoryAssignmentsByCwd,
|
|
4757
|
+
...mergedPatch.conversationCategoryAssignmentsByCwd ?? {}
|
|
4758
|
+
},
|
|
4759
|
+
skills: {
|
|
4760
|
+
...state.skills,
|
|
4761
|
+
...mergedPatch.skills ?? {},
|
|
4762
|
+
installsBySlug: {
|
|
4763
|
+
...state.skills.installsBySlug,
|
|
4764
|
+
...mergedPatch.skills?.installsBySlug ?? {}
|
|
4765
|
+
}
|
|
4766
|
+
},
|
|
4767
|
+
migration: {
|
|
4768
|
+
...state.migration,
|
|
4769
|
+
status: "pending_local_storage",
|
|
4770
|
+
startedAt: state.migration.startedAt ?? startedAt,
|
|
4771
|
+
completedAt: null,
|
|
4772
|
+
localStorageImportedAt: null,
|
|
4773
|
+
lastError: null
|
|
4774
|
+
}
|
|
4775
|
+
}), {
|
|
4776
|
+
mode: "replace",
|
|
4777
|
+
allowBeforeMigrationComplete: true
|
|
4778
|
+
});
|
|
4779
|
+
} catch (error) {
|
|
4780
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
4781
|
+
await updateAppState((state) => ({
|
|
4782
|
+
...state,
|
|
4783
|
+
migration: {
|
|
4784
|
+
...state.migration,
|
|
4785
|
+
status: "pending",
|
|
4786
|
+
startedAt: state.migration.startedAt ?? startedAt,
|
|
4787
|
+
lastError: message
|
|
4788
|
+
}
|
|
4789
|
+
}), {
|
|
4790
|
+
mode: "replace",
|
|
4791
|
+
allowBeforeMigrationComplete: true
|
|
4792
|
+
});
|
|
4793
|
+
throw error;
|
|
4794
|
+
}
|
|
4795
|
+
}
|
|
4796
|
+
async function importLegacyLocalStorageOnce(payload) {
|
|
4797
|
+
const current = await getAppState();
|
|
4798
|
+
if (current.migration.status === "complete") {
|
|
4799
|
+
return { completed: true, importedKeys: [], skippedKeys: [] };
|
|
4800
|
+
}
|
|
4801
|
+
if (current.migration.status !== "pending_local_storage") {
|
|
4802
|
+
return { completed: false, importedKeys: [], skippedKeys: [] };
|
|
4803
|
+
}
|
|
4804
|
+
if (!payload || !isRecord5(payload)) {
|
|
4805
|
+
return { completed: false, importedKeys: [], skippedKeys: [] };
|
|
4806
|
+
}
|
|
4807
|
+
const { patch, consumedKeys, skippedKeys } = mergeLegacyLocalStoragePatch(payload);
|
|
4808
|
+
const completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
4809
|
+
const next = await updateAppState((state) => {
|
|
4810
|
+
if (state.migration.status !== "pending_local_storage") {
|
|
4811
|
+
return state;
|
|
4812
|
+
}
|
|
4813
|
+
return {
|
|
4814
|
+
...state,
|
|
4815
|
+
...patch,
|
|
4816
|
+
app: { ...state.app, ...patch.app ?? {} },
|
|
4817
|
+
autoRoll: { ...state.autoRoll, ...patch.autoRoll ?? {} },
|
|
4818
|
+
license: { ...state.license, ...patch.license ?? {} },
|
|
4819
|
+
providers: {
|
|
4820
|
+
...state.providers,
|
|
4821
|
+
...patch.providers ?? {},
|
|
4822
|
+
overridesByPath: {
|
|
4823
|
+
...state.providers.overridesByPath,
|
|
4824
|
+
...patch.providers?.overridesByPath ?? {}
|
|
4825
|
+
}
|
|
4826
|
+
},
|
|
4827
|
+
sandbox: {
|
|
4828
|
+
...state.sandbox,
|
|
4829
|
+
...patch.sandbox ?? {},
|
|
4830
|
+
overridesByPath: {
|
|
4831
|
+
...state.sandbox.overridesByPath,
|
|
4832
|
+
...patch.sandbox?.overridesByPath ?? {}
|
|
4833
|
+
}
|
|
4834
|
+
},
|
|
4835
|
+
preferences: { ...state.preferences, ...patch.preferences ?? {} },
|
|
4836
|
+
projectSettingsByPath: {
|
|
4837
|
+
...state.projectSettingsByPath,
|
|
4838
|
+
...patch.projectSettingsByPath ?? {}
|
|
4839
|
+
},
|
|
4840
|
+
conversationCategoriesByCwd: {
|
|
4841
|
+
...state.conversationCategoriesByCwd,
|
|
4842
|
+
...patch.conversationCategoriesByCwd ?? {}
|
|
4843
|
+
},
|
|
4844
|
+
conversationCategoryAssignmentsByCwd: {
|
|
4845
|
+
...state.conversationCategoryAssignmentsByCwd,
|
|
4846
|
+
...patch.conversationCategoryAssignmentsByCwd ?? {}
|
|
4847
|
+
},
|
|
4848
|
+
migration: {
|
|
4849
|
+
...state.migration,
|
|
4850
|
+
status: "complete",
|
|
4851
|
+
completedAt,
|
|
4852
|
+
localStorageImportedAt: completedAt,
|
|
4853
|
+
lastError: null
|
|
4854
|
+
}
|
|
4855
|
+
};
|
|
4856
|
+
}, {
|
|
4857
|
+
mode: "replace",
|
|
4858
|
+
allowBeforeMigrationComplete: true
|
|
4859
|
+
});
|
|
4860
|
+
if (next.migration.status !== "complete") {
|
|
4861
|
+
return { completed: false, importedKeys: [], skippedKeys: [] };
|
|
4862
|
+
}
|
|
4863
|
+
await cleanupLegacyCanonicalSources();
|
|
4864
|
+
return { completed: true, importedKeys: consumedKeys, skippedKeys };
|
|
4865
|
+
}
|
|
4866
|
+
|
|
4074
4867
|
// src/index.ts
|
|
4075
|
-
var VERSION = true ? "2.4.
|
|
4868
|
+
var VERSION = true ? "2.4.4" : "0.0.0";
|
|
4869
|
+
var cliStorageReadyPromise = null;
|
|
4870
|
+
async function ensureCliStorageReady() {
|
|
4871
|
+
if (cliStorageReadyPromise) {
|
|
4872
|
+
return cliStorageReadyPromise;
|
|
4873
|
+
}
|
|
4874
|
+
cliStorageReadyPromise = (async () => {
|
|
4875
|
+
await initializeAppState(getUserDataDir());
|
|
4876
|
+
const migrated = await runStorageMigrationV1();
|
|
4877
|
+
if (migrated.migration.status === "pending_local_storage") {
|
|
4878
|
+
await importLegacyLocalStorageOnce({});
|
|
4879
|
+
}
|
|
4880
|
+
const state = await getAppState();
|
|
4881
|
+
if (state.migration.status !== "complete") {
|
|
4882
|
+
throw new Error(
|
|
4883
|
+
`Storage migration is not complete (status: ${state.migration.status}). Open CodexUse desktop once and try again.`
|
|
4884
|
+
);
|
|
4885
|
+
}
|
|
4886
|
+
})().catch((error) => {
|
|
4887
|
+
cliStorageReadyPromise = null;
|
|
4888
|
+
throw error;
|
|
4889
|
+
});
|
|
4890
|
+
return cliStorageReadyPromise;
|
|
4891
|
+
}
|
|
4076
4892
|
function printHelp() {
|
|
4077
4893
|
console.log(`CodexUse CLI v${VERSION}
|
|
4078
4894
|
|
|
@@ -4591,12 +5407,15 @@ async function main() {
|
|
|
4591
5407
|
const rest = args.slice(1);
|
|
4592
5408
|
switch (command) {
|
|
4593
5409
|
case "profile":
|
|
5410
|
+
await ensureCliStorageReady();
|
|
4594
5411
|
await handleProfile(rest);
|
|
4595
5412
|
return;
|
|
4596
5413
|
case "license":
|
|
5414
|
+
await ensureCliStorageReady();
|
|
4597
5415
|
await handleLicense(rest);
|
|
4598
5416
|
return;
|
|
4599
5417
|
case "sync":
|
|
5418
|
+
await ensureCliStorageReady();
|
|
4600
5419
|
await handleSync(rest);
|
|
4601
5420
|
return;
|
|
4602
5421
|
default:
|